The WHL format was developed as a faster, more reliable way to install Python software, rather than rebuilding it from source every time. Just move the WHL file to the correct location on the target system to install, whereas source distribution requires build steps prior to installation.
Reference: github.com/jfloff/alpi…
Images based on the Alpine platform do not support roundpacks pandas and Numpy. This is why when we installed them using Python PIP during the build, we always compiled them from Alpine’s source file. Unfortunately, the only way to install Pandas on Alpine’s image is to wait until the build is complete. It can only be compiled and then installed, and can be used as a base image
If the container running docker build needs to access the Internet through the proxy, add the command line before the operation required to access the network in the file:
Export http_proxy = http://16.15.0.1:9011
And:
Export https_proxy = http://16.15.0.1:9011
Dockerfile:
The FROM python: 3.8.3 - alpine3.11 LABEL maintainer ="[email protected]"
RUN apk --update add --no-cache g++
RUN pip install pandas
Copy the code
V3.7: Dockerfile:
The FROM python: 3.7 - alpine MAINTAINER liu8816#alpine installing pandas is slow and cannot be installed from WHL.Utf-8 ENV LANGUAGE en_US. utF-8 ENV LC_ALL en_US. utF-8 ENV BOTTLE_VER 0.12.18 ENV PYTHON_BUILD_PACKAGES="\ # numpy dependency \ python3-dev GCC freetype-dev gfortran musl-dev g++ libgcc libquadmath musl libgfortran lapack-dev # Pillow depends on \ jpeg-dev zlib-dev freetype-dev lcms2 openjpeg-dev tiff-dev tk-dev TCL -dev bzip2-dev coreutils \ python3-dev \ dpkg-dev dpkg \ expat-dev \ findutils \ gcc g++ \ gdbm-dev \ libc-dev \ libffi-dev \ libnsl-dev \ libtirpc-dev \ linux-headers \ make \ ncurses-dev \ libressl-dev \ pax-utils \ readline-dev \ sqlite-dev \ tcl-dev \ tk \ tk-dev \ util-linux-dev \ xz-dev \ zlib-dev \ git \ musl-dev \ postgresql-dev \ freetds-dev freetype-dev \ gfortran libgcc \ libquadmath libgfortran lapack-dev \ "
If there is an error in PIP installation, add it as prompted
#python-dev #python-dev (missing), may exist, update with apk, may not be named python3-dev
COPY entrypoint.sh /entrypoint.sh
COPY requirements.txt /data/requirements.txt
# Update Alpine's software source to a domestic (Tsinghua University) site, because pulling from the default official source is too slow...
# http://dl-cdn.alpinelinux.org/alpine/v3.11/main
# https://mirrors.aliyun.com/alpine/
#set is a command of the shell, because the shell will continue to execute if something fails. Set-ex is used to exit the command and stop executing it.
# RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main/" > / etc/apk/repositories
RUN set -ex \
The container needs to be enabled when accessing the Internet via proxy
&& exportHttp_proxy = http://16.15.0.1:9011 \ &&exportHttps_proxy =http://16.15.0.1:9011 \ && sed-i's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& pip config set global.index-url https://mirrors.aliyun.com/pypi/simple \
&& pip config set install.trusted-host mirrors.aliyun.com \
&& apk add --update --no-cache --virtual .build-deps $PYTHON_BUILD_PACKAGES \
#Cython otherwise some PIP installation fails \
&& pip install Cython \
&& pip install numpy \
&& pip install matplotlib \
#==3.2.1 # Specify version number may require Sir Into wheel, then install, relatively slow \
&& pip install pandas \
&& pip install pynacl \
&& pip install gevent \
&& pip install psycopg2-binary \
&& pip install bottle==$BOTTLE_VER \
&& pip install uwsgi \
Others that do not need to be compiled and installed can be put together in a requirements. TXT file
&& pip install --no-cache-dir -r /data/requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com \
&& apk del --no-cache --purge .build-deps
RUN rm -rf /var/cache/apk/*
EXPOSE 80
#CMD /bin/sh
# set proper permission to run entrypoint script
#chmod a+x /entrypoint.sh
# This script installs APK and Pip prerequisites on container start, or ONBUILD. Notes:
# * Reads the -a flags and /apk-requirements.txt for install requests
# * Reads the -b flags and /build-requirements.txt for build packages -- removed when build is complete
# * Reads the -p flags and /requirements.txt for Pip packages
# * Reads the -r flag to specify a different file path for /requirements.txt
ENTRYPOINT ["/usr/bin/dumb-init"."bash"."/entrypoint.sh"]
Copy the code
======= Integrates the file of bottle
If there is an error at runtime:
ERROR: mirrors.aliyun.com/alpine/v3.1… temporary error (try again later)
Solution:
———- If Centos8 cannot resolve the domain name:
# add firewall configuration:
#firewall-cmd --zone=public --add-masquerade --permanent
#firewall-cmd --reload
#systemctl restart docker
Copy the code
Method 2. Add parameters and build through the local network
docker build -t py37bottle:v1_pandas . --network=host
Copy the code
Entrypoint. Sh: (available from https://github.com/jfloff/alpine-python)
#! /usr/bin/dumb-init /bin/bash
set -e
APK_REQUIREMENTS=()
BUILD_REQUIREMENTS=()
PIP_REQUIREMENTS=()
APKFILE='/apk-requirements.txt'
BUILDFILE='/build-requirements.txt'
REQFILE='/requirements.txt'
VERBOSITY=1
TMP_REQFILE='/tmp/requirements.txt'
function usage () {
cat <<"EOF"
Usage: $0 [-a -b -p -A -B -P -r -q -x] [--] <your command line>
-a : APK requirement. Can be specified multiple times.
-b : APK build requirement. These will be removed at the end to save space.
-p : Pip requirement. Can be specified multiple times.
-A : apk-requirements.txt file location, default: /apk-requirements.txt
-B : build-requirements.txt file location, default: /build-requirements.txt
-P : requirements.txt file location, default: /requirements.txt
-r : same as above, just to match Pip's -r flag. -q : quiet, doesn't print anything at all.
-x : Bash debug mode. Extremely verbose!
-- : Separator for flags and your command
Whatever you provide after your arguments is run at the end.
EOF
exit1}function vlog () {
if [ $VERBOSITY -gt0];then
echo The $1
fi
}
# Get and process arguments
while getopts ":a:b:p:A:B:P:r:qx" opt; do
case $opt in
a) APK_REQUIREMENTS+=("$OPTARG");; b) BUILD_REQUIREMENTS+=("$OPTARG");; p) PIP_REQUIREMENTS+=("$OPTARG");; A) APKFILE="$OPTARG" ;;
B) BUILDFILE="$OPTARG" ;;
P) REQFILE="$OPTARG" ;;
r) REQFILE="$OPTARG" ;;
q) VERBOSITY=0 ;;
x) set-x ;; \?echo "Invalid option: -$OPTARG" >&2
usage
;;
:)
echo "Option -$OPTARG requires an argument." >&2
usage
;;
esac
done
# Bad arguments
if[$?-ne0];then
usage
fi
# Strip out all the arguments that have been processed
shift $((OPTIND-1))
# If there's a double dash at the end, get that off
[[ The $1 = "--"&&]]shift
# Make some common flags objects
PIP_FLAGS=' '
if [ $VERBOSITY -eq0];then
PIP_FLAGS="$PIP_FLAGS -q"
fi
APK_FLAGS='--no-cache --no-progress'
if [ $VERBOSITY -eq0];then
APK_FLAGS="$APK_FLAGS -q"
fi
# Don't do anything if we've already done this.
if[[!-f /requirements.installed ]]; then
vlog "First run, checking for any requirements..."
# Install any APK requirements
if [[ -f "$APKFILE"]].then
vlog "APK requirements file detected!"
APK_REQUIREMENTS+=($( cat "$APKFILE" ))
fi
if [[ -f "$BUILDFILE"]].then
vlog "Build requirements file detected!"
BUILD_REQUIREMENTS+=($( cat "$BUILDFILE" ))
fi
# Unfortunately the Alpine repositories are in a slightly inconsistent state for now-- python2 only exists in 'edge', not main.
# if [[ "$PYTHON_VERSION" == '2' ]]; then BUILD_PACKAGES="$(echo $BUILD_PACKAGES | sed -e 's/python2/python/g')"; fi \
vlog "Installing all APK requirements..."
apk add $APK_FLAGS $BUILD_PACKAGES "${APK_REQUIREMENTS[@]}" "${BUILD_REQUIREMENTS[@]}"
# Install any Pip requirements
if [[ -f "$REQFILE" && "$(cat $REQFILE | wc -l)" -gt0]];then
# Do this check a little early-- since we merge cli in with file,
# we'd get a false positive for logging otherwise.
vlog "Pip requirements file detected!"
fi
# If we use CLI parameters, we'll have to reassign this.
TARGET_REQFILE="$REQFILE"
if [[ ${#PIP_REQUIREMENTS[@]} -gt0]];then
# Put all Pip requirements into the same file.
printf "%s\n" "${PIP_REQUIREMENTS[@]}" >> "$TMP_REQFILE"
if [[ -f "$REQFILE" && "$(cat $REQFILE | wc -l)" -gt0]];then
cat "$REQFILE" >> "$TMP_REQFILE"
fi
TARGET_REQFILE="$TMP_REQFILE"
fi
if [[ -f $TARGET_REQFILE && "$(cat $TARGET_REQFILE | wc -l)" -gt0]];then
vlog "Upgrading Pip..."
pip install $PIP_FLAGS --upgrade pip
vlog "Installing all Pip requirements..."
pip install $PIP_FLAGS -r "$TARGET_REQFILE"
fi
# Remove packages that were only required for build.
apk del $APK_FLAGS $BUILD_PACKAGES "${BUILD_REQUIREMENTS[@]}"
vlog "Installing APK requirements..."
apk add $APK_FLAGS "${APK_REQUIREMENTS[@]}"
touch /requirements.installed
else
vlog "/requirements.installed file exists-- skipping requirements installs."
fi
if [[ ! -z "$@"]].then
# If the user has given us a command, run it.
$@
else
# Otherwise, default to running 'python'.
python
fi
Copy the code