-
Notifications
You must be signed in to change notification settings - Fork 0
Feat: Buildkit caching for Docker builds #56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,87 @@ | ||
# declare default build args for later stages | ||
ARG PYTHON_VERSION=3.12 \ | ||
PYTHONDONTWRITEBYTECODE=1 \ | ||
PYTHONUNBUFFERED=1 \ | ||
USER=calitp \ | ||
USER_UID=1000 \ | ||
USER_GID=1000 | ||
|
||
FROM python:3.12 | ||
|
||
ENV PYTHONDONTWRITEBYTECODE=1 \ | ||
PYTHONUNBUFFERED=1 \ | ||
USER=calitp | ||
# renew top-level args in this stage | ||
ARG PYTHON_VERSION \ | ||
PYTHONDONTWRITEBYTECODE \ | ||
PYTHONUNBUFFERED \ | ||
USER \ | ||
USER_UID \ | ||
USER_GID | ||
|
||
# set env vars for the user, including HOME | ||
ENV PYTHONUNBUFFERED=${PYTHONUNBUFFERED} \ | ||
PYTHONDONTWRITEBYTECODE=${PYTHONDONTWRITEBYTECODE} \ | ||
HOME=/home/${USER} \ | ||
USER=${USER} \ | ||
PATH="/home/${USER}/.local/bin:$PATH" \ | ||
# update env for local pip installs | ||
# see https://docs.python.org/3/using/cmdline.html#envvar-PYTHONUSERBASE | ||
# since all `pip install` commands are in the context of $USER | ||
# $PYTHONUSERBASE is the location used by default | ||
PYTHONUSERBASE="/home/${USER}/.local" \ | ||
# where to store the pip cache (use the default) | ||
# https://pip.pypa.io/en/stable/cli/pip/#cmdoption-cache-dir | ||
PIP_CACHE_DIR="/home/${USER}/.cache/pip" \ | ||
GUNICORN_CONF="/$USER/run/gunicorn.conf.py" | ||
|
||
EXPOSE 8000 | ||
|
||
# create non-root $USER and home directory | ||
RUN useradd --create-home --shell /bin/bash $USER && \ | ||
USER root | ||
# install apt packages using the archives and lists cache | ||
RUN --mount=type=cache,id=apt-archives,sharing=locked,target=/var/cache/apt/archives \ | ||
--mount=type=cache,id=apt-lists,sharing=locked,target=/var/lib/apt/lists \ | ||
groupadd --gid ${USER_GID} ${USER} 2>/dev/null || true && \ | ||
useradd --uid ${USER_UID} --gid ${USER_GID} --create-home --shell /bin/bash ${USER} && \ | ||
# pip cache dir must be created and owned by the user to work with BuildKit cache | ||
mkdir -p ${PIP_CACHE_DIR} && \ | ||
# own the parent directory of PIP_CACHE_DIR | ||
chown -R ${USER}:${USER} /home/${USER}/.cache && \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we could use Bash parameter expansion |
||
# setup $USER permissions for nginx | ||
mkdir -p /var/cache/nginx && \ | ||
chown -R $USER /var/cache/nginx && \ | ||
chown -R $USER:$USER /var/cache/nginx && \ | ||
mkdir -p /var/lib/nginx && \ | ||
chown -R $USER /var/lib/nginx && \ | ||
chown -R $USER:$USER /var/lib/nginx && \ | ||
mkdir -p /var/log/nginx && \ | ||
chown -R $USER /var/log/nginx && \ | ||
chown -R $USER:$USER /var/log/nginx && \ | ||
touch /var/log/nginx/error.log && \ | ||
chown $USER /var/log/nginx/error.log && \ | ||
chown $USER:$USER /var/log/nginx/error.log && \ | ||
touch /var/run/nginx.pid && \ | ||
chown -R $USER /var/run/nginx.pid && \ | ||
chown -R $USER:$USER /var/run/nginx.pid && \ | ||
# setup directories and permissions for gunicorn, (eventual) app | ||
mkdir -p /$USER/app && \ | ||
mkdir -p /$USER/run && \ | ||
chown -R $USER /$USER && \ | ||
chown -R $USER:$USER /$USER && \ | ||
# install server components | ||
apt-get update && \ | ||
apt-get install -qq --no-install-recommends build-essential nginx gettext && \ | ||
python -m pip install --upgrade pip | ||
apt-get install -y --no-install-recommends build-essential nginx gettext && \ | ||
# this cleanup is still important for the final image layer size | ||
# remove lists from the image layer, but they remain in the BuildKit cache mount | ||
rm -rf /var/lib/apt/lists/* | ||
|
||
# enter run (gunicorn) directory | ||
WORKDIR /$USER/run | ||
|
||
# copy gunicorn config file | ||
COPY appcontainer/gunicorn.conf.py gunicorn.conf.py | ||
# overwrite default nginx.conf | ||
COPY appcontainer/nginx.conf /etc/nginx/nginx.conf | ||
|
||
# switch to non-root $USER | ||
USER $USER | ||
|
||
# update env for local pip installs | ||
# see https://docs.python.org/3/using/cmdline.html#envvar-PYTHONUSERBASE | ||
# since all `pip install` commands are in the context of $USER | ||
# $PYTHONUSERBASE is the location used by default | ||
ENV PATH="$PATH:/$USER/.local/bin" \ | ||
PYTHONUSERBASE="/$USER/.local" | ||
|
||
# install python dependencies | ||
COPY appcontainer/requirements.txt requirements.txt | ||
RUN pip install --no-cache-dir -r requirements.txt | ||
|
||
# copy gunicorn config file | ||
COPY appcontainer/gunicorn.conf.py gunicorn.conf.py | ||
ENV GUNICORN_CONF "/$USER/run/gunicorn.conf.py" | ||
|
||
# overwrite default nginx.conf | ||
COPY appcontainer/nginx.conf /etc/nginx/nginx.conf | ||
RUN --mount=type=cache,id=pipcache,target=${PIP_CACHE_DIR},uid=${USER_UID},gid=${USER_GID} \ | ||
python -m pip install --user --upgrade pip && \ | ||
pip install --user -r requirements.txt | ||
|
||
# enter app directory | ||
WORKDIR /$USER/app | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first I thought
PATH
andPYTHONUSERBASE
should just be set to/$USER/.local/bin
and/$USER/.local
respectively, but prefixing withhome
works too 👍