From 5b94bf22bd5dd7acc5ea1fefe45b4d4b12c11a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Hells=C3=A9n?= Date: Fri, 1 Jan 2021 16:15:47 +0100 Subject: [PATCH] Use python:3.9-slim and change to a multi-stage container to minimize size --- Dockerfile | 65 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0fc82fc..99b2c09 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,62 @@ -FROM archlinux +# We need gcc and build-essential to install our requirements but we +# don't need them when run the bot so we can selectively copy artifacts +# from this stage (compile-image) to second one (runtime-image), leaving +# behind everything we don't need in the final build. +FROM python:3.9-slim AS compile-image -# Update Arch and install gcc, python and pip and remove cache -RUN pacman -Syu --noconfirm && pacman --noconfirm -S gcc python python-pip git && yes | pacman -Scc +# We don't want apt-get to interact with us, +# and we want the default answers to be used for all questions. +# Is it also completely silent and unobtrusive. +ARG DEBIAN_FRONTEND=noninteractive -# Copy requirements for the bot and install them -COPY requirements.txt /tmp/ -RUN pip install --disable-pip-version-check --no-cache-dir --requirement /tmp/requirements.txt +# Update packages and install needed packages to build our requirements. +RUN apt-get update && \ + apt-get install -y --no-install-recommends build-essential gcc -# Create user +# Create new virtual environment in /opt/venv and change to it. +ENV VIRTUAL_ENV=/opt/venv +RUN python3 -m venv $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + +# Copy and install requirements. +COPY requirements.txt . +RUN pip install --disable-pip-version-check --no-cache-dir --requirement requirements.txt + +# Change to our second stage. This is the one that will run the bot. +FROM python:3.9-slim AS runtime-image + +# Copy Python dependencies from our build image. +COPY --from=compile-image /opt/venv /opt/venv + +# Create user so we don't run as root. RUN useradd --create-home botuser -WORKDIR /home/botuser +RUN chown -R botuser:botuser /home/botuser && chmod -R 755 /home/botuser USER botuser -RUN mkdir -p ~/data +# Change directory to where we will run the bot. +WORKDIR /home/botuser -# Copy bot and run +# Create directory for the sqlite database. +# You need to share this directory with the computer running +# the container to save the data. +RUN mkdir -p /home/botuser/data + +# Copy our Python bot to our home directory. COPY main.py . -CMD ["python", "./main.py"] + +# Don't generate byte code (.pyc-files). +# These are only needed if we run the python-files several times. +# Docker doesn't keep the data between runs so this adds nothing. +ENV PYTHONDONTWRITEBYTECODE 1 + +# Force the stdout and stderr streams to be unbuffered. +# Will allow log messages to be immediately dumped instead of being buffered. +# This is useful when the bot crashes before writing messages stuck in the buffer. +# Has a minor performance loss. We don't have many log messages so probably makes zero difference. +ENV PYTHONUNBUFFERED 1 + +# Use our virtual environment that we created in the other stage. +ENV PATH="/opt/venv/bin:$PATH" + +# Run bot. +CMD [ "python", "./main.py" ] \ No newline at end of file