Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Podmanify MUSCLE applications to enable automatic CI/CD #722

Merged
merged 67 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
a366c83
config(docker): Add Docker Compose file for production environment an…
drikusroor Jan 19, 2024
090ed1b
chore: Rename docker-compose file for deployment
drikusroor Jan 19, 2024
621f459
ci: Add Podman build & deploy workflow
drikusroor Jan 19, 2024
65cf453
fix: Update Podman image build and deployment configuration path
drikusroor Jan 19, 2024
b426098
config(docker): Add ip2country service to docker-compose-deploy.yml
drikusroor Jan 24, 2024
b45549b
ci: Use actions/checkout@v4 instead of v3
drikusroor Jan 24, 2024
060338e
ci(podman): Configure db service with bind mounts
drikusroor Jan 25, 2024
199bb51
ci: Use test environment variables in podman workflow for now
drikusroor Jan 25, 2024
beb7ee8
ci: Add server configuration
drikusroor Jan 26, 2024
1c510fb
ci: Check podman images after deploy
drikusroor Jan 26, 2024
7337963
ci: Update podman-compose command to force recreate containers
drikusroor Feb 1, 2024
ffb149f
ci: Add check for DJANGO_SETTINGS_MODULE environment variable
drikusroor Feb 1, 2024
4e63521
ci: Add environment variables and secrets to Podman workflow
drikusroor Feb 1, 2024
02514ab
ci: Add environment variable checks and log Podman images***
drikusroor Feb 1, 2024
5b5dc6e
ci: Add SQL_PORT environment variable
drikusroor Feb 1, 2024
1206ebb
ci: Update environment variables in podman.yml and docker-compose-dep…
drikusroor Feb 2, 2024
e1e0485
ci: Use DockerfileDevelop for server for now
drikusroor Feb 2, 2024
1ab23cf
ci: Update Podman workflow: Check logs of server service container af…
drikusroor Feb 2, 2024
c97ef21
config(docker): Add test target to DockerfileDevelop and docker-compo…
drikusroor Feb 2, 2024
856da91
ci: Update Podman workflow to check logs using podman-compose
drikusroor Feb 2, 2024
4bf3d37
config(docker): Update DockerfileDevelop to use python:3.8 as base image
drikusroor Feb 2, 2024
32528ff
ci: Refactor docker-compose-deploy.yml to run manage.py commands sepa…
drikusroor Feb 2, 2024
673c0bb
ci: Add Django superuser credentials to environment variables
drikusroor Feb 2, 2024
d15d8ed
ci: Refactor command in docker-compose-deploy.yml
drikusroor Feb 2, 2024
e4487f2
ci: Add check for Django superuser environment variables
drikusroor Feb 5, 2024
3a3c5a5
config(docker): Install devtools if AML_DEBUG is set to true
drikusroor Feb 5, 2024
7017f26
ci: Split up the backend's deploy commands
drikusroor Feb 5, 2024
40d3155
ci: Use correct container name
drikusroor Feb 5, 2024
1706a47
revert: Re-combine commands
drikusroor Feb 5, 2024
a4103f4
config: Add conditional installation of django-debug-toolbar in Docke…
drikusroor Feb 5, 2024
891004b
chore(deps): Add django-debug-toolbar to base.txt for development and…
drikusroor Feb 5, 2024
dbf5e68
ci: Add Podman check status workflow
drikusroor Feb 5, 2024
63b9de1
ci: Add healthcheck start_period to docker-compose file
drikusroor Feb 5, 2024
cf461e9
chore(deps): Move django-debug-toolbar back to development requirements
drikusroor Feb 6, 2024
63d02c0
config(docker): Add AML_DEBUG environment variable to docker-compose …
drikusroor Feb 6, 2024
3cf2ad9
ci: Add empty string for RUNNER_TRACKING_ID
drikusroor Feb 6, 2024
214dd70
ci: Add .env file and break cache in Dockerfile
drikusroor Feb 6, 2024
e858364
ci: Add subpath support
drikusroor Feb 6, 2024
6eb8d64
config: Add nginx-proxy service and custom-nginx.conf file
drikusroor Feb 7, 2024
a1d7fdd
config: Remove muscle client container
drikusroor Feb 7, 2024
ec73dbf
config: Refactor proxy_pass configuration in custom-nginx.conf
drikusroor Feb 7, 2024
4f67944
ci: Remove check status workflow
drikusroor Feb 7, 2024
6c035c1
config: Remove unnecessary settings related to static and media roots…
drikusroor Feb 7, 2024
a6dfd13
fix: Fix proxy URL in custom-nginx.conf
drikusroor Feb 7, 2024
4662b8d
config: Update nginx configuration to proxy requests to Django app
drikusroor Feb 7, 2024
631545e
config: Remove unnecessary commands and update Django settings and ng…
drikusroor Feb 7, 2024
892bc80
config: Update proxy_pass URL in custom-nginx.conf
drikusroor Feb 7, 2024
db0fd72
config: Add server dependency to docker-compose-deploy.yml
drikusroor Feb 7, 2024
8194a2b
config: Update static file URLs in production settings and nginx config
drikusroor Feb 7, 2024
8278b64
config: Add proxy_redirect off directive to custom-nginx.conf
drikusroor Feb 7, 2024
4628457
config: Add subpath for running Django on /server
drikusroor Feb 7, 2024
b9c41db
config: Commented out root location in custom-nginx.conf
drikusroor Feb 7, 2024
7ee0aba
config: Add proxy configuration for server
drikusroor Feb 7, 2024
b876c96
config: Update Django configuration to remove subpath /server/
drikusroor Feb 7, 2024
4b88621
config: Add proxy configuration for /server/ route
drikusroor Feb 7, 2024
7dc7078
config: Add URL prefix for server endpoints
drikusroor Feb 7, 2024
8f9d267
config: Update nginx configuration to serve frontend files for root r…
drikusroor Feb 7, 2024
4e4bcb8
docs: Add comment to STATIC_URL in production_settings.py
drikusroor Feb 8, 2024
d4f42d1
ci: Add some documentation & rename job to deploy-test
drikusroor Feb 8, 2024
8649235
config(nginx): Use root instead of alias
drikusroor Feb 8, 2024
bf21c6d
config(nginx): Mount django static assets & uploads directly in nginx…
drikusroor Feb 8, 2024
577130a
refactor: Update dev.txt with django-debug-toolbar
drikusroor Feb 14, 2024
78d7259
config: Add AML_SUBPATH environment variable
drikusroor Feb 14, 2024
960fb23
ci: Update runs-on value from "self-hosted" to "tst" in podman.yml
drikusroor Feb 14, 2024
c56d355
ci: Run deploy-test job on develop branch only
drikusroor Feb 14, 2024
3003d0f
ci: Add concurrency group for workflow on develop branch
drikusroor Feb 14, 2024
2d419e8
docker: Fetch Node.js 18 alpine image explicitly from docker.io
drikusroor Feb 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/workflows/podman.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Podman build & deploy

on:
push:
branches:
- develop
workflow_dispatch:

jobs:
deploy-test:
name: Deploy to test environment
environment: test
runs-on: tst
if: github.ref == 'refs/heads/develop'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
env:

# Variables
AML_ALLOWED_HOSTS: ${{ vars.AML_ALLOWED_HOSTS }}
AML_CORS_ORIGIN_WHITELIST: ${{ vars.AML_CORS_ORIGIN_WHITELIST }}
AML_DEBUG: ${{ vars.AML_DEBUG }}
AML_LOCATION_PROVIDER: ${{ vars.AML_LOCATION_PROVIDER }}
AML_SUBPATH: ${{ vars.AML_SUBPATH }}
DJANGO_SETTINGS_MODULE: ${{ vars.DJANGO_SETTINGS_MODULE }}
SQL_DATABASE: ${{ vars.SQL_DATABASE }}
SQL_HOST: ${{ vars.SQL_HOST }}
SQL_PORT: ${{ vars.SQL_PORT }}
REACT_APP_API_ROOT: ${{ vars.REACT_APP_API_ROOT }}
REACT_APP_EXPERIMENT_SLUG: ${{ vars.REACT_APP_EXPERIMENT_SLUG }}
REACT_APP_AML_HOME: ${{ vars.REACT_APP_AML_HOME }}
REACT_APP_HTML_PAGE_TITLE: ${{ vars.REACT_APP_HTML_PAGE_TITLE }}

# Secrets
AML_SECRET_KEY: ${{ secrets.AML_SECRET_KEY }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SQL_USER: ${{ secrets.SQL_USER }}
SQL_PASSWORD: ${{ secrets.SQL_PASSWORD }}
REACT_APP_SENTRY_DSN: ${{ secrets.REACT_APP_SENTRY_DSN }}
DJANGO_SUPERUSER_USERNAME: ${{ secrets.DJANGO_SUPERUSER_USERNAME }}
DJANGO_SUPERUSER_PASSWORD: ${{ secrets.DJANGO_SUPERUSER_PASSWORD }}
DJANGO_SUPERUSER_EMAIL: ${{ secrets.DJANGO_SUPERUSER_EMAIL }}

# Prevent podman services from exiting after startup
RUNNER_TRACKING_ID: ""

steps:
- uses: actions/checkout@v4
- name: Create .env file
run: |
touch .env
echo "REACT_APP_API_ROOT=$REACT_APP_API_ROOT" >> .env
echo "REACT_APP_EXPERIMENT_SLUG=$REACT_APP_EXPERIMENT_SLUG" >> .env
echo "REACT_APP_AML_HOME=$REACT_APP_AML_HOME" >> .env
echo "REACT_APP_HTML_PAGE_TITLE=$REACT_APP_HTML_PAGE_TITLE" >> .env
echo "REACT_APP_SENTRY_DSN=$REACT_APP_SENTRY_DSN" >> .env
cp .env frontend/.env
- name: Build Podman images
run: podman-compose -f docker-compose-deploy.yml build
- name: Deploy Podman images
run: podman-compose -f docker-compose-deploy.yml up -d --force-recreate
- name: Check Podman images
run: podman-compose -f docker-compose-deploy.yml ps
- name: Check logs
run: podman-compose -f docker-compose-deploy.yml logs
6 changes: 3 additions & 3 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.8
FROM docker.io/python:3.8
ENV PYTHONUNBUFFERED 1
RUN apt-get -y update
RUN apt-get install -y ffmpeg
Expand All @@ -7,6 +7,6 @@ RUN apt-get install -y gettext
WORKDIR /server
COPY requirements/prod.txt /server/
RUN pip install -r prod.txt
# We add remainig code later, so pip install won't need to rerun if source code changes
COPY . /server/

# We add remainig code later, so pip install won't need to rerun if source code changes
COPY . /server/
5 changes: 2 additions & 3 deletions backend/DockerfileDevelop
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
FROM python:3.8
FROM docker.io/python:3.8 as base
ENV PYTHONUNBUFFERED 1
RUN apt-get -y update
RUN apt-get install -y ffmpeg

WORKDIR /server
COPY requirements/dev.txt /server/
RUN pip install -r dev.txt

RUN pip install -r dev.txt
2 changes: 2 additions & 0 deletions backend/aml/base_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,5 @@
# We recommend adjusting this value in production.
profiles_sample_rate=0.2,
)

SUBPATH = os.getenv('AML_SUBPATH', None)
2 changes: 2 additions & 0 deletions backend/aml/production_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases

# Static url is set to /django_static/ in the nginx configuration
# to avoid conflicts with the frontend's static files in /static/
STATIC_URL = '/django_static/'

DATABASES = {
Expand Down
5 changes: 5 additions & 0 deletions backend/aml/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
# ^ The static helper function only works in debug mode
# (https://docs.djangoproject.com/en/3.0/howto/static-files/)


# Prefix all URLS with /server if AML_SUBPATH is set
if settings.SUBPATH:
urlpatterns = [path('server/', include(urlpatterns))]

# Debug toolbar
if settings.DEBUG:
import debug_toolbar
Expand Down
7 changes: 4 additions & 3 deletions backend/requirements/dev.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# This file is autogenerated by pip-compile with python 3.8
# To update, run:
# This file is autogenerated by pip-compile with Python 3.8
# by the following command:
#
# pip-compile --output-file=requirements/dev.txt requirements.in/dev.txt
#
Expand Down Expand Up @@ -36,7 +36,7 @@ django==3.2.24
# django-inline-actions
django-cors-headers==3.10.0
# via -r requirements.in/base.txt
django-debug-toolbar==3.2.2
django-debug-toolbar==4.3.0
# via -r requirements.in/dev.txt
django-inline-actions==2.4.0
# via -r requirements.in/base.txt
Expand Down Expand Up @@ -102,6 +102,7 @@ requests==2.31.0
# -r requirements.in/dev.txt
# genbadge
roman==4.1
# via -r requirements.in/base.txt
sentry-sdk==1.38.0
# via -r requirements.in/base.txt
six==1.16.0
Expand Down
5 changes: 3 additions & 2 deletions backend/requirements/prod.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# This file is autogenerated by pip-compile with python 3.8
# To update, run:
# This file is autogenerated by pip-compile with Python 3.8
# by the following command:
#
# pip-compile --output-file=requirements/prod.txt requirements.in/prod.txt
#
Expand Down Expand Up @@ -56,6 +56,7 @@ pytz==2023.3
requests==2.31.0
# via genbadge
roman==4.1
# via -r requirements.in/base.txt
sentry-sdk==1.38.0
# via -r requirements.in/base.txt
six==1.16.0
Expand Down
108 changes: 108 additions & 0 deletions docker-compose-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
version: '3.8'

services:
db:
image: postgres
environment:
- POSTGRES_DB=${SQL_DATABASE}
- POSTGRES_USER=${SQL_USER}
- POSTGRES_PASSWORD=${SQL_PASSWORD}
- PGHOST=${SQL_HOST}
- PGPORT=${SQL_PORT}
- PGUSER=${SQL_USER}
- PGDATABASE=${SQL_DATABASE}
- PGPASSWORD=${SQL_PASSWORD}
volumes:
- /home/github-runner/podman-volumes/db-data:/var/lib/postgresql/data
- /home/github-runner/podman-volumes/db-backups:/backups
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
start_period: 5s
interval: 5s
timeout: 5s
retries: 5
ip2country:
image: extrawurst/ip2country:latest
ports:
- 8854:5000
server:
build:
context: ./backend
dockerfile: Dockerfile
depends_on:
db:
condition: service_healthy
ip2country:
condition: service_started
volumes:
- /home/github-runner/podman-volumes/server-static:/server/static
- /home/github-runner/podman-volumes/server-logs:/server/logs
- /home/github-runner/podman-volumes/server-uploads:/server/upload
environment:
- AML_ALLOWED_HOSTS=${AML_ALLOWED_HOSTS}
- AML_DEBUG=${AML_DEBUG}
- AML_CORS_ORIGIN_WHITELIST=${AML_CORS_ORIGIN_WHITELIST}
- AML_LOCATION_PROVIDER=${AML_LOCATION_PROVIDER}
- AML_SECRET_KEY=${AML_SECRET_KEY}
- AML_SUBPATH=${AML_SUBPATH}
- DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE}
- DJANGO_SUPERUSER_USERNAME=${DJANGO_SUPERUSER_USERNAME}
- DJANGO_SUPERUSER_EMAIL=${DJANGO_SUPERUSER_EMAIL}
- DJANGO_SUPERUSER_PASSWORD=${DJANGO_SUPERUSER_PASSWORD}
- SENTRY_DSN=${SENTRY_DSN}
- SQL_DATABASE=${SQL_DATABASE}
- SQL_USER=${SQL_USER}
- SQL_PASSWORD=${SQL_PASSWORD}
- SQL_HOST=${SQL_HOST}
ports:
- 8000:8000
command: bash -c "python manage.py migrate && python manage.py bootstrap && python manage.py collectstatic --noinput && gunicorn aml.wsgi:application --bind 0.0.0.0:8000"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an idea, we can also do this later: we might start up gunicorn with multiple workers, which may help us with high server loads.

client-builder:
build:
context: ./frontend
dockerfile: Dockerfile
target: builder
volumes:
- type: bind
source: ./frontend/src
target: /client/src
- type: bind
source: ./frontend/public
target: /client/public
- type: bind
source: ./frontend/.storybook
target: /client/.storybook
environment:
- REACT_APP_API_ROOT=${REACT_APP_API_ROOT}
- REACT_APP_EXPERIMENT_SLUG=${REACT_APP_EXPERIMENT_SLUG}
- REACT_APP_AML_HOME=${REACT_APP_AML_HOME}
- REACT_APP_LOGO_URL=${REACT_APP_LOGO_URL}
- REACT_APP_HTML_FAVICON=${REACT_APP_HTML_FAVICON}
- REACT_APP_HTML_PAGE_TITLE=${REACT_APP_HTML_PAGE_TITLE}
- REACT_APP_HTML_OG_DESCRIPTION=${REACT_APP_HTML_OG_DESCRIPTION}
- REACT_APP_HTML_OG_IMAGE=${REACT_APP_HTML_OG_IMAGE}
- REACT_APP_HTML_OG_TITLE=${REACT_APP_HTML_OG_TITLE}
- REACT_APP_HTML_OG_URL=${REACT_APP_HTML_OG_URL}
- REACT_APP_HTML_BODY_CLASS=${REACT_APP_HTML_BODY_CLASS}
- REACT_APP_SENTRY_DSN=${REACT_APP_SENTRY_DSN}
- REACT_APP_STRICT=${REACT_APP_STRICT}

# This service is responsible for serving
# 1. The built frontend from the client-builder service
# 2. The static files from the server service (e.g., static files & uploads from the Django app)
nginx-proxy:
build:
context: ./frontend
dockerfile: Dockerfile
target: runner
command: nginx -g 'daemon off;'
ports:
- 3000:80
depends_on:
- client-builder
- server
volumes:
- /home/github-runner/podman-volumes/server-static:/usr/share/nginx/html/django_static
- /home/github-runner/podman-volumes/server-uploads:/usr/share/nginx/html/upload
- ./nginx/custom-nginx.conf:/etc/nginx/conf.d/default.conf

17 changes: 15 additions & 2 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
FROM node:18-alpine
# Builder image
FROM docker.io/node:18-alpine as builder

RUN yarn set version stable
WORKDIR /client
COPY package.json /client/
COPY yarn.lock /client/
COPY jsconfig.json /client/
RUN yarn
COPY . /client/

# Copy .env file to break the cache
COPY .env /client/

RUN yarn
RUN yarn scss
RUN yarn build

# Runner image that serves the built app using nginx
FROM docker.io/nginx:alpine as runner

COPY --from=builder /client/build /usr/share/nginx/html
EXPOSE 80
18 changes: 18 additions & 0 deletions nginx/custom-nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
server {
listen 80;

# Serve frontend files for root requests
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}

# Proxy pass to the Django app
location /server/ {
proxy_pass http://server:8000;
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;
}
}
Loading