-
-
Notifications
You must be signed in to change notification settings - Fork 25
Production Deployment
Hosting has been provided by Digital Ocean. We use GitHub Actions to execute workflows required to deploy to a staging and a production environment.
A single host was created for both staging and production environments using the following command. You will need to authenticate using a personal access token to execute these.
doctl auth init --context=cb
doctl --context=cb compute droplet create backend --enable-backups --enable-monitoring --image=docker-18-04 --region=sfo2 --size=s-1vcpu-1gb --ssh-keys=26664376 --tag-names=v3
A new user has been created to run the applications. The password is long, complex and is not known. It should not be needed.
adduser cb
usermod -aG docker cb
The firewall needs to be opened up.
ufw allow http
ufw allow https
Our Django application is packaged as a Docker image. It is deployed as a service using Docker Compose. It listens on port 8000 on the container network. This port is not exposed outside the container network as all inbound requests come from the web server. No volumes are mounted as all code and dependencies are contained within the image.
The table below outlines the environment variables that need to be set. Environment variables shows as **** are set through GitHub secrets.
Environment Variable | Value | Description |
---|---|---|
DATABASE_URL |
**** | database connection string |
EMAIL_HOST |
localhost |
email provider |
DJANGO_SETTINGS_MODULE |
config.settings.production |
which Django settings to use |
DJANGO_SECRET_KEY |
**** | the Django secret key |
DJANGO_ADMIN_URL |
admin |
the Django admin URL |
`DJANGO_ALLOWED_HOSTS | **** | the Django allowed hosts |
`DJANGO_SECURE_SSL_REDIRECT | True |
force redirect to SSL |
A reverse proxy sits in front of the Django application. We are using Traefik. It is deployed as a service using Docker Compose and exposes port 80 and 443 on the host network. It listens to Docker for new services being deployed (app_staging
and app_prod
) and sets up inbound routes appropriately. It also handles the provision and renewal of LetsEncrypt certificates.
The reverse proxy needs to be deployed manually. Ensure the DO_AUTH_TOKEN
environment variable is set and run the following command as the cb
user.
docker-compose -f docker-compose-proxy.yaml up -d
You should now be good to trigger GitHub Actions.
Domains and DNS are handled by Digital Ocean. Records were created as shown below. The IP address used is the address of the droplet hosting the Django application.
- api.codebuddies.org
- api-staging.codebuddies.org
doctl --context=cb compute domain records create codebuddies.org --record-name=api --record-data=165.227.21.195 --record-type=A
doctl --context=cb compute domain records create codebuddies.org --record-name=api-staging --record-data=165.227.21.195 --record-type=A
We are using a managed instance of PostgreSQL. We have created the following database type.
- Memory: 1 GB RAM
- Compute: 1vCPU
- Disk: 10 GB
- Failover: Primary only
- Region: SFO2
- DB: PostgreSQL 11
- Staging - latest PR
- Production - latest release
- Test - execute tests - triggered on all PRs
- Stage - build and tag container image, push to staging - triggered on merge to master
- Deploy - deploy existing container image to production - triggered on release
A number of GitHub Secrets have been defined to allow the GitHub Actions Workflows to inject credentials where necessary. These are documented below, but secrets have been masked for obvious reasons.
Environment Variable | Value | Description |
---|---|---|
DO_AUTH_TOKEN |
**** | DigitalOcean access token for DNS updates |
DO_SSH_KEY |
**** | DigitalOcean SSH key for copying files |
DO_SSH_USER |
cb | DigitalOcean system user |
DO_SSH_PASSPHRASE |
**** | Pass-phrase for SSH key |
DO_PRODUCTION_HOST |
api.codebuddies.org | DigitalOcean production droplet name |
DO_PRODUCTION_SSH_PORT |
22 | SSH port for production droplet |
DO_PRODUCTION_DB_URL |
**** | Database connection string for production |
PRODUCTION_ALLOWED_HOSTS |
api.codebuddies.org | Django allowed hosts for production |
PRODUCTION_DJANGO_SECRET_KEY |
**** | Django secret key for production |
DO_STAGING_HOST |
api-staging.codebuddies.org | DigitalOcean staging droplet name |
DO_STAGING_SSH_PORT |
22 | SSH port for staging droplet |
DO_STAGING_DB_URL |
**** | Database connection string for staging |
STAGING_ALLOWED_HOSTS |
api-staging.codebuddies.org | Django allowed hosts for staging |
STAGING_DJANGO_SECRET_KEY |
**** | Django secret key for staging |