From c2c5b62a63beb4221a59d3024cd94772cc4c8f59 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 7 Mar 2025 09:16:24 +0100 Subject: [PATCH] initialize docker build --- .dockerignore | 7 +++++++ Dockerfile | 40 ++++++++++++++++++++++++++++++++++++++ docker/Caddyfile | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ docker/run.sh | 24 +++++++++++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker/Caddyfile create mode 100644 docker/run.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..c739237 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +# Exclude the project virtual environment from image builds +.venv + +# Don't add credentials and other local stuff +.env +media +db.sqlite3 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4e50b07 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,40 @@ +FROM python:3.13-slim + +EXPOSE 8000 +WORKDIR /app + +ENV PATH="/app/.venv/bin:$PATH" +ENV STATIC_ROOT=/app/staticfiles +ENV MEDIA_ROOT=/data/media +# Set Caddy's XDG base directory to a writable location +ENV XDG_DATA_HOME=/app/run/caddy/data +ENV XDG_CONFIG_HOME=/app/run/caddy/config + +# Install system dependencies including Caddy +RUN apt-get update && apt-get install -y \ + debian-keyring \ + debian-archive-keyring \ + apt-transport-https \ + curl \ + && curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg \ + && curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list \ + && apt-get update \ + && apt-get install -y caddy procps \ + && rm -rf /var/lib/apt/lists/* + +# Install binaries with correct permissions +COPY --from=ghcr.io/astral-sh/uv:latest --chown=root:root --chmod=755 /uv /usr/local/bin/uv +COPY --chmod=755 docker/run.sh /usr/local/bin/run.sh + +COPY docker/Caddyfile /app/config/caddy/Caddyfile +ADD . /app + +RUN uv sync --frozen \ + && uv pip install gunicorn --no-cache-dir \ + && mkdir -p /app/config/caddy /app/run/caddy /app/run/gunicorn \ + && chgrp -R 0 /app \ + && chmod -R g=u /app \ + && chmod g+w /app/config/caddy/Caddyfile + # && SECRET_KEY= uv run src/manage.py collectstatic --noinput + +CMD ["/usr/local/bin/run.sh"] \ No newline at end of file diff --git a/docker/Caddyfile b/docker/Caddyfile new file mode 100644 index 0000000..bfe1b1c --- /dev/null +++ b/docker/Caddyfile @@ -0,0 +1,50 @@ +{ + auto_https off + http_port 8080 + https_port 0 + cert_issuer internal + skip_install_trust + + log { + output stderr + format console + level INFO + } + + servers { + protocols h1 + } + + storage file_system { + root /app/run/caddy + } +} + +:8080 { + # Health check endpoint + handle /healthz { + respond "OK" 200 + } + + # Handle static files + handle /static/* { + uri strip_prefix /static + root * /app/staticfiles + file_server + } + + # Handle media files + handle /media/* { + uri strip_prefix /media + root * /data/media + file_server + } + + # Proxy all other requests to Gunicorn + handle { + reverse_proxy unix//app/run/gunicorn.sock + } + + # Basic compression for better performance + encode gzip +} diff --git a/docker/run.sh b/docker/run.sh new file mode 100644 index 0000000..8efbfec --- /dev/null +++ b/docker/run.sh @@ -0,0 +1,24 @@ +#!/bin/sh -e + +# Create required directories with appropriate permissions +mkdir -p /app/run/caddy /app/run/gunicorn + +# Set Caddy config location +export XDG_CONFIG_HOME="/app/config" + +echo "Applying database migrations" +uv run src/manage.py migrate + +echo "Starting Caddy" +exec caddy run --config /app/config/caddy/Caddyfile --adapter caddyfile 2>&1 & + +echo "Starting Gunicorn" +exec \ + gunicorn \ + -w 4 \ + --access-logfile - \ + --error-log - \ + --capture-output \ + --pythonpath /app/.venv/lib/python3.13/site-packages/ \ + --bind unix:/app/run/gunicorn.sock \ + servala.wsgi:application