コンテンツにスキップ

【Django × Docker】本番環境デプロイ手順

Djangoで作成したWebアプリケーションをDockerコンテナ上で動作させ、GunicornとNginxを使ってWebアプリケーションをデプロイする方法について解説します。本番環境でのSSL化(Let's Encrypt)とGitHub Actionsを使用した自動デプロイも含めています。

流れとしては、まずはVPS上でデプロイと動作確認を行い、その後GitHub Actionsを使用して自動デプロイ設定を行います。

ディレクトリ構成

以下のディレクトリ構成を想定して説明します。

uml diagram

準備

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
1
2
3
4
5
#!/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
1
2
3
4
5
#!/bin/bash

# ufwのインストール
sudo apt-get update -y
sudo apt-get install -y ufw

次に、ufwの設定を行います。

bash
1
2
3
4
5
6
7
8
#!/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
1
2
3
4
5
#!/bin/bash

# certbotのインストール
sudo apt-get update -y
sudo apt-get install -y certbot python3-certbot-nginx

証明書の取得

Let's EncryptでSSL証明書を取得します。

bash
1
2
3
4
#!/bin/bash

# 証明書の取得
sudo certbot --nginx -d <ドメイン>
複数ドメインの場合

複数のドメインを設定する場合は、以下のように設定します。

bash
1
2
# 複数ドメインの証明書の取得
sudo certbot --nginx -d <ドメイン1> -d <ドメイン2>

リポジトリのクローン

GitHubリポジトリをクローンします。

リポジトリ内の各ファイルの内容については後述します。

bash
1
2
3
4
5
#!/bin/bash

# リポジトリのクローン
git clone https://<USERNAME>:<TOKEN>@github.com/<USERNAME>/<REPOSITORY>.git
cd refrain

.envファイルの設定

.envファイルを作成し、環境変数を設定します。 設定項目については、各自の環境に合わせて設定してください。

.env
1
2
3
4
5
6
7
8
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
1
2
3
4
#!/bin/bash

# Dockerコンテナのビルド
docker-compose up --build -d

デプロイの確認

デプロイが正常に行われているか確認します。

bash
1
2
3
4
#!/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
1
2
3
4
5
#!/bin/bash

# タグのpush
git tag v1.0.0
git push origin v1.0.0

GitHub Actionsのページにアクセスし、デプロイが正常に行われているか確認します。

コメント