diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..7e169ca --- /dev/null +++ b/.dockerignore @@ -0,0 +1,37 @@ +# Git and VCS +.git +.gitmodules + +# Python caches +__pycache__/ +*.pyc +*.pyo +*.pyd +*.pytest_cache/ +.pytest_cache/ + +# Virtual environments +.venv/ +.env +.env.* + +# Build artifacts +build/ +dist/ +*.egg-info/ +.coverage +htmlcov/ + +# OS files +.DS_Store + +# Tool caches +.ruff_cache/ +.uv/ + +# Local DBs +*.sqlite3 + +# Docker +Dockerfile* +compose.override.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6ea985..7f6deef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,12 @@ jobs: - name: Checkout uses: actions/checkout@v4 + # NOTE: we manage uv and python directly right now, but we can DRY this up by using docker within the + # GH actions workflow in the future. The direct method is supposed to be faster so we'll leave it for + # now. When we start to have more complex dependencies within the dockerfile we can swap over. + # Sample run commands: + # docker build -t form-submission-mvp:ci . + # docker run --rm form-submission-mvp:ci uv run pytest -q - name: Install uv run: curl -LsSf https://astral.sh/uv/install.sh | sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..86eab2a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,33 @@ +# syntax=docker/dockerfile:1.7 +FROM python:3.12-slim AS base + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 + +# Install system deps (curl for uv installer, build tools only if needed) +RUN apt-get update && apt-get install -y --no-install-recommends \ + curl ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +# Install uv +RUN curl -LsSf https://astral.sh/uv/install.sh | sh +ENV PATH="/root/.local/bin:${PATH}" + +WORKDIR /app + +# Copy project metadata first for better layer caching +COPY pyproject.toml uv.lock* ./ + +# Install dependencies without installing the project code yet (faster rebuilds) +RUN uv sync --frozen --no-install-project + +# Copy the rest of the source code +COPY . . + +# Install the project itself (editable-like install) +RUN uv sync --frozen + +EXPOSE 8000 + +# For Django dev server; override in compose for different commands +CMD ["uv", "run", "python", "efile_app/manage.py", "runserver", "0.0.0.0:8000"] diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..86c159a --- /dev/null +++ b/compose.yml @@ -0,0 +1,27 @@ +services: + web: + build: + context: . + dockerfile: Dockerfile + image: form-submission-mvp:web + command: >- + sh -c "uv run python efile_app/manage.py migrate && + uv run python efile_app/manage.py runserver 0.0.0.0:8000" + ports: + - "8000:8000" + environment: + PYTHONDONTWRITEBYTECODE: "1" + PYTHONUNBUFFERED: "1" + # DJANGO_SETTINGS_MODULE: efile.settings # manage.py sets this; uncomment to override + volumes: + - .:/app:delegated + - venv:/app/.venv + # healthcheck: + # test: ["CMD-SHELL", "wget -qO- http://localhost:8000/ || exit 1"] + # interval: 10s + # timeout: 5s + # retries: 5 + +volumes: + venv: + driver: local