From bf5c08346ea1c29bdc24bd37cb2f45202e9b3c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Hells=C3=A9n?= Date: Thu, 23 Jan 2025 18:39:47 +0100 Subject: [PATCH] Update Dockerfile and add comments in pyproject.toml --- .vscode/settings.json | 5 ++++ Dockerfile | 55 ++++++++-------------------------------- pyproject.toml | 13 +++++++--- tests/test_dockerfile.py | 27 ++++++++++++++++++++ 4 files changed, 51 insertions(+), 49 deletions(-) create mode 100644 tests/test_dockerfile.py diff --git a/.vscode/settings.json b/.vscode/settings.json index 8e5cd32..043b9fb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,7 @@ "asctime", "asyncio", "audioop", + "botuser", "cookiejar", "dateparser", "delenv", @@ -19,8 +20,12 @@ "Lovinator", "pycodestyle", "pydocstyle", + "pyproject", + "PYTHONDONTWRITEBYTECODE", + "PYTHONUNBUFFERED", "pyupgrade", "sqlalchemy", + "thelovinator", "uvloop" ], "python.analysis.typeCheckingMode": "standard" diff --git a/Dockerfile b/Dockerfile index 6b0e05d..902fd8c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,48 +1,13 @@ -FROM python:3.12-slim as base - -ENV LANG C.UTF-8 -ENV LC_ALL C.UTF-8 -ENV POETRY_VIRTUALENVS_IN_PROJECT=1 -ENV POETRY_NO_INTERACTION=1 -ENV POETRY_HOME=/opt/poetry -ENV PYSETUP_PATH=/opt/pysetup -ENV VENV_PATH="/opt/pysetup/.venv" -ENV PIP_NO_CACHE_DIR=off -ENV PIP_DISABLE_PIP_VERSION_CHECK=on -ENV PIP_DEFAULT_TIMEOUT=100 +FROM python:3.13-slim +ENV PYTHONUNBUFFERED=1 ENV PYTHONDONTWRITEBYTECODE=1 -ENV PYTHONFAULTHANDLER=1 -ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH" -ENV PYTHONPATH="${PYTHONPATH}:/discord_reminder_bot" - -FROM base as python-deps - -RUN apt-get update && \ - apt-get install -y --no-install-recommends curl build-essential - -RUN --mount=type=cache,target=/root/.cache \ - curl -sSL https://install.python-poetry.org | python3 - - -WORKDIR $PYSETUP_PATH -COPY pyproject.toml ./ - -RUN --mount=type=cache,target=/root/.cache \ - poetry install --only main - -FROM base as runtime - -# Copy virtual env from python-deps stage -COPY --from=python-deps $PYSETUP_PATH $PYSETUP_PATH - -# Create directory for the sqlite database. -RUN mkdir -p /home/botuser/data - -# Copy source code -COPY discord_reminder_bot /home/botuser/discord_reminder_bot/ - +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ +RUN useradd -m botuser && mkdir -p /home/botuser/data WORKDIR /home/botuser - +COPY interactions /home/botuser/interactions +COPY discord_reminder_bot /home/botuser/discord_reminder_bot +RUN --mount=type=cache,target=/root/.cache/uv \ + --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ + uv sync --no-install-project VOLUME ["/home/botuser/data/"] - -# Run bot. -CMD [ "python", "/home/botuser/discord_reminder_bot/main.py" ] +CMD ["uv", "run", "discord_reminder_bot/main.py"] diff --git a/pyproject.toml b/pyproject.toml index b2f7bcb..a1493be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,9 +9,11 @@ description = "Discord bot that allows you to set date, cron and interval remind readme = "README.md" requires-python = ">=3.13" dependencies = [ - # The Discord bot library, and legacy-cgi is because Python 3.13 removed cgi module - "discord-py[speed]>=2.4.0,<3.0.0", # https://github.com/Rapptz/discord.py - "legacy-cgi>=2.6.2,<3.0.0; python_version >= '3.13'", # https://github.com/jackrosenthal/legacy-cgi + # The Discord bot library uses discord.py + # legacy-cgi and audioop-lts are because Python 3.13 removed cgi module and audioop module + "discord-py[speed]>=2.4.0,<3.0.0", # https://github.com/Rapptz/discord.py + "legacy-cgi>=2.6.2,<3.0.0; python_version >= '3.13'", # https://github.com/jackrosenthal/legacy-cgi + "audioop-lts>=0.2.1,<1.0.0; python_version >= '3.13'", # https://github.com/AbstractUmbra/audioop # For parsing dates and times in /remind commands "dateparser>=1.0.0", # https://github.com/scrapinghub/dateparser @@ -55,9 +57,12 @@ dateparser = {version = ">=1.0.0"} # https://github.com/Rapptz/discord.py # https://github.com/jackrosenthal/legacy-cgi -# The Discord bot library, and legacy-cgi is because Python 3.13 removed cgi module +# https://github.com/AbstractUmbra/audioop +# The Discord bot library uses discord.py +# legacy-cgi and audioop-lts are because Python 3.13 removed cgi module and audioop module discord-py = {version = ">=2.4.0,<3.0.0", extras = ["speed"]} legacy-cgi = {version = ">=2.6.2,<3.0.0", markers = "python_version >= '3.13'"} +audioop-lts = {version = ">=0.2.1,<1.0.0", markers = "python_version >= '3.13'"} # https://github.com/lovvskillz/python-discord-webhook # For sending webhook messages to Discord diff --git a/tests/test_dockerfile.py b/tests/test_dockerfile.py new file mode 100644 index 0000000..f616bd2 --- /dev/null +++ b/tests/test_dockerfile.py @@ -0,0 +1,27 @@ +from __future__ import annotations + +from pathlib import Path + +import pytest + + +@pytest.fixture +def dockerfile_content() -> str: + """Read the content of the Dockerfile and return it as a string. + + Returns: + str: The content of the Dockerfile. + """ + return Path("Dockerfile").read_text(encoding="utf-8") + + +def test_volume_exists(dockerfile_content: str) -> None: + """Test that the volume is set in the Dockerfile.""" + assert_msg = "Volume not set in Dockerfile. This has to always be set to /home/botuser/data/." + assert 'VOLUME ["/home/botuser/data/"]' in dockerfile_content, assert_msg + + +def test_env_variables(dockerfile_content: str) -> None: + """Test that the environment variables for Python are set in the Dockerfile.""" + assert "ENV PYTHONUNBUFFERED=1" in dockerfile_content, "PYTHONUNBUFFERED not set in Dockerfile" + assert "ENV PYTHONDONTWRITEBYTECODE=1" in dockerfile_content, "PYTHONDONTWRITEBYTECODE not set in Dockerfile"