From 8b99e73284ea1df302a2eb9b4b495becd444847e Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Wed, 11 Dec 2024 20:05:31 +0300 Subject: [PATCH 1/8] updated deploypreview workflow and docker files accordingly --- .github/workflows/deploy-previews.yml | 6 ++-- src/website/Dockerfile | 12 +++---- src/website/docker-compose.yml | 37 +++++++++++++++++++ src/website/entrypoint.sh | 7 ++-- src/website/nginx/Dockerfile | 10 ++++++ src/website/nginx/nginx.conf | 51 +++++++++++++++++++++++++++ 6 files changed, 108 insertions(+), 15 deletions(-) create mode 100644 src/website/docker-compose.yml create mode 100644 src/website/nginx/Dockerfile create mode 100644 src/website/nginx/nginx.conf diff --git a/.github/workflows/deploy-previews.yml b/.github/workflows/deploy-previews.yml index ae12f1a6d9..2c6fa4aa50 100644 --- a/.github/workflows/deploy-previews.yml +++ b/.github/workflows/deploy-previews.yml @@ -1192,7 +1192,7 @@ jobs: --timeout=60 \ --concurrency=10 \ --image=${{ env.REGISTRY_URL }}/${{ env.PROJECT_ID }}/pr-previews/website-pr-previews:${{ github.sha }} \ - --port=8000 \ + --port=8080 \ --cpu=1000m \ --memory=1024Mi \ --update-secrets=/etc/env/.env=sta-env-website-backend:latest,/etc/config/google_application_credentials.json=sta-key-analytics-service-account:latest \ @@ -1221,5 +1221,5 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: 'website changes in this PR available for preview [here](${{ needs.website.outputs.url }})' - }) \ No newline at end of file + body: 'website changes in this PR available for preview [here](${needs.website.outputs.url})' + }) diff --git a/src/website/Dockerfile b/src/website/Dockerfile index 449e362eac..48f41122d1 100644 --- a/src/website/Dockerfile +++ b/src/website/Dockerfile @@ -5,7 +5,6 @@ FROM python:3.11-slim ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 -# Set the working directory inside the container WORKDIR /app # Install system dependencies @@ -14,18 +13,17 @@ RUN apt-get update && apt-get install -y \ libpq-dev \ && apt-get clean -# Copy requirements file and install dependencies -COPY requirements.txt ./ +# Copy requirements and install +COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -# Copy the rest of the backend code into the container +# Copy the rest of the code COPY . . -# Expose the port the Django app will run on +# Expose the port for Gunicorn EXPOSE 8000 -# Add execution permissions to entrypoint.sh +# Add execute permission to entrypoint.sh RUN chmod +x /app/entrypoint.sh -# Set the entrypoint for the container ENTRYPOINT ["/app/entrypoint.sh"] diff --git a/src/website/docker-compose.yml b/src/website/docker-compose.yml new file mode 100644 index 0000000000..2da1611a56 --- /dev/null +++ b/src/website/docker-compose.yml @@ -0,0 +1,37 @@ +version: "3.8" +services: + web: + build: + context: . + dockerfile: Dockerfile + env_file: .env + expose: + - "8000" + depends_on: + - db + volumes: + - ./staticfiles:/app/staticfiles + + nginx: + build: + context: ./nginx + dockerfile: Dockerfile + ports: + - "80:80" + depends_on: + - web + volumes: + # Mount the staticfiles into Nginx container + - ./staticfiles:/usr/share/nginx/html/static + + db: + image: postgres:15 + environment: + POSTGRES_USER: your_user + POSTGRES_PASSWORD: your_password + POSTGRES_DB: your_db + volumes: + - db_data:/var/lib/postgresql/data + +volumes: + db_data: diff --git a/src/website/entrypoint.sh b/src/website/entrypoint.sh index 217438654c..8aeb5a94b8 100644 --- a/src/website/entrypoint.sh +++ b/src/website/entrypoint.sh @@ -1,16 +1,13 @@ #!/bin/sh -# Exit immediately if a command exits with a non-zero status +# Exit on error set -e -# Run Django migrations echo "Running migrations..." python manage.py migrate --noinput -# Collect static files (ensure the static files directory exists) echo "Collecting static files..." python manage.py collectstatic --noinput -# Start Gunicorn server to serve the Django application -echo "Starting Gunicorn server..." +echo "Starting Gunicorn..." exec gunicorn core.wsgi:application --bind 0.0.0.0:8000 --timeout 600 --workers 3 --log-level info diff --git a/src/website/nginx/Dockerfile b/src/website/nginx/Dockerfile new file mode 100644 index 0000000000..3f6c8e8f6a --- /dev/null +++ b/src/website/nginx/Dockerfile @@ -0,0 +1,10 @@ +FROM nginx:alpine + +# Remove default configuration +RUN rm /etc/nginx/conf.d/default.conf + +# Copy your custom nginx configuration +COPY nginx.conf /etc/nginx/nginx.conf + +# Expose port 80 for Nginx +EXPOSE 80 diff --git a/src/website/nginx/nginx.conf b/src/website/nginx/nginx.conf new file mode 100644 index 0000000000..bb2f31dcc3 --- /dev/null +++ b/src/website/nginx/nginx.conf @@ -0,0 +1,51 @@ +user nginx; +worker_processes auto; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + # Set client body size limit to 10MB + client_max_body_size 10M; + + upstream django_app { + # Points to the Django/Gunicorn container service name defined in docker-compose + server web:8000; + } + + server { + listen 80; + server_name _; + + # Serving static files directly from Nginx + # Assuming 'staticfiles' directory is where Django collectstatic places files + location /static/ { + alias /usr/share/nginx/html/static/; + expires 1y; + access_log off; + add_header Cache-Control "public"; + } + + location / { + proxy_pass http://django_app; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } +} From e870447474edf91dc395da141e150d407296862d Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Wed, 11 Dec 2024 20:26:34 +0300 Subject: [PATCH 2/8] updated the configurations to run one docker file --- .github/workflows/deploy-previews.yml | 9 +++---- src/website/Dockerfile | 19 ++++++++++++-- src/website/docker-compose.yml | 37 --------------------------- src/website/entrypoint.sh | 4 +-- src/website/{nginx => }/nginx.conf | 9 +++---- src/website/nginx/Dockerfile | 10 -------- src/website/supervisord.conf | 13 ++++++++++ 7 files changed, 38 insertions(+), 63 deletions(-) delete mode 100644 src/website/docker-compose.yml rename src/website/{nginx => }/nginx.conf (72%) delete mode 100644 src/website/nginx/Dockerfile create mode 100644 src/website/supervisord.conf diff --git a/.github/workflows/deploy-previews.yml b/.github/workflows/deploy-previews.yml index 2c6fa4aa50..2e942d6b98 100644 --- a/.github/workflows/deploy-previews.yml +++ b/.github/workflows/deploy-previews.yml @@ -1186,17 +1186,14 @@ jobs: - name: Deploy to Cloud Run run: |- - gcloud run deploy ${{ needs.branch-name.outputs.lowercase }}-website-preview \ - --region=${{ secrets.REGION }} \ + gcloud run deploy website-backend-nginix-website-preview \ + --region=${REGION} \ --max-instances=10 \ --timeout=60 \ --concurrency=10 \ - --image=${{ env.REGISTRY_URL }}/${{ env.PROJECT_ID }}/pr-previews/website-pr-previews:${{ github.sha }} \ - --port=8080 \ + --image=${REGISTRY_URL}/${PROJECT_ID}/pr-previews/website-pr-previews:${GITHUB_SHA} \ --cpu=1000m \ --memory=1024Mi \ - --update-secrets=/etc/env/.env=sta-env-website-backend:latest,/etc/config/google_application_credentials.json=sta-key-analytics-service-account:latest \ - --command="/bin/sh","-c","cat /etc/env/.env >> /app/.env; /app/entrypoint.sh" \ --allow-unauthenticated - name: Get preview service url diff --git a/src/website/Dockerfile b/src/website/Dockerfile index 48f41122d1..1b163df12e 100644 --- a/src/website/Dockerfile +++ b/src/website/Dockerfile @@ -11,6 +11,8 @@ WORKDIR /app RUN apt-get update && apt-get install -y \ gcc \ libpq-dev \ + nginx \ + supervisor \ && apt-get clean # Copy requirements and install @@ -20,10 +22,23 @@ RUN pip install --no-cache-dir -r requirements.txt # Copy the rest of the code COPY . . -# Expose the port for Gunicorn -EXPOSE 8000 +# Remove default Nginx config +RUN rm /etc/nginx/conf.d/default.conf + +# Make sure we have a directory for static files (to serve them via Nginx) +RUN mkdir -p /usr/share/nginx/html/static/ # Add execute permission to entrypoint.sh RUN chmod +x /app/entrypoint.sh +# Copy custom Nginx config +COPY nginx.conf /etc/nginx/nginx.conf + +# Copy supervisor config +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf + +# Default port for Cloud Run is 8080, ensure Nginx listens on this port +ENV PORT 8080 +EXPOSE 8080 + ENTRYPOINT ["/app/entrypoint.sh"] diff --git a/src/website/docker-compose.yml b/src/website/docker-compose.yml deleted file mode 100644 index 2da1611a56..0000000000 --- a/src/website/docker-compose.yml +++ /dev/null @@ -1,37 +0,0 @@ -version: "3.8" -services: - web: - build: - context: . - dockerfile: Dockerfile - env_file: .env - expose: - - "8000" - depends_on: - - db - volumes: - - ./staticfiles:/app/staticfiles - - nginx: - build: - context: ./nginx - dockerfile: Dockerfile - ports: - - "80:80" - depends_on: - - web - volumes: - # Mount the staticfiles into Nginx container - - ./staticfiles:/usr/share/nginx/html/static - - db: - image: postgres:15 - environment: - POSTGRES_USER: your_user - POSTGRES_PASSWORD: your_password - POSTGRES_DB: your_db - volumes: - - db_data:/var/lib/postgresql/data - -volumes: - db_data: diff --git a/src/website/entrypoint.sh b/src/website/entrypoint.sh index 8aeb5a94b8..e0b79fe390 100644 --- a/src/website/entrypoint.sh +++ b/src/website/entrypoint.sh @@ -9,5 +9,5 @@ python manage.py migrate --noinput echo "Collecting static files..." python manage.py collectstatic --noinput -echo "Starting Gunicorn..." -exec gunicorn core.wsgi:application --bind 0.0.0.0:8000 --timeout 600 --workers 3 --log-level info +echo "Starting Supervisor (which runs Nginx + Gunicorn)..." +exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf diff --git a/src/website/nginx/nginx.conf b/src/website/nginx.conf similarity index 72% rename from src/website/nginx/nginx.conf rename to src/website/nginx.conf index bb2f31dcc3..f0f7f09eb7 100644 --- a/src/website/nginx/nginx.conf +++ b/src/website/nginx.conf @@ -19,20 +19,17 @@ http { access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; - # Set client body size limit to 10MB client_max_body_size 10M; upstream django_app { - # Points to the Django/Gunicorn container service name defined in docker-compose - server web:8000; + # Gunicorn will be running on 127.0.0.1:8000 inside the same container + server 127.0.0.1:8000; } server { - listen 80; + listen ${PORT}; server_name _; - # Serving static files directly from Nginx - # Assuming 'staticfiles' directory is where Django collectstatic places files location /static/ { alias /usr/share/nginx/html/static/; expires 1y; diff --git a/src/website/nginx/Dockerfile b/src/website/nginx/Dockerfile deleted file mode 100644 index 3f6c8e8f6a..0000000000 --- a/src/website/nginx/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM nginx:alpine - -# Remove default configuration -RUN rm /etc/nginx/conf.d/default.conf - -# Copy your custom nginx configuration -COPY nginx.conf /etc/nginx/nginx.conf - -# Expose port 80 for Nginx -EXPOSE 80 diff --git a/src/website/supervisord.conf b/src/website/supervisord.conf new file mode 100644 index 0000000000..1636b94653 --- /dev/null +++ b/src/website/supervisord.conf @@ -0,0 +1,13 @@ +[supervisord] +nodaemon=true + +[program:gunicorn] +command=gunicorn core.wsgi:application --bind 0.0.0.0:8000 --timeout 600 --workers 3 --log-level info +directory=/app +autostart=true +autorestart=true + +[program:nginx] +command=/usr/sbin/nginx -g "daemon off;" +autostart=true +autorestart=true From f68fde67fc35dfbf44785d0abf24e1ba43781d1b Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Wed, 11 Dec 2024 20:41:03 +0300 Subject: [PATCH 3/8] update --- .github/workflows/deploy-previews.yml | 12 ++++----- src/website/Dockerfile | 37 +++++++++++++++------------ src/website/entrypoint.sh | 2 +- src/website/nginx.conf | 5 +++- src/website/supervisord.conf | 6 ++++- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/.github/workflows/deploy-previews.yml b/.github/workflows/deploy-previews.yml index 2e942d6b98..58586eeb5b 100644 --- a/.github/workflows/deploy-previews.yml +++ b/.github/workflows/deploy-previews.yml @@ -1180,18 +1180,18 @@ jobs: - name: Build and Push Container run: | - cd src/website/ - docker build --tag ${{ env.REGISTRY_URL }}/${{ env.PROJECT_ID }}/pr-previews/website-pr-previews:${{ github.sha }} ./ + cd website/ + docker build --tag ${{ env.REGISTRY_URL }}/${{ env.PROJECT_ID }}/pr-previews/website-pr-previews:${{ github.sha }} . docker push ${{ env.REGISTRY_URL }}/${{ env.PROJECT_ID }}/pr-previews/website-pr-previews:${{ github.sha }} - name: Deploy to Cloud Run run: |- - gcloud run deploy website-backend-nginix-website-preview \ - --region=${REGION} \ + gcloud run deploy ${{ needs.branch-name.outputs.lowercase }}-website-preview \ + --region=${{ secrets.REGION }} \ --max-instances=10 \ --timeout=60 \ --concurrency=10 \ - --image=${REGISTRY_URL}/${PROJECT_ID}/pr-previews/website-pr-previews:${GITHUB_SHA} \ + --image=${{ env.REGISTRY_URL }}/${{ env.PROJECT_ID }}/pr-previews/website-pr-previews:${{ github.sha }} \ --cpu=1000m \ --memory=1024Mi \ --allow-unauthenticated @@ -1218,5 +1218,5 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: 'website changes in this PR available for preview [here](${needs.website.outputs.url})' + body: 'Website changes in this PR are available for preview [here](${{ needs.website.outputs.url }})' }) diff --git a/src/website/Dockerfile b/src/website/Dockerfile index 1b163df12e..37c527ce81 100644 --- a/src/website/Dockerfile +++ b/src/website/Dockerfile @@ -2,9 +2,10 @@ FROM python:3.11-slim # Set environment variables -ENV PYTHONDONTWRITEBYTECODE 1 -ENV PYTHONUNBUFFERED 1 +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 +# Set work directory WORKDIR /app # Install system dependencies @@ -13,32 +14,36 @@ RUN apt-get update && apt-get install -y \ libpq-dev \ nginx \ supervisor \ - && apt-get clean + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* -# Copy requirements and install +# Copy requirements and install Python dependencies COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -# Copy the rest of the code +# Copy project code COPY . . -# Remove default Nginx config -RUN rm /etc/nginx/conf.d/default.conf +# Remove default Nginx configuration if it exists +RUN rm -f /etc/nginx/conf.d/default.conf -# Make sure we have a directory for static files (to serve them via Nginx) +# Copy custom Nginx configuration +COPY nginx.conf /etc/nginx/nginx.conf + +# Ensure staticfiles directory exists for Nginx RUN mkdir -p /usr/share/nginx/html/static/ -# Add execute permission to entrypoint.sh -RUN chmod +x /app/entrypoint.sh +# Copy Supervisor configuration +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf -# Copy custom Nginx config -COPY nginx.conf /etc/nginx/nginx.conf +# Make entrypoint.sh executable +RUN chmod +x /app/entrypoint.sh -# Copy supervisor config -COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +# Set the PORT environment variable (Cloud Run uses 8080 by default) +ENV PORT=8080 -# Default port for Cloud Run is 8080, ensure Nginx listens on this port -ENV PORT 8080 +# Expose the port EXPOSE 8080 +# Start the entrypoint script ENTRYPOINT ["/app/entrypoint.sh"] diff --git a/src/website/entrypoint.sh b/src/website/entrypoint.sh index e0b79fe390..f865e28d4f 100644 --- a/src/website/entrypoint.sh +++ b/src/website/entrypoint.sh @@ -9,5 +9,5 @@ python manage.py migrate --noinput echo "Collecting static files..." python manage.py collectstatic --noinput -echo "Starting Supervisor (which runs Nginx + Gunicorn)..." +echo "Starting Supervisor (which runs Nginx and Gunicorn)..." exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf diff --git a/src/website/nginx.conf b/src/website/nginx.conf index f0f7f09eb7..ca129ccca5 100644 --- a/src/website/nginx.conf +++ b/src/website/nginx.conf @@ -19,10 +19,11 @@ http { access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; + # Set client body size limit to 10MB client_max_body_size 10M; upstream django_app { - # Gunicorn will be running on 127.0.0.1:8000 inside the same container + # Gunicorn is running on 127.0.0.1:8000 inside the container server 127.0.0.1:8000; } @@ -30,6 +31,7 @@ http { listen ${PORT}; server_name _; + # Serve static files location /static/ { alias /usr/share/nginx/html/static/; expires 1y; @@ -37,6 +39,7 @@ http { add_header Cache-Control "public"; } + # Proxy all other requests to Gunicorn location / { proxy_pass http://django_app; proxy_set_header Host $host; diff --git a/src/website/supervisord.conf b/src/website/supervisord.conf index 1636b94653..f893956ffb 100644 --- a/src/website/supervisord.conf +++ b/src/website/supervisord.conf @@ -2,12 +2,16 @@ nodaemon=true [program:gunicorn] -command=gunicorn core.wsgi:application --bind 0.0.0.0:8000 --timeout 600 --workers 3 --log-level info +command=gunicorn core.wsgi:application --bind 127.0.0.1:8000 --timeout 600 --workers 3 --log-level info directory=/app autostart=true autorestart=true +stdout_logfile=/var/log/supervisor/gunicorn.log +stderr_logfile=/var/log/supervisor/gunicorn_err.log [program:nginx] command=/usr/sbin/nginx -g "daemon off;" autostart=true autorestart=true +stdout_logfile=/var/log/supervisor/nginx.log +stderr_logfile=/var/log/supervisor/nginx_err.log From 743f2e13250cbfe696ed3a8590733ac0997f669d Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Wed, 11 Dec 2024 20:45:41 +0300 Subject: [PATCH 4/8] UP --- src/website/entrypoint.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/website/entrypoint.sh b/src/website/entrypoint.sh index f865e28d4f..543a17c530 100644 --- a/src/website/entrypoint.sh +++ b/src/website/entrypoint.sh @@ -9,5 +9,9 @@ python manage.py migrate --noinput echo "Collecting static files..." python manage.py collectstatic --noinput +# Move collected static files to the Nginx static directory +echo "Moving static files to Nginx directory..." +cp -r /app/staticfiles/* /usr/share/nginx/html/static/ + echo "Starting Supervisor (which runs Nginx and Gunicorn)..." exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf From 91d2ba6cfbe70b9786b4e6a61678519ff9ec248d Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Wed, 11 Dec 2024 20:48:01 +0300 Subject: [PATCH 5/8] UP --- .github/workflows/deploy-previews.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-previews.yml b/.github/workflows/deploy-previews.yml index 58586eeb5b..4cd5f2d94d 100644 --- a/.github/workflows/deploy-previews.yml +++ b/.github/workflows/deploy-previews.yml @@ -1180,8 +1180,8 @@ jobs: - name: Build and Push Container run: | - cd website/ - docker build --tag ${{ env.REGISTRY_URL }}/${{ env.PROJECT_ID }}/pr-previews/website-pr-previews:${{ github.sha }} . + cd src/website/ + docker build --tag ${{ env.REGISTRY_URL }}/${{ env.PROJECT_ID }}/pr-previews/website-pr-previews:${{ github.sha }} ./ docker push ${{ env.REGISTRY_URL }}/${{ env.PROJECT_ID }}/pr-previews/website-pr-previews:${{ github.sha }} - name: Deploy to Cloud Run @@ -1218,5 +1218,5 @@ jobs: issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - body: 'Website changes in this PR are available for preview [here](${{ needs.website.outputs.url }})' + body: 'website changes in this PR available for preview [here](${{ needs.website.outputs.url }})' }) From c05f399df58805ad0d2bd1bed67eec4096dbf87a Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Wed, 11 Dec 2024 20:58:18 +0300 Subject: [PATCH 6/8] UPDATE --- .github/workflows/deploy-previews.yml | 2 +- src/website/Dockerfile | 7 ++++--- src/website/entrypoint.sh | 4 ++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy-previews.yml b/.github/workflows/deploy-previews.yml index 4cd5f2d94d..707fb98148 100644 --- a/.github/workflows/deploy-previews.yml +++ b/.github/workflows/deploy-previews.yml @@ -1189,7 +1189,7 @@ jobs: gcloud run deploy ${{ needs.branch-name.outputs.lowercase }}-website-preview \ --region=${{ secrets.REGION }} \ --max-instances=10 \ - --timeout=60 \ + --timeout=300 \ --concurrency=10 \ --image=${{ env.REGISTRY_URL }}/${{ env.PROJECT_ID }}/pr-previews/website-pr-previews:${{ github.sha }} \ --cpu=1000m \ diff --git a/src/website/Dockerfile b/src/website/Dockerfile index 37c527ce81..3a498fc29b 100644 --- a/src/website/Dockerfile +++ b/src/website/Dockerfile @@ -8,12 +8,13 @@ ENV PYTHONUNBUFFERED=1 # Set work directory WORKDIR /app -# Install system dependencies +# Install system dependencies, including nginx, supervisor, and gettext for envsubst RUN apt-get update && apt-get install -y \ gcc \ libpq-dev \ nginx \ supervisor \ + gettext \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -27,8 +28,8 @@ COPY . . # Remove default Nginx configuration if it exists RUN rm -f /etc/nginx/conf.d/default.conf -# Copy custom Nginx configuration -COPY nginx.conf /etc/nginx/nginx.conf +# Copy custom Nginx configuration template +COPY nginx.conf /etc/nginx/nginx.conf.template # Ensure staticfiles directory exists for Nginx RUN mkdir -p /usr/share/nginx/html/static/ diff --git a/src/website/entrypoint.sh b/src/website/entrypoint.sh index 543a17c530..88190ea140 100644 --- a/src/website/entrypoint.sh +++ b/src/website/entrypoint.sh @@ -13,5 +13,9 @@ python manage.py collectstatic --noinput echo "Moving static files to Nginx directory..." cp -r /app/staticfiles/* /usr/share/nginx/html/static/ +# Substitute environment variables in nginx.conf.template and generate nginx.conf +echo "Configuring Nginx to listen on PORT=${PORT}..." +envsubst '${PORT}' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf + echo "Starting Supervisor (which runs Nginx and Gunicorn)..." exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf From e506d045b237079d38531a00bc7077ee0a12faee Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Wed, 11 Dec 2024 21:06:31 +0300 Subject: [PATCH 7/8] UPDATES --- src/website/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/website/Dockerfile b/src/website/Dockerfile index 3a498fc29b..09b82bb0fe 100644 --- a/src/website/Dockerfile +++ b/src/website/Dockerfile @@ -41,10 +41,10 @@ COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf RUN chmod +x /app/entrypoint.sh # Set the PORT environment variable (Cloud Run uses 8080 by default) -ENV PORT=8080 +ENV PORT=8000 # Expose the port -EXPOSE 8080 +EXPOSE 8000 # Start the entrypoint script ENTRYPOINT ["/app/entrypoint.sh"] From 19dd69c5f7b91fca0b7b54087deaa67221dac936 Mon Sep 17 00:00:00 2001 From: Ochieng Paul Date: Wed, 11 Dec 2024 22:41:34 +0300 Subject: [PATCH 8/8] update --- .github/workflows/deploy-previews.yml | 5 ++- src/website/Dockerfile | 45 ++++++++------------------- src/website/entrypoint.sh | 17 ++++------ 3 files changed, 23 insertions(+), 44 deletions(-) diff --git a/.github/workflows/deploy-previews.yml b/.github/workflows/deploy-previews.yml index 707fb98148..20ab382da3 100644 --- a/.github/workflows/deploy-previews.yml +++ b/.github/workflows/deploy-previews.yml @@ -1189,11 +1189,14 @@ jobs: gcloud run deploy ${{ needs.branch-name.outputs.lowercase }}-website-preview \ --region=${{ secrets.REGION }} \ --max-instances=10 \ - --timeout=300 \ + --timeout=60 \ --concurrency=10 \ --image=${{ env.REGISTRY_URL }}/${{ env.PROJECT_ID }}/pr-previews/website-pr-previews:${{ github.sha }} \ + --port=8000 \ --cpu=1000m \ --memory=1024Mi \ + --update-secrets=/etc/env/.env=sta-env-website-backend:latest,/etc/config/google_application_credentials.json=sta-key-analytics-service-account:latest \ + --command="/bin/sh","-c","cat /etc/env/.env >> /app/.env; /app/entrypoint.sh" \ --allow-unauthenticated - name: Get preview service url diff --git a/src/website/Dockerfile b/src/website/Dockerfile index 09b82bb0fe..449e362eac 100644 --- a/src/website/Dockerfile +++ b/src/website/Dockerfile @@ -2,49 +2,30 @@ FROM python:3.11-slim # Set environment variables -ENV PYTHONDONTWRITEBYTECODE=1 -ENV PYTHONUNBUFFERED=1 +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 -# Set work directory +# Set the working directory inside the container WORKDIR /app -# Install system dependencies, including nginx, supervisor, and gettext for envsubst +# Install system dependencies RUN apt-get update && apt-get install -y \ gcc \ libpq-dev \ - nginx \ - supervisor \ - gettext \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# Copy requirements and install Python dependencies -COPY requirements.txt . + && apt-get clean + +# Copy requirements file and install dependencies +COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt -# Copy project code +# Copy the rest of the backend code into the container COPY . . -# Remove default Nginx configuration if it exists -RUN rm -f /etc/nginx/conf.d/default.conf - -# Copy custom Nginx configuration template -COPY nginx.conf /etc/nginx/nginx.conf.template - -# Ensure staticfiles directory exists for Nginx -RUN mkdir -p /usr/share/nginx/html/static/ - -# Copy Supervisor configuration -COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf +# Expose the port the Django app will run on +EXPOSE 8000 -# Make entrypoint.sh executable +# Add execution permissions to entrypoint.sh RUN chmod +x /app/entrypoint.sh -# Set the PORT environment variable (Cloud Run uses 8080 by default) -ENV PORT=8000 - -# Expose the port -EXPOSE 8000 - -# Start the entrypoint script +# Set the entrypoint for the container ENTRYPOINT ["/app/entrypoint.sh"] diff --git a/src/website/entrypoint.sh b/src/website/entrypoint.sh index 88190ea140..217438654c 100644 --- a/src/website/entrypoint.sh +++ b/src/website/entrypoint.sh @@ -1,21 +1,16 @@ #!/bin/sh -# Exit on error +# Exit immediately if a command exits with a non-zero status set -e +# Run Django migrations echo "Running migrations..." python manage.py migrate --noinput +# Collect static files (ensure the static files directory exists) echo "Collecting static files..." python manage.py collectstatic --noinput -# Move collected static files to the Nginx static directory -echo "Moving static files to Nginx directory..." -cp -r /app/staticfiles/* /usr/share/nginx/html/static/ - -# Substitute environment variables in nginx.conf.template and generate nginx.conf -echo "Configuring Nginx to listen on PORT=${PORT}..." -envsubst '${PORT}' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf - -echo "Starting Supervisor (which runs Nginx and Gunicorn)..." -exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +# Start Gunicorn server to serve the Django application +echo "Starting Gunicorn server..." +exec gunicorn core.wsgi:application --bind 0.0.0.0:8000 --timeout 600 --workers 3 --log-level info