diff --git a/.dockerignore b/.dockerignore index d174557..c03adae 100644 --- a/.dockerignore +++ b/.dockerignore @@ -109,6 +109,7 @@ venv/ ENV/ env.bak/ venv.bak/ +.env.example # Spyder project settings .spyderproject @@ -144,12 +145,10 @@ tests/ # https://github.com/marketplace/renovate renovate.json -# Other files not needed in the Docker image +# Git files and directories .git/ -README.md -pyproject.toml -poetry.lock -LICENSE +.gitignore + +# Docker files docker-compose.yml Dockerfile -.gitignore diff --git a/Dockerfile b/Dockerfile index 2a85c02..9fb849b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,71 +1,48 @@ -# We have two stages, one for making the virtual environment and -# installing the dependencies and another for running the uvicorn server. -# We use an virtual environment so we seperate the dependencies from the -# system-level dependencies. -FROM python:3.10-slim AS build-image +FROM python:3.10-slim +# TODO: Do the Poetry stuff in its own stage +# TODO: Add support for logging +# TODO: Add health check +# TODO: Add support for changing uid/gid +# TODO: Add support for changing host and port -# Create virtual environment in /opt/venv, we will use this in the other -# stage. -RUN python -m venv /opt/venv +# We don't want apt-get to interact with us and we want the default answers to be used for all questions. +ARG DEBIAN_FRONTEND=noninteractive -# Make sure we use the virtualenv. -ENV PATH="/opt/venv/bin:$PATH" +# 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. +ENV PYTHONUNBUFFERED 1 -# Copy requirements.txt to the container, it was generated with -# 'poetry export -f requirements.txt --without-hashes' -# Note that if we pipe the output of the commmand to requirements.txt in -# Windows, it will be UTF-16 LE encoded. -COPY requirements.txt . +# Update the system and install curl, it is needed for downloading Poetry. +RUN apt-get update && apt-get install curl ffmpeg -y --no-install-recommends -# Install the requirements. -RUN pip install -r requirements.txt - -# This is the stage where we will run the uvicorn server. -FROM python:3.10-slim AS run-image - -# Copy the virtual environment to the run-image. -COPY --from=build-image /opt/venv /opt/venv - -# Install ffmpeg, it is needed for finding the video resolution and -# making the video thumbnail. -RUN apt-get update -RUN apt-get install -y --no-install-recommends ffmpeg - -# Create user so we don't run as root and make the needed directories -# Logs are stored in /var/log/discord-embed and uploaded files, -# thumbnails, and HTML are stored in /Uploads. +# 1. Create user so we don't run as root +# 2. Create directories that the bot needs that are owned by the user. +# /Uploads is used to store the uploaded files. +# /home/botuser/discord-embed is where the Python code is stored. RUN useradd --create-home botuser && \ -install --verbose --directory --mode=0755 --owner=botuser --group=botuser /var/log/discord-embed/ /Uploads + install --verbose --directory --mode=0775 --owner=botuser --group=botuser /Uploads /home/botuser/discord-embed -# Persist the uploaded files and files we have created. -VOLUME ["/Uploads"] - -# Change to the user we created so we don't run as root. +# Change to the user we created. USER botuser # Change directory to where we will run the bot. WORKDIR /home/botuser/discord-embed -# Add main.py and settings.py to the container. +# Add needed files to the container, files and directories not needed are ignored in .dockerignore. ADD --chown=botuser:botuser . /home/botuser/discord-embed/ -# Uvicorn runs on port 5000, we can't use any ports below 1024 due to -# not being root. -EXPOSE 5000 +# 1. Install Poetry. +# 2. Add Poetry to the PATH. +# 3. Install dependencies. +ENV PATH="/home/botuser/.local/bin/:$PATH" +RUN curl -sSL https://install.python-poetry.org | python - +RUN poetry install --no-interaction --no-ansi --no-dev -# Make sure we use the virtualenv. -ENV PATH="/opt/venv/bin:$PATH" - -# 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. This means that -# the output will be printed immediately instead of being buffered. If -# the Python application crashes, the output could be lost. -ENV PYTHONUNBUFFERED 1 +# Persist the uploaded files and files we have created. +VOLUME ["/Uploads"] # Run the server on all interfaces and on port 5000. # You should run a reverse proxy like nginx infront of this. -CMD ["uvicorn", "discord_embed.main:app", "--host", "0.0.0.0", "--port", "5000"] +EXPOSE 5000 +CMD ["poetry", "run", "uvicorn", "discord_embed.main:app", "--host", "0.0.0.0", "--port", "5000"] \ No newline at end of file