From 27d0ff68a59ef4acdb27f8cdbe73d22e03f53835 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 3 Feb 2026 14:29:13 -0800 Subject: [PATCH 01/22] use .env.prod in docker-compose.prod.yaml --- .gitignore | 1 + docker/docker-compose.prod.yaml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c5ba5117..c77ac2b2 100644 --- a/.gitignore +++ b/.gitignore @@ -86,6 +86,7 @@ celerybeat-schedule # dotenv .env +.env.prod # virtualenv venv/ diff --git a/docker/docker-compose.prod.yaml b/docker/docker-compose.prod.yaml index 872e7c53..2598a35b 100644 --- a/docker/docker-compose.prod.yaml +++ b/docker/docker-compose.prod.yaml @@ -26,7 +26,7 @@ services: depends_on: - db env_file: - - .env.dev + - .env.prod environment: ALLOWED_HOSTS: ${ALLOWED_HOSTS} DEBUG: ${DEBUG} From 5e5cc5bbf30fe7f0c4a368415e66415db5f2f053 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 3 Feb 2026 15:13:11 -0800 Subject: [PATCH 02/22] add github action to publish docker image to github packages --- .../create-and-publish-docker-images.yml | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/workflows/create-and-publish-docker-images.yml diff --git a/.github/workflows/create-and-publish-docker-images.yml b/.github/workflows/create-and-publish-docker-images.yml new file mode 100644 index 00000000..37256b53 --- /dev/null +++ b/.github/workflows/create-and-publish-docker-images.yml @@ -0,0 +1,58 @@ +# source: https://docs.github.com/en/actions/tutorials/publish-packages/publish-docker-images#publishing-images-to-docker-hub-and-github-packages +name: Create and publish a Docker image + +# manually trigger while testing +on: + workflow_dispatch: + +# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + permissions: + contents: read + packages: write + attestations: write + id-token: write + # + steps: + - name: Checkout repository + uses: actions/checkout@v5 + # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. + # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see [Usage](https://github.com/docker/build-push-action#usage) in the README of the `docker/build-push-action` repository. + # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. + - name: Build and push Docker image + id: push + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + # This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see [Using artifact attestations to establish provenance for builds](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds). + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v3 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true + From e91eb06f4849892ec69b6c3b10c4cf4a75cba93d Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 3 Feb 2026 15:20:27 -0800 Subject: [PATCH 03/22] point push step to prod dockerfile --- .github/workflows/create-and-publish-docker-images.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/create-and-publish-docker-images.yml b/.github/workflows/create-and-publish-docker-images.yml index 37256b53..ffea8093 100644 --- a/.github/workflows/create-and-publish-docker-images.yml +++ b/.github/workflows/create-and-publish-docker-images.yml @@ -43,9 +43,10 @@ jobs: id: push uses: docker/build-push-action@v6 with: - context: . + context: ./TEKDB + file: ./TEKDB/prod.Dockerfile push: true - tags: ${{ steps.meta.outputs.tags }} + tags: ghcr.io/${{ github.repository }}/web:latest,ghcr.io/${{ github.repository }}/web:${{ github.sha }} labels: ${{ steps.meta.outputs.labels }} # This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see [Using artifact attestations to establish provenance for builds](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds). From ec83f25d21d5add9c63b62c94e691c17d65914d1 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 3 Feb 2026 15:24:15 -0800 Subject: [PATCH 04/22] try triggering action on push --- .github/workflows/create-and-publish-docker-images.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/create-and-publish-docker-images.yml b/.github/workflows/create-and-publish-docker-images.yml index ffea8093..eb90ec3d 100644 --- a/.github/workflows/create-and-publish-docker-images.yml +++ b/.github/workflows/create-and-publish-docker-images.yml @@ -2,8 +2,7 @@ name: Create and publish a Docker image # manually trigger while testing -on: - workflow_dispatch: +on: [push, workflow_dispatch] # Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. env: From 453f95e339610b8c2272e438ecd09dec6146adb0 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 3 Feb 2026 15:35:37 -0800 Subject: [PATCH 05/22] try generating slug for repo name --- .github/workflows/create-and-publish-docker-images.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/create-and-publish-docker-images.yml b/.github/workflows/create-and-publish-docker-images.yml index eb90ec3d..85e9e4f1 100644 --- a/.github/workflows/create-and-publish-docker-images.yml +++ b/.github/workflows/create-and-publish-docker-images.yml @@ -35,9 +35,16 @@ jobs: uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + - name: Format repo slug + uses: actions/github-script@v4 + id: repo_slug + with: + result-encoding: string + script: return `ghcr.io/${github.repository.toLowerCase()}` # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see [Usage](https://github.com/docker/build-push-action#usage) in the README of the `docker/build-push-action` repository. # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. + - name: Build and push Docker image id: push uses: docker/build-push-action@v6 @@ -45,8 +52,11 @@ jobs: context: ./TEKDB file: ./TEKDB/prod.Dockerfile push: true + builder: ${{ steps.buildx.outputs.name }} tags: ghcr.io/${{ github.repository }}/web:latest,ghcr.io/${{ github.repository }}/web:${{ github.sha }} labels: ${{ steps.meta.outputs.labels }} + cache-from: type=registry,ref=${{ steps.repo_slug.outputs.result }}:main + cache-to: type=inline # This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see [Using artifact attestations to establish provenance for builds](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds). - name: Generate artifact attestation From 4d93d8d5bdb1781c3a7d056c28b664880a81cf25 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 3 Feb 2026 15:41:08 -0800 Subject: [PATCH 06/22] try getting slug for repo name as string --- .github/workflows/create-and-publish-docker-images.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/create-and-publish-docker-images.yml b/.github/workflows/create-and-publish-docker-images.yml index 85e9e4f1..841295de 100644 --- a/.github/workflows/create-and-publish-docker-images.yml +++ b/.github/workflows/create-and-publish-docker-images.yml @@ -36,11 +36,12 @@ jobs: with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - name: Format repo slug - uses: actions/github-script@v4 + uses: actions/github-script@v8 id: repo_slug with: result-encoding: string - script: return `ghcr.io/${github.repository.toLowerCase()}` + script: | + return `ghcr.io/${process.env.GITHUB_REPOSITORY.toLowerCase()}` # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see [Usage](https://github.com/docker/build-push-action#usage) in the README of the `docker/build-push-action` repository. # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. From 43916a5b11a81d29642eac52192ef7b4200cde92 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 3 Feb 2026 15:43:54 -0800 Subject: [PATCH 07/22] try again to use lowercase repo name --- .github/workflows/create-and-publish-docker-images.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/create-and-publish-docker-images.yml b/.github/workflows/create-and-publish-docker-images.yml index 841295de..3d212206 100644 --- a/.github/workflows/create-and-publish-docker-images.yml +++ b/.github/workflows/create-and-publish-docker-images.yml @@ -7,7 +7,6 @@ on: [push, workflow_dispatch] # Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. env: REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} jobs: build-and-push-image: @@ -35,6 +34,10 @@ jobs: uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + # note: IMAGE_NAME will be set in the next step via GITHUB_ENV + - name: Set lowercase image name + run: | + echo "IMAGE_NAME=$(echo \"${GITHUB_REPOSITORY}\" | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV - name: Format repo slug uses: actions/github-script@v8 id: repo_slug @@ -53,8 +56,7 @@ jobs: context: ./TEKDB file: ./TEKDB/prod.Dockerfile push: true - builder: ${{ steps.buildx.outputs.name }} - tags: ghcr.io/${{ github.repository }}/web:latest,ghcr.io/${{ github.repository }}/web:${{ github.sha }} + tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/web:latest,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/web:${{ github.sha }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=registry,ref=${{ steps.repo_slug.outputs.result }}:main cache-to: type=inline From 521e7509cb4f36d0c3cc93b23535c5fac0b85858 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 3 Feb 2026 15:46:19 -0800 Subject: [PATCH 08/22] try setting lowercase IMAGE_NAME env var --- .github/workflows/create-and-publish-docker-images.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/create-and-publish-docker-images.yml b/.github/workflows/create-and-publish-docker-images.yml index 3d212206..f95f4f63 100644 --- a/.github/workflows/create-and-publish-docker-images.yml +++ b/.github/workflows/create-and-publish-docker-images.yml @@ -29,15 +29,15 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. + - name: Set lowercase image name + run: | + IMAGE_NAME=$(echo "${GITHUB_REPOSITORY}" | tr '[:upper:]' '[:lower:]') + echo "IMAGE_NAME=${IMAGE_NAME}" >> $GITHUB_ENV - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - # note: IMAGE_NAME will be set in the next step via GITHUB_ENV - - name: Set lowercase image name - run: | - echo "IMAGE_NAME=$(echo \"${GITHUB_REPOSITORY}\" | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV - name: Format repo slug uses: actions/github-script@v8 id: repo_slug From 05fcd1b18c342049421b519eddd7a97bc3c8aadf Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 3 Feb 2026 15:49:41 -0800 Subject: [PATCH 09/22] add prod dockerfile --- TEKDB/prod.Dockerfile | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 TEKDB/prod.Dockerfile diff --git a/TEKDB/prod.Dockerfile b/TEKDB/prod.Dockerfile new file mode 100644 index 00000000..ca2d2e24 --- /dev/null +++ b/TEKDB/prod.Dockerfile @@ -0,0 +1,46 @@ +FROM python:3.11-slim + +# Prevent Python from writing .pyc files and enable unbuffered stdout/stderr +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 +ENV PIP_NO_CACHE_DIR=1 + +# Install system dependencies +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + postgresql-client \ + gcc \ + gdal-bin \ + libgdal-dev \ + libgeos-dev \ + && rm -rf /var/lib/apt/lists/* + +# Set working directory +WORKDIR /usr/src/app + +# Copy requirements first (cache pip install step when dependencies don't change) +COPY requirements.txt requirements_linux.txt /usr/src/app/ + +# Upgrade pip and install Python dependencies +# Note: editable packages (-e) will be installed at runtime via entrypoint.sh +RUN pip install --upgrade pip \ + && pip install -r requirements.txt -r requirements_linux.txt + +# Copy the application code +COPY . /usr/src/app + +# Copy and make entrypoint executable. The repository contains `docker/entrypoint.sh` +# which runs collectstatic, migrations and launches uWSGI. +COPY entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +# Expose the port the app runs on (entrypoint starts django development server or uWSGI on 8000) +EXPOSE 8000 + +# Default settings module (can be overridden at runtime) +ENV DJANGO_SETTINGS_MODULE=TEKDB.settings + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + +# use prod server in prod Dockerfile +CMD ["prod"] \ No newline at end of file From 76b4ab0e55886ea9830dda55d868c73ce166afe7 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 3 Feb 2026 16:12:03 -0800 Subject: [PATCH 10/22] remove cache lines for build and push step --- .github/workflows/create-and-publish-docker-images.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/create-and-publish-docker-images.yml b/.github/workflows/create-and-publish-docker-images.yml index f95f4f63..be42c4fb 100644 --- a/.github/workflows/create-and-publish-docker-images.yml +++ b/.github/workflows/create-and-publish-docker-images.yml @@ -58,8 +58,6 @@ jobs: push: true tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/web:latest,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/web:${{ github.sha }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=registry,ref=${{ steps.repo_slug.outputs.result }}:main - cache-to: type=inline # This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see [Using artifact attestations to establish provenance for builds](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds). - name: Generate artifact attestation From 5fb47f561ed5c21bfa8b1853b41f54d515252955 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 3 Feb 2026 16:25:26 -0800 Subject: [PATCH 11/22] try token change --- .github/workflows/create-and-publish-docker-images.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/create-and-publish-docker-images.yml b/.github/workflows/create-and-publish-docker-images.yml index be42c4fb..b3eca98e 100644 --- a/.github/workflows/create-and-publish-docker-images.yml +++ b/.github/workflows/create-and-publish-docker-images.yml @@ -11,13 +11,12 @@ env: jobs: build-and-push-image: runs-on: ubuntu-latest - # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + # Sets the permissions granted to the `PACKAGE_TOKEN` for the actions in this job. permissions: contents: read packages: write attestations: write id-token: write - # steps: - name: Checkout repository uses: actions/checkout@v5 @@ -27,7 +26,7 @@ jobs: with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + password: ${{ secrets.PACKAGE_TOKEN }} # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. - name: Set lowercase image name run: | From 942ea136f6329ee49252b4723683d82dc6b5f955 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 3 Feb 2026 16:45:15 -0800 Subject: [PATCH 12/22] remove push from trigger options --- .github/workflows/create-and-publish-docker-images.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/create-and-publish-docker-images.yml b/.github/workflows/create-and-publish-docker-images.yml index b3eca98e..658a2459 100644 --- a/.github/workflows/create-and-publish-docker-images.yml +++ b/.github/workflows/create-and-publish-docker-images.yml @@ -2,7 +2,8 @@ name: Create and publish a Docker image # manually trigger while testing -on: [push, workflow_dispatch] +on: + workflow_dispatch # Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. env: From c83e88ce5e8dd1bf6cd3a44a1a4915998b3a862e Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Wed, 4 Feb 2026 10:47:33 -0800 Subject: [PATCH 13/22] use common docker compose and use extends --- docker/{docker-compose.yml => common.yaml} | 7 ++-- docker/docker-compose.prod.yaml | 42 ++++------------------ docker/docker-compose.yaml | 13 +++++++ 3 files changed, 21 insertions(+), 41 deletions(-) rename docker/{docker-compose.yml => common.yaml} (94%) create mode 100644 docker/docker-compose.yaml diff --git a/docker/docker-compose.yml b/docker/common.yaml similarity index 94% rename from docker/docker-compose.yml rename to docker/common.yaml index f865e83a..3ee08bef 100644 --- a/docker/docker-compose.yml +++ b/docker/common.yaml @@ -16,7 +16,7 @@ services: interval: 10s timeout: 5s retries: 5 - + web: build: context: ../TEKDB/ @@ -39,7 +39,4 @@ services: ports: - "8000:8000" volumes: - - ../TEKDB:/usr/src/app - -volumes: - tekdb_db_data: + - ../TEKDB:/usr/src/app \ No newline at end of file diff --git a/docker/docker-compose.prod.yaml b/docker/docker-compose.prod.yaml index 2598a35b..c063379b 100644 --- a/docker/docker-compose.prod.yaml +++ b/docker/docker-compose.prod.yaml @@ -1,46 +1,16 @@ services: db: - image: postgis/postgis:15-3.4 - restart: always - platform: linux/amd64 - environment: - POSTGRES_DB: ${SQL_DATABASE} - POSTGRES_USER: ${SQL_USER} - POSTGRES_PASSWORD: ${SQL_PASSWORD} - volumes: - - tekdb_db_data:/var/lib/postgresql/data - ports: - - "5432:5432" - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${SQL_USER} -d ${SQL_DATABASE} -h localhost -p ${SQL_PORT}"] - interval: 10s - timeout: 5s - retries: 5 + extends: + file: common.yaml + service: db web: - build: - context: ../TEKDB/ - dockerfile: ../TEKDB/Dockerfile + extends: + file: common.yaml + service: web command: ["prod"] - restart: unless-stopped - depends_on: - - db env_file: - .env.prod - environment: - ALLOWED_HOSTS: ${ALLOWED_HOSTS} - DEBUG: ${DEBUG} - SQL_ENGINE: ${SQL_ENGINE} - SQL_HOST: ${SQL_HOST} - SQL_PORT: ${SQL_PORT} - SQL_DATABASE: ${SQL_DATABASE} - SQL_USER: ${SQL_USER} - SQL_PASSWORD: ${SQL_PASSWORD} - SECRET_KEY: ${SECRET_KEY} - ports: - - "8000:8000" - volumes: - - ../TEKDB:/usr/src/app volumes: tekdb_db_data: diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml new file mode 100644 index 00000000..5a99ff86 --- /dev/null +++ b/docker/docker-compose.yaml @@ -0,0 +1,13 @@ +services: + db: + extends: + file: common.yaml + service: db + + web: + extends: + file: common.yaml + service: web + +volumes: + tekdb_db_data: From 3e60eaaeb4cc55553250cf5b25d93ce396c6d9a2 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Wed, 4 Feb 2026 12:54:58 -0800 Subject: [PATCH 14/22] wip: add gh action to push to ECR and deploy to app runner --- .github/workflows/deploy-app-runner.yml | 62 +++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 .github/workflows/deploy-app-runner.yml diff --git a/.github/workflows/deploy-app-runner.yml b/.github/workflows/deploy-app-runner.yml new file mode 100644 index 00000000..c9d90965 --- /dev/null +++ b/.github/workflows/deploy-app-runner.yml @@ -0,0 +1,62 @@ +name: Publish to ECR and Deploy to App Runner +on: + push: + branches: [develop] # Trigger workflow on git push to develop branch + workflow_dispatch: # Allow manual invocation of the workflow + +jobs: + deploy: + runs-on: ubuntu-latest + # These permissions are needed to interact with GitHub's OIDC Token endpoint. + permissions: + id-token: write + contents: read + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + persist-credentials: false + + - name: Configure AWS credentials + id: aws-credentials + uses: aws-actions/configure-aws-credentials@v5 + with: + # Use GitHub OIDC provider + role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} + aws-region: ${{ secrets.AWS_REGION }} + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + # steps to build, tag, and push Docker image to ECR + # tag with both latest and git sha + - name: Build, tag, and push image to Amazon ECR + id: build-image + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: tekdb + IMAGE_TAG: ${{ github.sha }} + run: | + docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . + docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG + echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" + docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest + docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest + echo "::set-output name=image-latest::$ECR_REGISTRY/$ECR_REPOSITORY:latest" + + # - name: Deploy to App Runner Image + # id: deploy-apprunner + # uses: awslabs/amazon-app-runner-deploy@main + # with: + # service: app-runner-git-deploy-service + # image: ${{ steps.build-image.outputs.image }} + # access-role-arn: ${{ secrets.ROLE_ARN }} + # region: ${{ secrets.AWS_REGION }} + # cpu : 1 + # memory : 2 + # wait-for-service-stability-seconds: 1200 + + # - name: App Runner URL + # run: echo "App runner URL ${{ steps.deploy-apprunner.outputs.service-url }}" \ No newline at end of file From cddcf48dd50a715302a9051f3db2f30791c2ea93 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Mon, 23 Feb 2026 16:04:33 -0800 Subject: [PATCH 15/22] set 5432 as default db port --- TEKDB/TEKDB/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TEKDB/TEKDB/settings.py b/TEKDB/TEKDB/settings.py index 49af92a8..21028c6b 100644 --- a/TEKDB/TEKDB/settings.py +++ b/TEKDB/TEKDB/settings.py @@ -127,7 +127,7 @@ "USER": os.environ.get("SQL_USER", "postgres"), "PASSWORD": os.environ.get("SQL_PASSWORD", None), "HOST": os.environ.get("SQL_HOST", "db"), - "PORT": os.environ.get("SQL_PORT", None), + "PORT": os.environ.get("SQL_PORT", 5432), } } From bd97aacbd2f5387f3109aefaa7621469325f9823 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Mon, 23 Feb 2026 16:56:56 -0800 Subject: [PATCH 16/22] use nginx proxy in prod setup --- TEKDB/entrypoint.sh | 4 ++-- docker/docker-compose.prod.yaml | 18 ++++++++++++++++++ proxy/Dockerfile | 9 +++++---- proxy/default.conf | 2 +- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/TEKDB/entrypoint.sh b/TEKDB/entrypoint.sh index fac43bbe..182563da 100644 --- a/TEKDB/entrypoint.sh +++ b/TEKDB/entrypoint.sh @@ -32,8 +32,8 @@ if [ "$(python manage.py shell -c 'from TEKDB.models import LookupPlanningUnit; fi if [ "$1" = "prod" ]; then - echo "Starting uWSGI (HTTP) on :8000" - uwsgi --http :8000 --master --enable-threads --module TEKDB.wsgi + echo "Starting uWSGI (socket) on :8000" + uwsgi --socket :8000 --master --enable-threads --module TEKDB.wsgi elif [ "$1" = "dev" ]; then echo "Starting python development server on :8000" python manage.py runserver 0.0.0.0:8000 diff --git a/docker/docker-compose.prod.yaml b/docker/docker-compose.prod.yaml index c063379b..2f0b55b9 100644 --- a/docker/docker-compose.prod.yaml +++ b/docker/docker-compose.prod.yaml @@ -11,6 +11,24 @@ services: command: ["prod"] env_file: - .env.prod + ports: [] + volumes: + - static_volume:/usr/src/app/static + - media_volume:/usr/src/app/media + proxy: + build: + context: ../proxy/ + dockerfile: ../proxy/Dockerfile + restart: unless-stopped + depends_on: + - web + ports: + - "8080:8080" + volumes: + - static_volume:/vol/static/static:ro + - media_volume:/vol/static/media:ro volumes: tekdb_db_data: + static_volume: + media_volume: diff --git a/proxy/Dockerfile b/proxy/Dockerfile index b7fd7b32..978935c0 100644 --- a/proxy/Dockerfile +++ b/proxy/Dockerfile @@ -1,11 +1,12 @@ FROM nginxinc/nginx-unprivileged:1-alpine +USER root + COPY ./default.conf /etc/nginx/conf.d/default.conf COPY ./uwsgi_params /etc/nginx/uwsgi_params -USER root - -RUN mkdir -p /vol/static -RUN chmod 755 /vol/static +RUN chmod 644 /etc/nginx/conf.d/default.conf /etc/nginx/uwsgi_params && \ + mkdir -p /vol/static && \ + chmod 755 /vol/static USER nginx diff --git a/proxy/default.conf b/proxy/default.conf index 99e1e714..8ef2d0a5 100644 --- a/proxy/default.conf +++ b/proxy/default.conf @@ -8,7 +8,7 @@ server { alias /vol/static/media; } location / { - uwsgi_pass app:8000; + uwsgi_pass web:8000; include /etc/nginx/uwsgi_params; } } From fd1ec8987df1502ada2392a25d5f671a389f1281 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 24 Feb 2026 09:18:03 -0800 Subject: [PATCH 17/22] add docker compose for testing prod set up locally --- docker/docker-compose.prod.local.yaml | 34 +++++++++++++++++++++++++++ docker/docker-compose.prod.yaml | 7 +++--- 2 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 docker/docker-compose.prod.local.yaml diff --git a/docker/docker-compose.prod.local.yaml b/docker/docker-compose.prod.local.yaml new file mode 100644 index 00000000..2f0b55b9 --- /dev/null +++ b/docker/docker-compose.prod.local.yaml @@ -0,0 +1,34 @@ +services: + db: + extends: + file: common.yaml + service: db + + web: + extends: + file: common.yaml + service: web + command: ["prod"] + env_file: + - .env.prod + ports: [] + volumes: + - static_volume:/usr/src/app/static + - media_volume:/usr/src/app/media + proxy: + build: + context: ../proxy/ + dockerfile: ../proxy/Dockerfile + restart: unless-stopped + depends_on: + - web + ports: + - "8080:8080" + volumes: + - static_volume:/vol/static/static:ro + - media_volume:/vol/static/media:ro + +volumes: + tekdb_db_data: + static_volume: + media_volume: diff --git a/docker/docker-compose.prod.yaml b/docker/docker-compose.prod.yaml index 2f0b55b9..2105577a 100644 --- a/docker/docker-compose.prod.yaml +++ b/docker/docker-compose.prod.yaml @@ -8,6 +8,7 @@ services: extends: file: common.yaml service: web + image: ${ITKDB_ECR_PATH}:latest command: ["prod"] env_file: - .env.prod @@ -16,14 +17,12 @@ services: - static_volume:/usr/src/app/static - media_volume:/usr/src/app/media proxy: - build: - context: ../proxy/ - dockerfile: ../proxy/Dockerfile + image: ${ITKDB_PROXY_ECR_PATH}:latest restart: unless-stopped depends_on: - web ports: - - "8080:8080" + - "80:8080" volumes: - static_volume:/vol/static/static:ro - media_volume:/vol/static/media:ro From 7f91476b5501f2678db41cb9cbba108d19b3a43e Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Tue, 24 Feb 2026 11:21:47 -0800 Subject: [PATCH 18/22] add OpenTofu/terraform to gitignore --- .gitignore | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c77ac2b2..a3f79ad1 100644 --- a/.gitignore +++ b/.gitignore @@ -99,4 +99,10 @@ ENV/ .ropeproject #vscode settings -.vscode/ \ No newline at end of file +.vscode/ + +# OpenTofu/Terraform +.terraform/ +terraform.tfstate +terraform.tfstate.backup +*.tfvars \ No newline at end of file From 60d0dcc0277c7bc711a1371ff036a0ee2c7c84f3 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Wed, 25 Feb 2026 16:41:56 -0800 Subject: [PATCH 19/22] add tf/opentofu IaC --- docker/common.yaml | 14 +--------- docker/docker-compose.yaml | 12 +++++++++ infra/ec2.tf | 55 ++++++++++++++++++++++++++++++++++++++ infra/ecr.tf | 17 ++++++++++++ infra/iam.tf | 28 +++++++++++++++++++ infra/main.tf | 52 +++++++++++++++++++++++++++++++++++ infra/networking.tf | 53 ++++++++++++++++++++++++++++++++++++ infra/outputs.tf | 16 +++++++++++ infra/terraform.tf | 17 ++++++++++++ 9 files changed, 251 insertions(+), 13 deletions(-) create mode 100644 infra/ec2.tf create mode 100644 infra/ecr.tf create mode 100644 infra/iam.tf create mode 100644 infra/main.tf create mode 100644 infra/networking.tf create mode 100644 infra/outputs.tf create mode 100644 infra/terraform.tf diff --git a/docker/common.yaml b/docker/common.yaml index 3ee08bef..2d58c8e7 100644 --- a/docker/common.yaml +++ b/docker/common.yaml @@ -26,17 +26,5 @@ services: - db env_file: - .env.dev - environment: - ALLOWED_HOSTS: ${ALLOWED_HOSTS} - DEBUG: ${DEBUG} - SQL_ENGINE: ${SQL_ENGINE} - SQL_HOST: ${SQL_HOST} - SQL_PORT: ${SQL_PORT} - SQL_DATABASE: ${SQL_DATABASE} - SQL_USER: ${SQL_USER} - SQL_PASSWORD: ${SQL_PASSWORD} - SECRET_KEY: ${SECRET_KEY} ports: - - "8000:8000" - volumes: - - ../TEKDB:/usr/src/app \ No newline at end of file + - "8000:8000" \ No newline at end of file diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 5a99ff86..5969649f 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -8,6 +8,18 @@ services: extends: file: common.yaml service: web + volumes: + - ../TEKDB:/usr/src/app + environment: + ALLOWED_HOSTS: ${ALLOWED_HOSTS} + DEBUG: ${DEBUG} + SQL_ENGINE: ${SQL_ENGINE} + SQL_HOST: ${SQL_HOST} + SQL_PORT: ${SQL_PORT} + SQL_DATABASE: ${SQL_DATABASE} + SQL_USER: ${SQL_USER} + SQL_PASSWORD: ${SQL_PASSWORD} + SECRET_KEY: ${SECRET_KEY} volumes: tekdb_db_data: diff --git a/infra/ec2.tf b/infra/ec2.tf new file mode 100644 index 00000000..5242a645 --- /dev/null +++ b/infra/ec2.tf @@ -0,0 +1,55 @@ +resource "aws_key_pair" "itkdb" { + key_name = "${var.project_name}-key" + public_key = var.ssh_public_key + + tags = { + Project = "${var.project_name}-staging" + } +} + +resource "aws_instance" "itkdb" { + ami = var.ec2_ami + instance_type = var.ec2_instance_type + key_name = aws_key_pair.itkdb.key_name + vpc_security_group_ids = [aws_security_group.itkdb.id] + iam_instance_profile = aws_iam_instance_profile.ec2_profile.name + subnet_id = tolist(data.aws_subnets.default.ids)[0] + user_data_replace_on_change = true + + # TODO: fix this! currently does not work + # Install Docker and AWS CLI v2 on first boot + user_data = <<-EOF + #!/bin/bash + set -e + sudo apt update + sudo apt install -y docker + systemctl start docker + systemctl enable docker + usermod -aG docker ubuntu + sudo snap install aws-cli --classic + unzip awscliv2.zip + sudo ./aws/install + EOF + + root_block_device { + volume_size = 20 + volume_type = "gp3" + encrypted = true + } + + tags = { + Name = "${var.project_name}-staging-server" + Project = var.project_name + } +} + +# Elastic IP so the address never changes across stop/start +resource "aws_eip" "itkdb" { + instance = aws_instance.itkdb.id + domain = "vpc" + + tags = { + Name = "${var.project_name}-staging-eip" + Project = var.project_name + } +} \ No newline at end of file diff --git a/infra/ecr.tf b/infra/ecr.tf new file mode 100644 index 00000000..9a5c9826 --- /dev/null +++ b/infra/ecr.tf @@ -0,0 +1,17 @@ +resource "aws_ecr_repository" "web" { + name = "ecotrust/${var.project_name}" + image_tag_mutability = "MUTABLE" + + tags = { + Project = var.project_name + } +} + +resource "aws_ecr_repository" "proxy" { + name = "ecotrust/${var.project_name}-proxy" + image_tag_mutability = "MUTABLE" + + tags = { + Project = var.project_name + } +} diff --git a/infra/iam.tf b/infra/iam.tf new file mode 100644 index 00000000..fcf46649 --- /dev/null +++ b/infra/iam.tf @@ -0,0 +1,28 @@ +# IAM role that allows the EC2 instance to pull images from ECR +resource "aws_iam_role" "ec2_ecr_role" { + name = "${var.project_name}-ec2-ecr-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [{ + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { Service = "ec2.amazonaws.com" } + }] + }) + + tags = { + Project = var.project_name + } +} + +resource "aws_iam_role_policy_attachment" "ecr_read" { + role = aws_iam_role.ec2_ecr_role.name + policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" +} + +# Instance profile wraps the role so EC2 can use it +resource "aws_iam_instance_profile" "ec2_profile" { + name = "${var.project_name}-ec2-profile" + role = aws_iam_role.ec2_ecr_role.name +} \ No newline at end of file diff --git a/infra/main.tf b/infra/main.tf new file mode 100644 index 00000000..57ebd1bd --- /dev/null +++ b/infra/main.tf @@ -0,0 +1,52 @@ +provider "aws" { + region = var.aws_region +} + +variable "aws_region" { + description = "AWS region to deploy into" + type = string + default = "us-west-2" +} + +variable "project_name" { + description = "Project name used to prefix all resources" + type = string + default = "itkdb" +} + +variable "aws_profile" { + description = "AWS profile to use" + type = string + default = "default" +} + +variable "bucket_name" { + description = "S3 bucket name for Terraform state (must be globally unique)" + type = string + default = "itkdb-tf-state" +} + +variable "ec2_instance_type" { + description = "EC2 instance type" + type = string + default = "t3.small" +} + +variable "ec2_ami" { + description = "Ubuntu 24.04 LTS AMI ID (region-specific — update if changing region)" + type = string + # Ubuntu 24.04 LTS us-west-1 — check https://cloud-images.ubuntu.com/locator/ec2/ for your region + default = "ami-06b527a1e4cb6f265" +} + +variable "ssh_public_key" { + description = "SSH public key to install on the EC2 instance (contents of your .pub file)" + type = string + sensitive = true +} + +variable "allowed_ssh_cidr" { + description = "CIDR block allowed to SSH into the EC2 instance (use your IP: x.x.x.x/32)" + type = string + default = "0.0.0.0/0" # Restrict this to your IP in production! +} \ No newline at end of file diff --git a/infra/networking.tf b/infra/networking.tf new file mode 100644 index 00000000..fee43725 --- /dev/null +++ b/infra/networking.tf @@ -0,0 +1,53 @@ +data "aws_vpc" "default" { + default = true +} + +data "aws_subnets" "default" { + filter { + name = "vpc-id" + values = [data.aws_vpc.default.id] + } +} + +resource "aws_security_group" "itkdb" { + name = "${var.project_name}-sg" + description = "Security group for ITKDB Staging EC2 instance" + vpc_id = data.aws_vpc.default.id + + # HTTP + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + # HTTPS (for when you add SSL via certbot/nginx later) + ingress { + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + # SSH — restrict to your IP in production! + ingress { + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = [var.allowed_ssh_cidr] + } + + # Allow all outbound (needed for ECR pulls, apt, etc.) + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags = { + Name = "${var.project_name}-sg" + Project = var.project_name + } +} \ No newline at end of file diff --git a/infra/outputs.tf b/infra/outputs.tf new file mode 100644 index 00000000..960acf91 --- /dev/null +++ b/infra/outputs.tf @@ -0,0 +1,16 @@ +output "ec2_public_ip" { + description = "Elastic IP of the EC2 instance — use this for DNS and GitHub secrets" + value = aws_eip.itkdb.public_ip +} + +output "ecr_web_url" { + description = "ECR URL for the web image" + value = aws_ecr_repository.web.repository_url +} + +output "ecr_proxy_url" { + description = "ECR URL for the proxy image" + value = aws_ecr_repository.proxy.repository_url +} + +data "aws_caller_identity" "current" {} \ No newline at end of file diff --git a/infra/terraform.tf b/infra/terraform.tf new file mode 100644 index 00000000..11c04bca --- /dev/null +++ b/infra/terraform.tf @@ -0,0 +1,17 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.92" + } + } + + required_version = ">= 1.2" + + backend "s3" { + bucket = "itkdb-tf-state" + key = "staging/terraform.tfstate" + region = var.aws_region + profile = "default" + } +} \ No newline at end of file From e8e2c00dcd41cf17ac7f9ddea4624a59e040670f Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Thu, 26 Feb 2026 10:33:04 -0800 Subject: [PATCH 20/22] track terraform.lock.hcl --- infra/.terraform.lock.hcl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 infra/.terraform.lock.hcl diff --git a/infra/.terraform.lock.hcl b/infra/.terraform.lock.hcl new file mode 100644 index 00000000..900ce952 --- /dev/null +++ b/infra/.terraform.lock.hcl @@ -0,0 +1,20 @@ +# This file is maintained automatically by "tofu init". +# Manual edits may be lost in future updates. + +provider "registry.opentofu.org/hashicorp/aws" { + version = "5.100.0" + constraints = "~> 5.92" + hashes = [ + "h1:BrNG7eFOdRrRRbHdvrTjMJ8X8Oh/tiegURiKf7J2db8=", + "zh:1a41f3ee26720fee7a9a0a361890632a1701b5dc1cf5355dc651ddbe115682ff", + "zh:30457f36690c19307921885cc5e72b9dbeba369445815903acd5c39ac0e41e7a", + "zh:42c22674d5f23f6309eaf3ac3a4f1f8b66b566c1efe1dcb0dd2fb30c17ce1f78", + "zh:4cc271c795ff8ce6479ec2d11a8ba65a0a9ed6331def6693f4b9dccb6e662838", + "zh:60932aa376bb8c87cd1971240063d9d38ba6a55502c867fdbb9f5361dc93d003", + "zh:864e42784bde77b18393ebfcc0104cea9123da5f4392e8a059789e296952eefa", + "zh:9750423138bb01ecaa5cec1a6691664f7783d301fb1628d3b64a231b6b564e0e", + "zh:e5d30c4dec271ef9d6fe09f48237ec6cfea1036848f835b4e47f274b48bda5a7", + "zh:e62bd314ae97b43d782e0841b13e68a3f8ec85cc762004f973ce5ce7b6cdbfd0", + "zh:ea851a3c072528a4445ac6236ba2ce58ffc99ec466019b0bd0e4adde63a248e4", + ] +} From 1d46d36a20c83b5b20484a643f7b78603ba8e80f Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Thu, 26 Feb 2026 12:01:07 -0800 Subject: [PATCH 21/22] remove deploy app runner gh action workflow --- .github/workflows/deploy-app-runner.yml | 62 ------------------------- 1 file changed, 62 deletions(-) delete mode 100644 .github/workflows/deploy-app-runner.yml diff --git a/.github/workflows/deploy-app-runner.yml b/.github/workflows/deploy-app-runner.yml deleted file mode 100644 index c9d90965..00000000 --- a/.github/workflows/deploy-app-runner.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: Publish to ECR and Deploy to App Runner -on: - push: - branches: [develop] # Trigger workflow on git push to develop branch - workflow_dispatch: # Allow manual invocation of the workflow - -jobs: - deploy: - runs-on: ubuntu-latest - # These permissions are needed to interact with GitHub's OIDC Token endpoint. - permissions: - id-token: write - contents: read - - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - persist-credentials: false - - - name: Configure AWS credentials - id: aws-credentials - uses: aws-actions/configure-aws-credentials@v5 - with: - # Use GitHub OIDC provider - role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} - aws-region: ${{ secrets.AWS_REGION }} - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 - - # steps to build, tag, and push Docker image to ECR - # tag with both latest and git sha - - name: Build, tag, and push image to Amazon ECR - id: build-image - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - ECR_REPOSITORY: tekdb - IMAGE_TAG: ${{ github.sha }} - run: | - docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . - docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG - echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" - docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest - docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest - echo "::set-output name=image-latest::$ECR_REGISTRY/$ECR_REPOSITORY:latest" - - # - name: Deploy to App Runner Image - # id: deploy-apprunner - # uses: awslabs/amazon-app-runner-deploy@main - # with: - # service: app-runner-git-deploy-service - # image: ${{ steps.build-image.outputs.image }} - # access-role-arn: ${{ secrets.ROLE_ARN }} - # region: ${{ secrets.AWS_REGION }} - # cpu : 1 - # memory : 2 - # wait-for-service-stability-seconds: 1200 - - # - name: App Runner URL - # run: echo "App runner URL ${{ steps.deploy-apprunner.outputs.service-url }}" \ No newline at end of file From 476f04bf874ce67ae84056bd5c05429813a920b1 Mon Sep 17 00:00:00 2001 From: Paige Williams Date: Thu, 26 Feb 2026 14:50:51 -0800 Subject: [PATCH 22/22] use commands in docker compose not dockerfiles; remove prod.Dockerfile --- .../create-and-publish-docker-images.yml | 2 +- TEKDB/Dockerfile | 2 - TEKDB/entrypoint.sh | 3 ++ TEKDB/prod.Dockerfile | 46 ------------------- docker/docker-compose.prod.local.yaml | 4 +- docker/docker-compose.yaml | 1 + 6 files changed, 7 insertions(+), 51 deletions(-) delete mode 100644 TEKDB/prod.Dockerfile diff --git a/.github/workflows/create-and-publish-docker-images.yml b/.github/workflows/create-and-publish-docker-images.yml index 658a2459..d58cffc7 100644 --- a/.github/workflows/create-and-publish-docker-images.yml +++ b/.github/workflows/create-and-publish-docker-images.yml @@ -54,7 +54,7 @@ jobs: uses: docker/build-push-action@v6 with: context: ./TEKDB - file: ./TEKDB/prod.Dockerfile + file: ./TEKDB/Dockerfile push: true tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/web:latest,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/web:${{ github.sha }} labels: ${{ steps.meta.outputs.labels }} diff --git a/TEKDB/Dockerfile b/TEKDB/Dockerfile index 1ba7ac1f..78fb2bd3 100644 --- a/TEKDB/Dockerfile +++ b/TEKDB/Dockerfile @@ -42,5 +42,3 @@ ENV DJANGO_SETTINGS_MODULE=TEKDB.settings ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] -# use development server by default -CMD ["dev"] diff --git a/TEKDB/entrypoint.sh b/TEKDB/entrypoint.sh index 182563da..a0644cd0 100644 --- a/TEKDB/entrypoint.sh +++ b/TEKDB/entrypoint.sh @@ -34,6 +34,9 @@ fi if [ "$1" = "prod" ]; then echo "Starting uWSGI (socket) on :8000" uwsgi --socket :8000 --master --enable-threads --module TEKDB.wsgi +elif [ "$1" = "prod-local" ]; then + echo "Starting uWSGI (http) on :8000 with local settings" + uwsgi --http :8000 --master --enable-threads --module TEKDB.wsgi elif [ "$1" = "dev" ]; then echo "Starting python development server on :8000" python manage.py runserver 0.0.0.0:8000 diff --git a/TEKDB/prod.Dockerfile b/TEKDB/prod.Dockerfile deleted file mode 100644 index ca2d2e24..00000000 --- a/TEKDB/prod.Dockerfile +++ /dev/null @@ -1,46 +0,0 @@ -FROM python:3.11-slim - -# Prevent Python from writing .pyc files and enable unbuffered stdout/stderr -ENV PYTHONDONTWRITEBYTECODE=1 -ENV PYTHONUNBUFFERED=1 -ENV PIP_NO_CACHE_DIR=1 - -# Install system dependencies -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - postgresql-client \ - gcc \ - gdal-bin \ - libgdal-dev \ - libgeos-dev \ - && rm -rf /var/lib/apt/lists/* - -# Set working directory -WORKDIR /usr/src/app - -# Copy requirements first (cache pip install step when dependencies don't change) -COPY requirements.txt requirements_linux.txt /usr/src/app/ - -# Upgrade pip and install Python dependencies -# Note: editable packages (-e) will be installed at runtime via entrypoint.sh -RUN pip install --upgrade pip \ - && pip install -r requirements.txt -r requirements_linux.txt - -# Copy the application code -COPY . /usr/src/app - -# Copy and make entrypoint executable. The repository contains `docker/entrypoint.sh` -# which runs collectstatic, migrations and launches uWSGI. -COPY entrypoint.sh /usr/local/bin/entrypoint.sh -RUN chmod +x /usr/local/bin/entrypoint.sh - -# Expose the port the app runs on (entrypoint starts django development server or uWSGI on 8000) -EXPOSE 8000 - -# Default settings module (can be overridden at runtime) -ENV DJANGO_SETTINGS_MODULE=TEKDB.settings - -ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] - -# use prod server in prod Dockerfile -CMD ["prod"] \ No newline at end of file diff --git a/docker/docker-compose.prod.local.yaml b/docker/docker-compose.prod.local.yaml index 2f0b55b9..421e3d93 100644 --- a/docker/docker-compose.prod.local.yaml +++ b/docker/docker-compose.prod.local.yaml @@ -8,9 +8,9 @@ services: extends: file: common.yaml service: web - command: ["prod"] + command: ["prod-local"] env_file: - - .env.prod + - .env.dev ports: [] volumes: - static_volume:/usr/src/app/static diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 5969649f..742ef053 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -8,6 +8,7 @@ services: extends: file: common.yaml service: web + command: ["dev"] volumes: - ../TEKDB:/usr/src/app environment: