【Django × Docker】本番環境デプロイ手順
Djangoで作成したWebアプリケーションをDockerコンテナ上で動作させ、GunicornとNginxを使ってWebアプリケーションをデプロイする方法について解説します。本番環境でのSSL化(Let's Encrypt)とGitHub Actionsを使用した自動デプロイも含めています。
流れとしては、まずはVPS上でデプロイと動作確認を行い、その後GitHub Actionsを使用して自動デプロイ設定を行います。
ディレクトリ構成
以下のディレクトリ構成を想定して説明します。

準備
githubにシークレットを登録
GitHub Actionsで使用するシークレット
GitHub Actionsからデプロイ先にSSH接続し、デプロイ用のスクリプトを実行するために、以下のシークレットを登録します。
SSH_PRIVATE_KEY
: SSH秘密鍵
SSH_USERNAME
: SSHユーザ名
SSH_HOST
: SSHホスト名
SSH_PORT
: SSHポート番号
ENV
: 環境変数
ACCESS_TOKEN
: GitHub Personal Access Token
USERNAME
: GitHubユーザ名
GitHub Actionsでのシークレットの登録方法
GitHubリポジトリのSettings > Secretsにて、シークレットを登録します。
ACCESS_TOKEN
の作成と登録は必須ではありませんが、筆者の環境では使用しているため、本手順では登録しています。
各インフラ関連ファイルの作成
以下のファイルを作成します。
Dockerfile |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | # Dockerfile
FROM python:3.11-slim
RUN mkdir /code
WORKDIR /code
COPY requirements.txt .
RUN python3 -m venv /.venv && \
. /.venv/bin/activate && \
pip install --upgrade pip && \
pip install --no-cache-dir -r requirements.txt
COPY . .
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
|
entrypoint.sh |
---|
| #!/bin/sh
. /.venv/bin/activate
cd /code
python3 manage.py collectstatic --noinput
exec gunicorn --bind 0.0.0.0:8080 config.wsgi:application
|
docker-compose.yml |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 | version: '3'
services:
web:
build: .
volumes:
- .:/code
expose:
- "8080"
env_file:
- .env
depends_on:
- db
db:
image: postgres:15
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: mydatabase
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
nginx:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx:/etc/nginx/conf.d
- ./static:/code/static
- ./media:/code/media
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro # Nginx設定ファイルをマウント
- /etc/letsencrypt/live/refrainit.com/fullchain.pem:/etc/nginx/ssl/fullchain.pem:ro # 証明書ファイルを個別にマウント
- /etc/letsencrypt/live/refrainit.com/privkey.pem:/etc/nginx/ssl/privkey.pem:ro # 秘密鍵ファイルを個別にマウント
depends_on:
- web
volumes:
postgres_data:
|
nginx/default.conf |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 | server {
listen 443 ssl;
server_name refrainit.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'AESGCM:CHACHA20:AES:!aNULL:!MD5:!3DES';
location / {
proxy_pass http://web:8080; # アプリケーションコンテナへのプロキシ設定
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;
}
}
server {
listen 80;
server_name refrainit.com;
location / {
return 301 https://$host$request_uri;
}
}
|
VPS上の作業
VPSにDockerとDocker Composeをインストール
VPSにDockerとDocker Composeをインストールします。
手順はこちらを参考にしてください。
VPSのufw設定
VPSのufw設定を行います。まずは、ufwをインストールします。
bash |
---|
| #!/bin/bash
# ufwのインストール
sudo apt-get update -y
sudo apt-get install -y ufw
|
次に、ufwの設定を行います。
bash |
---|
| #!/bin/bash
# ufwの設定
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
|
インストール
VPSにcertbotをインストールします。
bash |
---|
| #!/bin/bash
# certbotのインストール
sudo apt-get update -y
sudo apt-get install -y certbot python3-certbot-nginx
|
証明書の取得
Let's EncryptでSSL証明書を取得します。
bash |
---|
| #!/bin/bash
# 証明書の取得
sudo certbot --nginx -d <ドメイン>
|
複数ドメインの場合
複数のドメインを設定する場合は、以下のように設定します。
bash |
---|
| # 複数ドメインの証明書の取得
sudo certbot --nginx -d <ドメイン1> -d <ドメイン2>
|
リポジトリのクローン
GitHubリポジトリをクローンします。
リポジトリ内の各ファイルの内容については後述します。
bash |
---|
| #!/bin/bash
# リポジトリのクローン
git clone https://<USERNAME>:<TOKEN>@github.com/<USERNAME>/<REPOSITORY>.git
cd refrain
|
.envファイルの設定
.env
ファイルを作成し、環境変数を設定します。
設定項目については、各自の環境に合わせて設定してください。
.env |
---|
| DEBUG=False
ALLOWED_HOSTS=<HOST>
SECRET_KEY=<SECRET_KEY>
DB_NAME=<DB_NAME>
DB_USER=<DB_USER>
DB_PASSWORD=<DB_PASSWORD>
DB_HOST=<DB_HOST>
DB_PORT=<DB_PORT>
|
docker-composeのビルド
Dockerコンテナをビルドします。
bash |
---|
| #!/bin/bash
# Dockerコンテナのビルド
docker-compose up --build -d
|
デプロイの確認
デプロイが正常に行われているか確認します。
bash |
---|
| #!/bin/bash
# デプロイの確認
docker ps -a
|
デプロイ先のURLにアクセスして、Webアプリケーションが正常に動作していることを確認します。
GitHub Actionsの設定
今後のデプロイを自動化するために、GitHub Actionsを設定します。
条件は、v*
タグがpushされたときに自動デプロイを行うように設定します。
GitHub Actionsの設定
GitHubリポジトリの.github/workflows
ディレクトリにdeploy.yml
ファイルを作成します。
.github/workflows/deploy.yml |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | name: Deploy to VPS Server
on:
push:
tags:
- 'v*'
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install SSH Key for Deploy
uses: appleboy/ssh-action@master
with:
key: ${{ secrets.SSH_PRIVATE_KEY }}
host: ${{secrets.SSH_HOST}}
username: ${{secrets.SSH_USERNAME}}
port: ${{secrets.SSH_PORT}}
script: |
cd ~
sudo rm -rf ~/refrain
git clone https://${{ secrets.USERNAME }}:${{ secrets.ACCESS_TOKEN }}@github.com/kkm-horikawa/refrain.git
cd refrain
echo "${{ secrets.ENV }}" > .env
docker-compose down
docker system prune -a --volumes -f
docker-compose up --build -d
|
デプロイの確認
GitHubリポジトリにタグをpushして、自動デプロイが正常に行われるか確認します。
bash |
---|
| #!/bin/bash
# タグのpush
git tag v1.0.0
git push origin v1.0.0
|
GitHub Actionsのページにアクセスし、デプロイが正常に行われているか確認します。