Digital Ocean
This guide can also help you deploy projects on other VPS like Linode, AWS EC2
Introduction
This deployment method is inspired by Cookiecutter Django
I optimized it for some people who are new to Docker and Docker Compose
Prerequisite
The VPS should have Docker and Docker compose installed, Docker pre-installed
- Please config DNS record to point to the IP of the VPS.
- Please replace
domaie nameandemailname in compose/production/traefik/traefik.yml to match your Domain and your email.
Setup App
SSH to the VPS
# clone the code in /app
(server)$ git clone {GIT_REPO_SSH_URL} /app
# this directory contains DB data
(server)$ mkdir /app/postgres_data && chmod 777 /app/postgres_data
# this directory contains DB backup files
(server)$ mkdir /app/postgres_backup && chmod 777 /app/postgres_backup
# this directory contains media files
(server)$ mkdir /app/media && chmod 777 /app/media
ENV variable
Create .env.production at /app directory
You can check Sample env file for Production
Build
(server)$ cd /app
# wait for some mins
(server)$ docker compose -f production.yml build
(server)$ docker compose -f production.yml up
If you are using old version of Docker Compose, please use docker-compose instead of docker compose
If no error raised, you should be able to visit https://example.com/
Press Ctrl+c to stop the running containers.
# check again
(server)$ docker compose -f production.yml ps
Rather than manually running the containers, let's let Supervisor handle this for us.
Process Manager
Start by installing Supervisor:
(server)$ apt-get update
(server)$ apt-get install -y supervisor
Next, add the following config to /etc/supervisor/conf.d/django_project.conf:
[program:django_project]
directory=/app/
command=docker compose -f production.yml up
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/supervisor/%(program_name)s_stdout.log
stdout_logfile_maxbytes=5MB
stdout_logfile_backups=5
stopwaitsecs=15
stopasgroup=true
Restart:
(server)$ supervisorctl
supervisor> reload
Really restart the remote supervisord process y/N? y
Restarted supervisord
supervisor> status
django_project STARTING
Now the containers should automatically run on boot. We can also restart the containers via the supervisorctl restart django_project command.
Useful Commands
# To create a superuser
$ docker compose -f production.yml run --rm django python manage.py createsuperuser
# Enter shell
$ docker compose -f production.yml run --rm django python manage.py shell
Auto Deploy in CI
SaaS Hammer already supports this feature and you can check .github/workflows/deploy.yml
Let's create SSH key pair which are used only for deployment.
$ ssh-keygen -t rsa -b 4096 -C "deploy@saashammer.com"
# you will get files
id_rsa id_rsa.pub
Add the id_rsa.pub to user on the server
cat ~/.ssh/id_rsa.pub | ssh USER@HOST "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Add the id_rsa.pub as Deploy key on Github
https://docs.github.com/en/developers/overview/managing-deploy-keys
Config id_rsa as ssh KEY in Github action secrets.
So in Github action, SSH will use the private ssh key id_rsa to login VPS, and then keep using it to pull code.
You should also add HOST, PORT, UERNAME to make the SSH login work. It is recommended to check .github/workflows/deploy.yml to know more details.
And then build image and restart the app via supervisorctl