diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..7ccb1bc --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,69 @@ +name: Build and Publish Docker Image + +on: + push: + branches: ["master"] + pull_request: + +concurrency: + group: docker-publish-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + packages: write + +env: + IMAGE_NAME: ${{ github.repository }} + REGISTRY: ghcr.io + +jobs: + docker: + name: Build and Publish + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Add Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + # Tag latest for default branch (commonly 'master') + type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.event_name == 'push' }} + # Branch name tags for non-default branches on push + type=ref,event=branch,enable=${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && github.event_name == 'push' }} + # PR tags like pr- + type=ref,event=pr + # Always include a short SHA tag for traceability + type=sha,format=short + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64 + push: true + tags: ${{ steps.meta.outputs.tags }} + annotations: ${{ steps.meta.outputs.annotations }} + cache-from: type=gha + cache-to: type=gha,mode=max + diff --git a/Dockerfile b/Dockerfile index 1628c3d..22c8c65 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3 +FROM python:3.13 ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 @@ -7,10 +7,16 @@ COPY requirements.txt /code/ RUN pip install -r requirements.txt COPY WBSAtool /code/ +# Static files volume RUN mkdir /static VOLUME /static -RUN python manage.py collectstatic --noinput -RUN python manage.py migrate --noinput + +# Copy startup script that will run scripts +COPY docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh EXPOSE 8000 -CMD gunicorn WBSAtool.wsgi:application --bind 0.0.0.0:8000 --workers 2 \ No newline at end of file + +# Entrypoint runs scripts then executes the container CMD +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +CMD ["gunicorn", "WBSAtool.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "2"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..54fe587 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,67 @@ +services: + db: + image: postgres:17 + restart: unless-stopped + volumes: + - ./data/db:/var/lib/postgresql/data + environment: + - POSTGRES_DB=postgres + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + + web: + image: ff-durlach/wbsa-tool:latest + restart: always + expose: + - 8000 + environment: + - DEBUG=True + - HSTS_SECONDS=31536000 + # public hostname + - ALLOWED_HOSTS= + - TRUSTED_ORIGINS= + - SECRET_KEY=SECRET + - DATABASE=postgres + - POSTGRES_HOST=db + - POSTGRES_USER=postgres + - POSTGRES_PASS=postgres + - POSTGRES_PORT=5432 + # link to publicly reachable nominatim instance + - NOMINATIM_URL=https://nominatim/search + volumes: + - "./data/static:/static" + depends_on: + - nominatim + - db + networks: + - default + - proxy + + nominatim: + image: mediagis/nominatim:4.3 + restart: unless-stopped + environment: + # see https://github.com/mediagis/nominatim-docker/tree/master/4.3#configuration for more options + PBF_URL: https://download.geofabrik.de/europe/germany/baden-wuerttemberg/karlsruhe-regbez-latest.osm.pbf + REPLICATION_URL: https://download.geofabrik.de/europe/germany/baden-wuerttemberg/karlsruhe-regbez-updates/ + NOMINATIM_PASSWORD: very_secure_password + networks: + - proxy + volumes: + - ./data/nominatim:/var/lib/postgresql/14/main + shm_size: 1gb + + + nginx: + image: nginx + restart: always + volumes: + - "./data/static:/usr/share/nginx/html/static:ro" + networks: + - proxy + depends_on: + - web + + +networks: + proxy: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..4ac83be --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env sh +set -e + +# Ensure we're in the app directory +cd /code + +# Collect static files at container startup (works with a mounted /static volume) +python manage.py collectstatic --noinput + +# Run migrations +RUN python manage.py migrate --noinput + +# Execute the CMD passed to the container +exec "$@"