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 name
andemail
name 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