0. 初めに

Dockerを利用しPython、Django、PostgreSQL、Gunicorn、Nginxの開発・本番環境の構築します。

Dockerとはコンテナ型の仮想環境を作成・配布・実行できるプラットフォームとのことです。Dockerを使えばWebアプリケーションだけでなくサーバーの設定などのインフラもまとめて管理できて、かつバージョンやOSの差を気にすること無く環境の構築ができるというメリットがあります。

Pythonの仮想環境としばしば比較されることがありますが、Pythonの仮想環境はあくまでPythonの依存関係のみをカプセル化し、DockerはOS全体をカプセル化するという違いがあります。

※参考サイト1

0-1. 開発環境
  • OS : Ubuntu 22.04.1 LTS on WSL2
  • Docker : 20.10.22
  • Docker Compose : v2.14.1
0-2. VPS環境
  • WebARENA Indigo : メモリ 4G, ストレージ:SSD 80GB, CPU:2コア
  • OS:Ubuntu 22.04
  • Docker : 20.10.22
  • Docker Compose : v2.14.1
  • VPS-IP : 160.248.11.107
  • Container : Debian GNU/Linux 11 (bullseye)
0-3. 共通環境
  • Python : 3.11.1
  • Django:4.1.4
  • Nginx:1.23.3
  • Gunicorn:20.1.0
  • PostgrSQL:14.0
  • psycopg2-binary:2.9.3
0-4. Python3.11
  1. Python 3.11はPython 3.10と比べて平均で 25%速くなりました。ワークロードにも寄りますが、10%から60%の速度向上が見込めます。これは「起動時の高速化」と「実行時の高速化」の二つによって達成されています。
    • 起動時の高速化:起動時間が10-15%高速化
    • 実行時の高速化:最大 2~20%の速度向上
  2. SSLモジュール
  3. Python 3.11の新機能Data Class Transforms
  4. Python3.11の新機能
0-5. Dockerの準備

Ubuntu22.04に最新版のDocker-CE(無償版)をインストールします。 Docker公式ドキュメント

  1. リポジトリへの追加処理に必要なツールのインストール

    sudo apt-get update
    sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
    
  2. Dockerの公式GPGキーを追加し、リポジトリへの追加を行いファイルを確認します。

    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
    
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    
    cat /etc/apt/sources.list.d/docker.list 
    
  3. 22.04 LTSのコードネームである「jammy」、「stable」で安定版ということも確認しておきます。 ここまで確認できたら、パッケージリストを更新し、「docker-ce」の情報を確認します。

    sudo apt-get update
    
    sudo apt info docker-ce -a
    
  4. Ubuntu 22.04への最新版Dockerのインストール後、バージョンを確認します。

    $ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
    
    (WSL Ubuntuの場合のみ)
    $ sudo service docker start
    
    $ sudo docker version
    Client: Docker Engine - Community
    Version:           20.10.22
    API version:       1.41
    Go version:        go1.18.9
    Git commit:        3a2c30b
    Built:             Thu Dec 15 22:28:04 2022
    OS/Arch:           linux/amd64
    Context:           default
    Experimental:      true
    
    Server: Docker Engine - Community
    Engine:
      Version:          20.10.22
      API version:      1.41 (minimum version 1.12)
      Go version:       go1.18.9
      Git commit:       42c8b31
      Built:            Thu Dec 15 22:25:49 2022
      OS/Arch:          linux/amd64
      Experimental:     false
    containerd:
      Version:          1.6.14
      GitCommit:        9ba4b250366a5ddde94bb7c9d1def331423aa323
    runc:
      Version:          1.1.4
      GitCommit:        v1.1.4-0-g5fd4c4d
    docker-init:
      Version:          0.19.0
      GitCommit:        de40ad0
    
    ※DockerがSeverへ接続できない場合の対処
    sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
    sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
    sudo cat /var/log/docker.logを確認
    
  5. Docker のリポジトリからCompose をインストール

    sudo apt install docker-compose-plugin
    
    docker compose version
    Docker Compose version v2.14.1
    

1. プロジェクトファイルの設定

1-1. Docker-Djangoプロジェクトの作成
  1. 以下のように「django_project」というプロジェクト全体を管理するディレクトリを作成します。
    ~/workspace/Docker-Django$ tree -L 2
    .
    └── django_project
    
1-2. 仮想環境の作成
  1. virtualenvのインストール

    [Pip3のインストール]
    
    sudo -H pip3 install --upgrade pip
    
    [virtualenvのインストール]
    python3.11で実行
    ※* 2            /usr/bin/python3.11   100       manual mode
    
    ~/workspace/Docker-Django$ sudo -H pip3 install virtualenv
    [Output]
    Collecting virtualenv
      Using cached virtualenv-20.17.1-py3-none-any.whl (8.8 MB)
    Collecting filelock<4,>=3.4.1
      Using cached filelock-3.9.0-py3-none-any.whl (9.7 kB)
    Collecting platformdirs<3,>=2.4
      Using cached platformdirs-2.6.2-py3-none-any.whl (14 kB)
    Collecting distlib<1,>=0.3.6
      Using cached distlib-0.3.6-py2.py3-none-any.whl (468 kB)
    Installing collected packages: distlib, platformdirs, filelock, virtualenv
    Successfully installed distlib-0.3.6 filelock-3.9.0 platformdirs-2.6.2 virtualenv-20.17.1
    WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
    
  2. virtualenvのファイル「venv」作成

    cd ~/workspace/Docker-Django/django_project
    
    $ virtualenv venv
    [Output]
    created virtual environment CPython3.11.1.final.0-64 in 483ms
      creator CPython3Posix(dest=/home/ubuntu/workspace/Docker-Django/django_project/venv, clear=False, no_vcs_ignore=False, global=False)
      seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/ubuntu/.local/share/virtualenv)
        added seed packages: pip==22.3.1, setuptools==65.6.3, wheel==0.38.4
      activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
    
  3. 仮想環境の有効化

    $ source venv/bin/activate
    (venv) xxx@xxx:~/workspace/Docker-Django/django_project$ ll
    
  4. 仮想化の無効化コマンド

    (venv)$ deactivate
    
1-3. Djangoプロジェクトの作成

仮想環境を有効化しpipコマンドでDjangoをインストールします

  1. 仮想環境を有効化

    (venv)$ pip3 install django==4.1.4
    [Output]
    Collecting django==4.1.4
      Using cached Django-4.1.4-py3-none-any.whl (8.1 MB)
    Collecting asgiref<4,>=3.5.2
      Using cached asgiref-3.6.0-py3-none-any.whl (23 kB)
    Collecting sqlparse>=0.2.2
      Using cached sqlparse-0.4.3-py3-none-any.whl (42 kB)
    Installing collected packages: sqlparse, asgiref, django
    Successfully installed asgiref-3.6.0 django-4.1.4 sqlparse-0.4.3
    
  2. Djangoのプロジェクトを作成

    (venv)$ django-admin startproject project .
    
    ~/workspace/Docker-Django/django_project$ tree -L 2
    .
    ├── manage.py
    ├── project
    │   ├── __init__.py
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── venv
    
  3. Djangoの起動

    (venv)$ python manage.py runserver
    [Output]
    Watching for file changes with StatReloader
    Performing system checks...
    
    System check identified no issues (0 silenced).
    
    You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
    Run 'python manage.py migrate' to apply them.
    January 03, 2023 - 04:54:41
    Django version 4.1.4, using settings 'project.settings'
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CONTROL-C.
    [03/Jan/2023 04:55:00] "GET / HTTP/1.1" 200 10681
    [03/Jan/2023 04:55:01] "GET /static/admin/css/fonts.css HTTP/1.1" 200 423
    [03/Jan/2023 04:55:01] "GET /static/admin/fonts/Roboto-Bold-webfont.woff HTTP/1.1" 200 86184
    [03/Jan/2023 04:55:01] "GET /static/admin/fonts/Roboto-Regular-webfont.woff HTTP/1.1" 200 85876
    [03/Jan/2023 04:55:01] "GET /static/admin/fonts/Roboto-Light-webfont.woff HTTP/1.1" 200 85692
    Not Found: /favicon.ico
    [03/Jan/2023 04:55:01] "GET /favicon.ico HTTP/1.1" 404 2111
    

2. ローカル環境DockerとDjangoの設定

2-1. Dockerファイルの作成
  • Dockerfile
    FROM python:3.11
    
    WORKDIR /usr/src/app
    
    ENV PYTHONDONTWRITEBYTECODE 1
    ENV PYTHONUNBUFFERED 1
    
    RUN pip install --upgrade pip
    COPY ./requirements.txt .
    RUN pip install -r requirements.txt
    
    COPY . .
    
2-2. requirements.txtファイルの作成
  • requirements.txt
    Django==4.1.4
    
2-3. ymlファイルの作成
  • docker-compose.yml
    version: '3.7'
    
    services:
      web:
        build: ./django_project
        command: python manage.py runserver 0.0.0.0:8000
        volumes:
          - ./django_project/:/usr/src/app/
        ports:
          - 8000:8000
        env_file:
          - ./.env.dev
    
2-4. 環境変数ファイルの作成
  1. .env.dev

    [Docker-Django/.env.dev]
    DEBUG=True
    SECRET_KEY='django-insecure-aqic3z!5eokrdoh8=j1@3tky7bem85qb0q=e9l#fa3s()ryv$h'
    ALLOWED_HOSTS=localhost 127.0.0.1 [::1] 160.248.11.107 [::1]
    

    ※SECRET_KEYの値は、LocalとVPSの各「settings.py」から転記します。

  2. ymlファイルのテスト

    [Docker-Django/docker-compose.yml]
    docker compose config
    
    (Output)
    name: django_project
    services:
      web:
        build:
          context: ./django_project
          dockerfile: Dockerfile
        command:
        - python
        - manage.py
        - runserver
        - 0.0.0.0:8000
        environment:
          ALLOWED_HOSTS: localhost 127.0.0.1 [::1]
          DEBUG: "True"
          SECRET_KEY: xxxxxxxxxxxxxxxxxxxx
        networks:
          default: null
        ports:
        - mode: ingress
          target: 8000
          published: "8000"
          protocol: tcp
        volumes:
        - type: bind
          source: /home/ubuntu/workspace/Docker-Django/django_project/django_project
          target: /usr/src/app
          bind:
            create_host_path: true
    networks:
      default:
        name: django_project_default
    
2-5. settings.pyファイルの作成
  • ~/workspace/Docker-Django/django_project/project/settings.pyの編集
    import os
    
    ...
    
    SECRET_KEY = os.environ.get("SECRET_KEY")
    
    DEBUG = os.environ.get("DEBUG")
    
    ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS").split(" ")
    
2-6. ローカル用コンテナのイメージ作成、コンテナ作成、起動
  1. イメージの作成

    $ sudo docker compose build
    
    [確認]
    $ sudo docker images
    REPOSITORY          TAG       IMAGE ID       CREATED          SIZE
    docker-django-web   latest    5c1b8984f6d8   24 seconds ago   1.01GB
    
  2. サービスを指定してビルドする場合は以下のコマンド(下記の場合はwebを指定)

    sudo docker compose build web
    
  3. ディレクトリ構造

    Docker-Django$ tree -aL 3
    .
    ├── .env.dev
    ├── README
    ├── django_project
    │   ├── Dockerfile
    │   ├── db.sqlite3
    │   ├── manage.py
    │   ├── project
    │   │   ├── __init__.py
    │   │   ├── __pycache__
    │   │   ├── asgi.py
    │   │   ├── settings.py
    │   │   ├── urls.py
    │   │   └── wsgi.py
    │   ├── requirements.txt
    │   └── venv
    │       ├── .gitignore
    │       ├── bin
    │       ├── lib
    │       └── pyvenv.cfg
    └── docker-compose.yml
    
  4. -dのオプションをつけて、コンテナのの作成後、バックグラウンドで起動

    $ sudo docker compose up -d
    (Opuput)
    [+] Running 2/2
    ⠿ Network docker-django_default  Created                                                                                                                   0.0s
    ⠿ Container docker-django-web-1  Started 
    
    (コンテナの確認)
    $ sudo docker ps
    CONTAINER ID   IMAGE               COMMAND                  CREATED          STATUS          PORTS                                       NAMES
    48abb0ddee8d   docker-django-web   "python manage.py ru…"   43 seconds ago   Up 42 seconds   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp   docker-django-web-1
    
  5. 表示確認

    1. LOCAL:localhost:8000

    2. VPS: 160.248.11.107:8000

    DisallowedHost at /
    Invalid HTTP_HOST header: '160.248.11.107:8000'. You may need to add '160.248.11.107' to ALLOWED_HOSTS.
    Request Method:	GET
    Request URL:	http://160.248.11.107:8000/
    Django Version:	4.1.4
    Exception Type:	DisallowedHost
    Exception Value:	
    Invalid HTTP_HOST header: '160.248.11.107:8000'. You may need to add '160.248.11.107' to ALLOWED_HOSTS.
    Exception Location:	/usr/local/lib/python3.11/site-packages/django/http/request.py, line 148, in get_host
    Python Executable:	/usr/local/bin/python
    Python Version:	3.11.1
    Python Path:	
    ['/usr/src/app',
    '/usr/local/lib/python311.zip',
    '/usr/local/lib/python3.11',
    '/usr/local/lib/python3.11/lib-dynload',
    '/usr/local/lib/python3.11/site-packages']
    Server time:	Mon, 02 Jan 2023 08:57:28 +0000
    
    1. 確認後コンテナの起動を停止、削除
    $ sudo docker compose down
    

3. Postgresqlの設定

3-1. docker-compose.ymlの編集
  • DockerHub:postgres15.1-alpine
    version: '3.7'
    
    services:
      web:
        build: ./django_project
        command: python manage.py runserver 0.0.0.0:8000
        volumes:
          - ./django_project/:/usr/src/app/
        ports:
          - 8000:8000
        env_file:
          - ./.env.dev
        depends_on:
          - db
      db:
        image: postgres:15.1-alpine
        volumes:
          - postgres_data:/var/lib/postgresql/data/
        env_file:
          - ./.env.dev
    
    volumes:
      postgres_data:
    
3-2. settings.pyファイルの編集
  • settings.pyのDATABASEの設定を変更
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': os.environ.get("SQL_DATABASE"),
            'USER': os.environ.get("SQL_USER"),
            'PASSWORD': os.environ.get("SQL_PASSWORD"),
            'HOST': os.environ.get("SQL_HOST"),
            'PORT': os.environ.get("SQL_PORT"),
        }
    }
    
3-3. 環境変数ファイルの編集
  • 環境変数のファイル(.env.dev)にデータベースの接続に必要な情報を追加
    DEBUG=True
    SECRET_KEY='django-insecure-aqic3z!5eokrdoh8=j1@3tky7bem85qb0q=e9l#fa3s()ryv$h'
    ALLOWED_HOSTS=localhost 127.0.0.1 [::1] 160.248.11.107 [::1]
    
    SQL_DATABASE=db_name
    SQL_USER=user_name
    SQL_PASSWORD=password
    SQL_HOST=db
    SQL_PORT=5432
    
    POSTGRES_USER=user_name
    POSTGRES_PASSWORD=password
    POSTGRES_DB=db_name
    
    ※HOSTはdocker-compose.ymlで指定したコンテナ名を設定する。
3-4. Dockerfileの編集
  • psycopg2の使用に合わせ、postgresqlの周辺ライブラリをインストールするよう編集します。
    FROM python:3.11
    
    WORKDIR /usr/src/app
    
    ENV PYTHONDONTWRITEBYTECODE 1
    ENV PYTHONUNBUFFERED 1
    
    # install psycopg2 dependencies
    RUN apt-get update 
        #&& apk add postgresql-dev gcc python3-dev musl-dev
    
    RUN pip install --upgrade pip
    COPY ./requirements.txt .
    RUN pip install -r requirements.txt
    
    COPY . .
    
    ※以下の内容は、エラーとなりますので上記のように変更
    # install psycopg2 dependencies
    RUN apk update \
    && apk add postgresql-dev gcc python3-dev musl-dev
    
3-5. requirements.txtファイルの作成
3-6. Postgresqlの動作確認
  • コンテナを起動して動作を確認

    sudo docker compose up -d --build
    [Output]
    [+] Building 14.3s (12/12) FINISHED                                                                                                                              
    => [internal] load build definition from Dockerfile                                                                                                        0.0s
    => => transferring dockerfile: 345B                                                                                                                        0.0s
    => [internal] load .dockerignore                                                                                                                           0.0s
    => => transferring context: 2B                                                                                                                             0.0s
    => [internal] load metadata for docker.io/library/python:3.11                                                                                              0.7s
    => [internal] load build context                                                                                                                           0.1s
    => => transferring context: 835.38kB                                                                                                                       0.1s
    => [1/7] FROM docker.io/library/python:3.11@sha256:250990a809a15bb6a3e307fec72dead200c882c940523fb1694baa78eb0e47c6                                        0.0s
    => CACHED [2/7] WORKDIR /usr/src/app                                                                                                                       0.0s
    => [3/7] RUN apt-get update                                                                                                                                2.3s
    => [4/7] RUN pip install --upgrade pip                                                                                                                     1.6s
    => [5/7] COPY ./requirements.txt .                                                                                                                         0.0s 
    => [6/7] RUN pip install -r requirements.txt                                                                                                               9.0s 
    => [7/7] COPY . .                                                                                                                                          0.4s 
    => exporting to image                                                                                                                                      0.3s 
    => => exporting layers                                                                                                                                     0.3s 
    => => writing image sha256:65a5170f390fb7d2558bf21341fcf1eecfa8e08293890f7266c8f1bfb0e42468                                                                0.0s 
    => => naming to docker.io/library/docker-django-web                                                                                                        0.0s 
    [+] Running 4/4                                                                                                                                                  
    ⠿ Network docker-django_default         Created                                                                                                            0.0s
    ⠿ Volume "docker-django_postgres_data"  Created                                                                                                            0.0s
    ⠿ Container docker-django-db-1          Started                                                                                                            0.4s
    ⠿ Container docker-django-web-1         Started   
    

    ※–build のオプションをつける事で、コンテナ作成前にイメージを再ビルドします。

  • コンテナの確認

    sudo docker ps
    [sudo] matsu のパスワード: 
    CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS          PORTS                                       NAMES
    3807ceadb077   docker-django-web      "python manage.py ru…"   26 minutes ago   Up 26 minutes   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp   docker-django-web-1
    2fe5656abd95   postgres:15.1-alpine   "docker-entrypoint.s…"   26 minutes ago   Up 26 minutes   5432/tcp                                    docker-django-db-1
    
  • データベースのマイグレーション

    sudo docker compose exec web python manage.py migrate --noinput
    [Output]
      Applying contenttypes.0001_initial... OK
      Applying auth.0001_initial... OK
      Applying admin.0001_initial... OK
      Applying admin.0002_logentry_remove_auto_add... OK
      Applying admin.0003_logentry_add_action_flag_choices... OK
      Applying contenttypes.0002_remove_content_type_name... OK
      Applying auth.0002_alter_permission_name_max_length... OK
      Applying auth.0003_alter_user_email_max_length... OK
      Applying auth.0004_alter_user_username_opts... OK
      Applying auth.0005_alter_user_last_login_null... OK
      Applying auth.0006_require_contenttypes_0002... OK
      Applying auth.0007_alter_validators_add_error_messages... OK
      Applying auth.0008_alter_user_username_max_length... OK
      Applying auth.0009_alter_user_last_name_max_length... OK
      Applying auth.0010_alter_group_name_max_length... OK
      Applying auth.0011_update_proxy_permissions... OK
      Applying auth.0012_alter_user_first_name_max_length... OK
      Applying sessions.0001_initial... OK
    
  • 以下のようなエラーが発生した場合、以下のコマンドを実行して、作成済みのコンテナとボリュームを削除しもう一度buildとmigrateを行います。

    django.db.utils.OperationalError: FATAL: database “db_name” does not exist

    docker compose down -v

  • データベースの確認

    sudo docker compose exec db psql --username=user_name --dbname=db_name
    [Output]
    psql (15.1)
    Type "help" for help.
    db_name=#
    
  • コマンド「# \l」を実行します。

    db_name=# \l
                                                      List of databases
      Name    |   Owner   | Encoding |  Collate   |   Ctype    | ICU Locale | Locale Provider |    Access privileges    
    -----------+-----------+----------+------------+------------+------------+-----------------+-------------------------
    db_name   | user_name | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | 
    postgres  | user_name | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | 
    template0 | user_name | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | =c/user_name           +
              |           |          |            |            |            |                 | user_name=CTc/user_name
    template1 | user_name | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | =c/user_name           +
              |           |          |            |            |            |                 | user_name=CTc/user_name
    (4 rows)
    
    db_name=# 
    
  • コンテナ作成時に作成されたボリュームデータを確認

    sudo docker volume inspect docker-django_postgres_data
    [Output]
    [
        {
            "CreatedAt": "2023-01-03T06:39:52+09:00",
            "Driver": "local",
            "Labels": {
                "com.docker.compose.project": "docker-django",
                "com.docker.compose.version": "2.14.1",
                "com.docker.compose.volume": "postgres_data"
            },
            "Mountpoint": "/var/lib/docker/volumes/docker-django_postgres_data/_data",
            "Name": "docker-django_postgres_data",
            "Options": null,
            "Scope": "local"
        }
    ]
    
3-7. シェルファイルの作成

コンテナを起動するためのコードを記入したシェルファイルを追加し、Dockerfileの内容も編集します。

  • entrypoint.shをdjango_projectディレクトリへ追加

  • [entrypoint.sh]

    #!/bin/sh
    
    if [ "$DATABASE" = "postgres" ]
    then
        echo "Waiting for postgres..."
    
        while ! nc -z $SQL_HOST $SQL_PORT; do
          sleep 0.1
        done
    
        echo "PostgreSQL started"
    fi
    
    exec "$@"
    
  • entrypoint.shの権限を変更

    $ chmod +x django_project/entrypoint.sh
    
  • 作成したシェルファイルの実行をDockerfileへ記入

  • コンテナのDebian GNU/Linux 11 (bullseye)には、nc2が入っていないのでインストールします。

  • [Dockerfile]

    FROM python:3.11
    
    WORKDIR /usr/src/app
    
    ENV PYTHONDONTWRITEBYTECODE 1
    ENV PYTHONUNBUFFERED 1
    
    # install psycopg2 dependencies
    RUN apt-get update 
    
    RUN pip install --upgrade pip
    COPY ./requirements.txt .
    RUN pip install -r requirements.txt
    
    # ncのインストール(コンテナのDebian GNU/Linux 11 (bullseye)に入っていない)
    RUN apt install -y ncat
    COPY ./entrypoint.sh .
    
    COPY . .
    
    ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
    
  • シェルファイルで使用する環境変数を、.env.devに追加

  • [.env.dev]

    DEBUG=True
    SECRET_KEY='django-insecure-aqic3z!5eokrdoh8=j1@3tky7bem85qb0q=e9l#fa3s()ryv$h'
    ALLOWED_HOSTS=localhost 127.0.0.1 [::1] 160.248.11.107 [::1]
    
    SQL_DATABASE=db_name
    SQL_USER=user_name
    SQL_PASSWORD=password
    SQL_HOST=db
    SQL_PORT=5432
    
    POSTGRES_USER=user_name
    POSTGRES_PASSWORD=password
    POSTGRES_DB=db_name
    
    DATABASE=postgres
    
  • Postgresqlをデータベースとして利用するため、デフォルトで作成されるSQLiteファイルを削除

    Docker-Django$
    .
    ├── .env.dev
    ├── django_project
    │   ├── Dockerfile
    │   ├── entrypoint.sh
    │   ├── manage.py
    │   ├── project
    │   │   ├── __init__.py
    │   │   ├── __pycache__
    │   │   ├── asgi.py
    │   │   ├── settings.py
    │   │   ├── urls.py
    │   │   └── wsgi.py
    │   ├── requirements.txt
    │   └── venv
    └── docker-compose.yml
    
  • イメージの再ビルド

    sudo docker compose build
    
  • コンテナの作成、起動

    sudo docker compose up -d
    
  • ブラウザで表示確認

    • Local : http://localhost:8000/
    • VPS : http://160.248.11.107:8000/

4. Gunicornの設定

本番環境ではGunicornをアプリケーションサーバーとして利用します。

4-1. requirements.txtの編集
  • requirements.txtを編集
    
    Django==4.1.4
    psycopg2-binary==2.9.3
    gunicorn==20.1.0
    
4-2. ymlファイルの編集

Gunicornを利用する設定にするため、ymlファイルを編集

  • [docker-compose.yml]

    version: '3.7'
    
    services:
      web:
        build: ./django_project
        # command: python manage.py runserver 0.0.0.0:8000
        command: gunicorn project.wsgi:application --bind 0.0.0.0:8000
        volumes:
          - ./django_project/:/usr/src/app/
        ports:
          - 8000:8000
        env_file:
          - ./.env.dev
        depends_on:
          - db
      db:
        image: postgres:15.1-alpine
        volumes:
          - postgres_data:/var/lib/postgresql/data/
        env_file:
          - ./.env.dev
    
    volumes:
      postgres_data:
    
  • Gunicornを起動させる設定で動作確認

  • まずは、現在起動している開発環境用のコンテナを停止、削除します。

    (sudo docker compose down -v)
    sudo docker compose down --rmi all --volumes
    (Output)
    [+] Running 6/6
    ⠿ Container docker-django-web-1       Removed                                                                                                              0.5s
    ⠿ Container docker-django-db-1        Removed                                                                                                              0.4s
    ⠿ Volume docker-django_postgres_data  Removed                                                                                                              0.0s
    ⠿ Image docker-django-web:latest      Removed                                                                                                              0.1s
    ⠿ Image postgres:15.1-alpine          Removed                                                                                                              0.1s
    ⠿ Network docker-django_default       Removed  
    

    ※-v : –volumes

  • ディレクトリ構造の確認

    Docker-Django$
    .
    ├── .env.dev
    ├── README
    ├── django_project
    │   ├── Dockerfile
    │   ├── entrypoint.sh
    │   ├── manage.py
    │   ├── project
    │   │   ├── __init__.py
    │   │   ├── __pycache__
    │   │   ├── asgi.py
    │   │   ├── settings.py
    │   │   ├── urls.py
    │   │   └── wsgi.py
    │   ├── requirements.txt
    │   └── venv
    └── docker-compose.yml
    
  • 本番環境用のymlファイルを指定してイメージの作成、コンテナの作成、起動を行います。

    sudo docker compose up -d --build
    [Output]
    ...
    [+] Running 4/4
    ⠿ Network docker-django_default         Created                                                                                                                             0.1s
    ⠿ Volume "docker-django_postgres_data"  Created                                                                                                                             0.0s
    ⠿ Container docker-django-db-1          Started                                                                                                                             0.8s
    ⠿ Container docker-django-web-1         Started   
    
  • (参考)ymlファイルを指定してイメージの作成、コンテナの作成、起動した際のログを確認する際は、ログ確認コマンド実行時にもymlファイルの指定を行います。

    sudo docker compose logs
    
  • 本番用のymlファイルを利用して起動すると、Djangoのrunserverの機能は使用しないため、Django内のstaticファイルは反映されなくなりますが、対策は後述します。

    • Local : http://localhost:8000/admin/
    • VPS : http://160.248.11.107:8000/admin/
4-3. Dockerファイルの編集
  • [Dockerfile]

    ## BUILDER ##
    
    FROM python:3.11 as builder
    
    WORKDIR /usr/src/app
    
    ENV PYTHONDONTWRITEBYTECODE 1
    ENV PYTHONUNBUFFERED 1
    
    # install psycopg2 dependencies
    RUN apt update \
        && apt install gcc musl-dev \
        && apt install python3-dev -y \
        && apt install musl-dev -y
        # postgresql-dev  gcc python3-dev musl-dev
    
    RUN pip install --upgrade pip
    COPY ./requirements.txt .
    RUN pip install -r requirements.txt
    
    RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt
    
    # ncのインストール(コンテナのDebian GNU/Linux 11 (bullseye)に入っていない)
    RUN apt install -y ncat
    COPY ./entrypoint.sh .
    
    COPY . .
    
    ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
    
    ## FINAL ##
    
    FROM python:3.11
    
    # 親ディレクトリも作成 -p
    #RUN mkdir -p /home/app
    
    # useraddはコマンド一発で作るタイプ : デフォルトではホームが作成されない
    # adduserは対話形式で作るタイプ : デフォルトでホームディレクトリを作成
    RUN addgroup -system app && adduser --system app && addgroup app app
    
    ENV HOME=/home/app
    ENV APP_HOME=/home/app/web
    RUN mkdir $APP_HOME
    WORKDIR $APP_HOME
    
    # RUN apt-get update && apt-get install libpq-dev
    # libpqがインストールできないのでlibpq-devを使っている。
    RUN apt update \
        && apt install libpq-dev
    COPY --from=builder /usr/src/app/wheels /wheels
    COPY --from=builder /usr/src/app/requirements.txt .
    RUN pip install --no-cache /wheels/*
    
    COPY ./entrypoint.sh $APP_HOME
    
    COPY . $APP_HOME
    
    RUN chown -R app:app $APP_HOME
    
    USER app
    
    ENTRYPOINT ["/home/app/web/entrypoint.sh"]
    
  • コンテナ内のディレクトリ構造

    [/home/app/web/]
    ~/web$
    -rw-rw-r-- 1 app app     1523 Jan  4 18:11 Dockerfile
    -rwxrwxr-x 1 app app      200 Jan  3 10:45 entrypoint.sh
    -rwxrwxr-x 1 app app      663 Jan  2 02:06 manage.py
    drwxrwxr-x 1 app app     4096 Jan  3 23:35 project
    -rw-rw-r-- 1 app app       53 Jan  3 15:13 requirements.txt
    drwxrwxr-x 1 app app     4096 Jan  3 23:35 venv
    
    [/var/lib/postgresql]
    /var/lib/postgresql#
    drwx------   19 postgres postgres      4096 Jan  5 03:23 data
    
  • コンテナ内のプロセス

    [app]
    ~/web$ ps -aux
    USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    app            1  0.1  0.0   2480   508 ?        Ss   03:23   0:01 /bin/sh /home/app/web/entrypoint.sh gunicorn project.wsgi:application --bind 0.0.0.0:8000
    [postgres]
    ~# ps -a
    PID   USER     TIME  COMMAND
        1 postgres  0:00 postgres
      50 postgres  0:00 postgres: checkpointer 
      51 postgres  0:00 postgres: background writer 
      53 postgres  0:00 postgres: walwriter 
      54 postgres  0:00 postgres: autovacuum launcher 
      55 postgres  0:00 postgres: logical replication launcher 
    
4-4. 本番環境用のymlファイルを利用したイメージ、コンテナの作成、起動
  • 使用していたコンテナの停止、削除、新コンテナの起動、新たな設定でデータベースのマイグレート

    sudo docker compose down --volumes
    
  • 新コンテナの起動

    sudo docker compose up -d --build
    
  • 新たな設定でデータベースのマイグレート

    sudo docker compose exec web python manage.py migrate --noinpu
    [Output]
    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, sessions
    Running migrations:
      Applying contenttypes.0001_initial... OK
      Applying auth.0001_initial... OK
      Applying admin.0001_initial... OK
      Applying admin.0002_logentry_remove_auto_add... OK
      Applying admin.0003_logentry_add_action_flag_choices... OK
      Applying contenttypes.0002_remove_content_type_name... OK
      Applying auth.0002_alter_permission_name_max_length... OK
      Applying auth.0003_alter_user_email_max_length... OK
      Applying auth.0004_alter_user_username_opts... OK
      Applying auth.0005_alter_user_last_login_null... OK
      Applying auth.0006_require_contenttypes_0002... OK
      Applying auth.0007_alter_validators_add_error_messages... OK
      Applying auth.0008_alter_user_username_max_length... OK
      Applying auth.0009_alter_user_last_name_max_length... OK
      Applying auth.0010_alter_group_name_max_length... OK
      Applying auth.0011_update_proxy_permissions... OK
      Applying auth.0012_alter_user_first_name_max_length... OK
      Applying sessions.0001_initial... OK
    
  • ブラウザで表示確認:どうしてか

    • ymlの確認:gunicornで起動している。
    web:
      build: ./django_project
      # command: python manage.py runserver 0.0.0.0:8000
      command: gunicorn project.wsgi:application --bind 0.0.0.0:8000
    
    • コンテナ内で起動
    sudo docker exec -it container_ID bash
    >>>コンテナ内
    app@c809940bc729:~/web$ source venv/bin/activate
    (venv) app@c809940bc729:~/web$ python manage.py runserver 0.0.0.0:8000
    Watching for file changes with StatReloader
    Performing system checks...
    
    System check identified no issues (0 silenced).
    January 04, 2023 - 15:16:45
    Django version 4.1.4, using settings 'project.settings'
    Starting development server at http://0.0.0.0:8000/
    Quit the server with CONTROL-C.
    
    [プロセスの確認]
      - プロセスの確認
      ~~~bash
      app@c809940bc729:~/web$ ps -aux
      USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
      app            1  0.1  0.0   2480   568 ?        Ss   14:46   0:02 /bin/sh /home/app/web/entrypoint.sh gunicorn project.wsgi:application 
      app        18135  0.0  0.1  58116 46768 pts/0    S+   15:16   0:00 python manage.py runserver 0.0.0.0:8000
      app        18139  0.3  0.1 430168 50932 pts/0    Sl+  15:16   0:01 /usr/local/bin/python manage.py runserver 0.0.0.0:8000
    
    • gunicornの起動
    sudo docker exec -it container_ID bash
    >>>コンテナ内
    app@08a393ac25a1:~/web$ gunicorn project.wsgi:application --bind 0.0.0.0:8000
    [2023-01-04 15:39:33 +0000] [2246] [INFO] Starting gunicorn 20.1.0
    [2023-01-04 15:39:33 +0000] [2246] [INFO] Listening at: http://0.0.0.0:8000 (2246)
    [2023-01-04 15:39:33 +0000] [2246] [INFO] Using worker: sync
    [2023-01-04 15:39:33 +0000] [2248] [INFO] Booting worker with pid: 2248
    
    [プロセスの確認]
    app@08a393ac25a1:~/web$ ps -aux
    USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    app            1  0.1  0.0   2480   572 ?        Ss   15:35   0:00 /bin/sh /home/app/web/entrypoint.sh gunicorn project.wsgi:application 
    app         2246  0.1  0.0  37404 31148 pts/0    S+   15:39   0:00 /usr/local/bin/python /usr/local/bin/gunicorn project.wsgi:application
    app         2248  0.0  0.1  65648 51604 pts/0    S+   15:39   0:00 /usr/local/bin/python /usr/local/bin/gunicorn project.wsgi:application
    
    • コンテナ内でgunicornが起動ができないので起動する
    app@08f41eff4b3a:~/web$  gunicorn project.wsgi:application --bind 0.0.0.0:8000
    [2023-01-05 03:37:49 +0000] [8594] [INFO] Starting gunicorn 20.1.0
    [2023-01-05 03:37:49 +0000] [8594] [INFO] Listening at: http://0.0.0.0:8000 (8594)
    [2023-01-05 03:37:49 +0000] [8594] [INFO] Using worker: sync
    [2023-01-05 03:37:49 +0000] [8597] [INFO] Booting worker with pid: 8597
    
    (結果)
      ~/web$ ps -aux
    USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    app            1  0.1  0.0   2480   508 ?        Ss   03:23   0:01 /bin/sh /home/app/web/entrypoint.sh gunicorn project.wsgi:application 
    app         8594  0.1  0.0  37404 30396 pts/0    S+   03:37   0:00 /usr/local/bin/python /usr/local/bin/gunicorn project.wsgi:application
    app         8597  0.1  0.1  65640 50556 pts/0    S+   03:37   0:00 /usr/local/bin/python /usr/local/bin/gunicorn project.wsgi:application
    
    • Local : http://localhost:8000/
    • VPS : http://160.248.11.107:8000/

5. Nginxの設定

Webサーバとして利用するNginxの設定

5-1. ymlファイルの編集

Nginx用のコンテナを設定するために、ymlファイルを編集

  • [docker-compose.yml]
    version: '3.7'
    
    services:
      web:
        build: ./django_project
        # command: python manage.py runserver 0.0.0.0:8000
        command: gunicorn project.wsgi:application --bind 0.0.0.0:8000
        #volumes:
        #  - ./django_project/:/usr/src/app/
        ports:
          - 8000:8000
        env_file:
          - ./.env.dev
        depends_on:
          - db
      db:
        image: postgres:15.1-alpine
        volumes:
          - postgres_data:/var/lib/postgresql/data/
        env_file:
          - ./.env.dev
      nginx:
        build: ./nginx
        ports:
            - 1317:80
        depends_on:
            - web  
    
    volumes:
      postgres_data:
    
5-2. Nginx用のフォルダの作成
  • Docker-Djangoディレクトリ内に、Nginx用のフォルダを作成し、その中にNginx用の「Dockerfile」、「nginx.conf」を作成します。

    $ mkdir nginx
    
  • Dockerfileの作成

    FROM nginx:1.23.3-alpine
    
    RUN rm /etc/nginx/conf.d/default.conf
    COPY nginx.conf /etc/nginx/conf.d
    
  • nginx.confの作成

  • [nginx.conf]

    upstream project {
        server web:8000;
    }
    
    server {
    
        listen 80;
    
        location / {
            proxy_pass http://project;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_redirect off;
        }
    
    }
    
5-3. ymlファイルの編集(Nginx仕様)
  • Nginxを使いますのでDjangoのrunserverコマンドは使用する8000番ポートの設定は不要です。
  • [webサービスの変更]
    version: '3.7'
    
    services:
      web:
        build:
          context: ./django_project
          dockerfile: Dockerfile.prod
        command: gunicorn project.wsgi:application --bind 0.0.0.0:8000
        expose:
          - 8000
        env_file:
          - ./.env.dev
        depends_on:
          - db
      db:
        image: postgres:15.1-alpine
        volumes:
          - postgres_data:/var/lib/postgresql/data/
        env_file:
          - ./.env.dev
      nginx:
        build: ./nginx
        ports:
            - 1317:80
        depends_on:
            - web  
    
    volumes:
      postgres_data:
    
5-4. 表示の確認
  • ディレクトリ構造

    ~/workspace/Docker-Django$ tree -aL 3
    .
    ├── .env.dev
    ├── django_project
    │   ├── Dockerfile
    │   ├── entrypoint.sh
    │   ├── manage.py
    │   ├── project
    │   │   ├── __init__.py
    │   │   ├── __pycache__
    │   │   ├── asgi.py
    │   │   ├── settings.py
    │   │   ├── urls.py
    │   │   └── wsgi.py
    │   ├── requirements.txt
    │   └── venv
    │       ├── .gitignore
    │       ├── bin
    │       ├── lib
    │       └── pyvenv.cfg
    ├── docker-compose.yml
    └── nginx
        ├── Dockerfile
        └── nginx.conf
    
  • コンテナの停止・削除

    sudo docker compose down --volumes
    
  • コンテナの起動

    sudo docker compose up -d --build
    
  • 新たな設定でデータベースのマイグレート

    sudo docker compose exec web python manage.py migrate --noinpu
    
  • ブラウザで表示を確認

    • Local : http://localhost:1317/
    • VPS : http://160.248.11.107:1317/

6. Nginxを利用したStatic,Mediaファイルの表示設定

これまでは、Gunicornををwebサーバとして利用していたため、Djangoプロジェクト内のstaticファイルが利用できていませんでした(adminページで表示が崩れます。)

6-1. Staticファイルの設定

webサーバにNginxを利用しますので、Staticファイルを扱う設定を加えます。

6-2. Settings.pyファイルの編集
  • STATIC_ROOT = os.path.join(BASE_DIR, “static”) を追加します。
    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR, "static")
    
6-3. ymlファイルの編集

staticファイル用のボリュームを作成し、ディレクトリを指定します。

  • wen、nginxへvolumesを2箇所追加します。
    version: '3.7'
    
    services:
      web:
        build: ./django_project
          #context: ./django_project
          #dockerfile: Dockerfile.prod
          #dockerfile: Dockerfile
        command: gunicorn project.wsgi:application --bind 0.0.0.0:8000
        volumes:
          - static_volume:/home/app/web/static
        expose:
          - 8000
        env_file:
          - ./.env.dev
        depends_on:
          - db
      db:
        image: postgres:15.1-alpine
        volumes:
          - postgres_data:/var/lib/postgresql/data/
        env_file:
          - ./.env.dev
      nginx:
        build: ./nginx
        volumes:
          - static_volume:/home/app/web/static
        ports:
            - 1317:80
        depends_on:
            - web  
    
    volumes:
      postgres_data:
      static_volume:
    
6-4. Dockerfileファイルの編集

ymlファイルのボリュームの設定に対応するために、Dockerfile内にディレクトリを作成するコードを追加します。

  • [Dockerfile.prod]
    ENV HOME=/home/app
    ENV APP_HOME=/home/app/web
    RUN mkdir $APP_HOME
    #追加
    RUN mkdir $APP_HOME/static
    WORKDIR $APP_HOME
    
6-5. nginx.confの編集

他のファイルで設定したstaticファイルの表示に対応するために、nginx.confを編集します。

  • [nginx.conf]
    upstream project {
        server web:8000;
    }
    
    server {
    
        listen 80;
    
        location / {
            proxy_pass http://project;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_redirect off;
        }
    
        location /static/ {
            alias /home/app/web/static/;
        }
    
    }
    
6-6. 表示の確認

設定を確認するために、表示を確認します。

  • 使用していたコンテナの停止、削除

    sudo docker compose down --volumes
    
  • 新コンテナの起動

    sudo docker compose up -d --build
    
  • 新たな設定でデータベースのマイグレート

    sudo docker compose exec web python manage.py migrate --noinpu
    
  • Djangoプロジェクト内のstatic関係のファイルを、nginxのstaticディレクトリへ移動するために、python manage.py collectstatic を行います。

    sudo docker compose exec web python manage.py collectstatic --no-input --clear
    [Output]
    130 static files copied to '/home/app/web/static'.
    
  • 表示 [Nginx]

    • Local : http://localhost:1317/
    • VPS:ポートを解放します。
    • VPS : http://160.248.11.107:1317/
  • 管理者画面の表示

    • Local : http://localhost:1317/admin/
    • VPS : http://160.248.11.107:1317/admin/
  • コンテナの/web/static/の構造

    app@ae0ce0954f55:~/web/static/admin$ ls -al
    drwxr-xr-x 3 app nogroup 4096 Jan  5 10:24 css
    drwxr-xr-x 2 app nogroup 4096 Jan  5 10:24 fonts
    drwxr-xr-x 3 app nogroup 4096 Jan  5 10:24 img
    drwxr-xr-x 4 app nogroup 4096 Jan  5 10:24 js
    
6-7. Mediaファイルの設定

Djangoでのstaticファイルとmediaファイルの使い分け

  • staticファイル:cssファイル、JSファイル、開発者がプロジェクトに追加した画像など

  • mediaファイル:webアプリの利用者が、対象のwebアプリ内で画像やファイルをアップロードして、表示する画像など

6-8. settings.pyの編集
  • staticファイル同様にmediaファイル用のurlとrootを指定します。
    ...
    
    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR, "static")
    
    MEDIA_URL = "/media/"
    MEDIA_ROOT = os.path.join(BASE_DIR, "media")
    
6-9. ymlファイルの編集
  • [docker-compose.yml]
    version: '3.7'
    
    services:
      web:
        build: ./django_project
          #dockerfile: Dockerfile.prod
        command: gunicorn project.wsgi:application --bind 0.0.0.0:8000
        volumes:
          - static_volume:/home/app/web/static
          - media_volume:/home/app/web/media
        expose:
          - 8000
        env_file:
          - ./.env.dev
        depends_on:
          - db
      db:
        image: postgres:15.1-alpine
        volumes:
          - postgres_data:/var/lib/postgresql/data/
        env_file:
          - ./.env.dev
      nginx:
        build: ./nginx
        volumes:
          - static_volume:/home/app/web/static
          - media_volume:/home/app/web/media
        ports:
            - 1317:80
        depends_on:
            - web  
    
    volumes:
      postgres_data:
      static_volume:
      media_volume:
    
6-10. Dockerファイルの編集
  • [Dockerfile]
    ENV HOME=/home/app
    ENV APP_HOME=/home/app/web
    RUN mkdir $APP_HOME
    #追加
    RUN mkdir $APP_HOME/static
    RUN mkdir $APP_HOME/media
    WORKDIR $APP_HOME
    
6-11. Nginxのconfigファイルの編集
  • [nginx.conf]
    upstream project {
        server web:8000;
    }
    
    server {
    
        listen 80;
    
        location / {
            proxy_pass http://project;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_redirect off;
        }
    
        location /static/ {
            alias /home/app/web/static/;
        }
    
        location /media/ {
            alias /home/app/web/media/;
        }
    }
    
6-12. コンテナを起動し表示確認
  • コンテナの停止、削除

    sudo docker compose down --volumes
    
  • コンテナの起動

    sudo docker compose up -d --build
    
  • 新たな設定でデータベースのマイグレート

    sudo docker compose exec web python manage.py migrate --noinpu
    
  • Djangoプロジェクト内のstatic関係のファイルを、nginxのstaticディレクトリへ移動。

    sudo docker compose exec web python manage.py collectstatic --no-input --clear
    
  • guncornの起動

    sudo docker compose exec web gunicorn project.wsgi:application --bind 0.0.0.0:8000
    
  • ブラウザで表示

    • Local : http://localhost:1317/
    • VPS : http://160.248.11.107:1317/

7. 独自ドメインの利用とHTTPS化

  • Let’s Encrypt によるコンテナ化された Django アプリケーションの保護
  • HTTPS Nginxプロキシの背後で実行されているコンテナ化されたDjangoアプリを、SSL証明書を暗号化して保護する方法。
  • Django アプリを Postgres、Nginx、Gunicorn と共にコンテナー化する方法を理解していることを前提とします。
7-1 settings.pyの編集
  • https化に備えCSRFのセキュリティー強化と、HTTPへリクエストがあった際に、HTTPSへリダイレクトするように以下のコードを追加します。
  • [settings.py]
    SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
    

8. Dockerfileを本番環境用、開発環境用

Dockerfileやdocker-compose.yamlを本番環境と開発環境で別のものを使用したいという状況があります。 同じ名称のファイルを作成することはできませんし、そもそもdocker compose buildのコマンドは何も指定しないが、自動的にDockerfileを元に buildの対象方法

  1. build するとき(Dockerfile からイメージを構築する)
  • Dockerfileを本番環境用、開発環境用にそれぞれ作成します。

    • 本番環境用 ・・・ Dockerfile.prod
    • 開発環境用 ・・・ Dockerfile.dev
  • ファイル名を指定してbuildします。

    // Dockerfile.prod を build するとき
    $ docker build -f Dockerfile.prod .
    
    // Dockerfile.dev を build するとき
    $ docker build -f Dockerfile.dev .
    
  1. コンテナの作成・起動・削除時
  • コンテナの作成・起動・削除時には、docker-compose up -dやdocker-compose downのコマンドの入力が必要です。このとき参照されるのは、docker-compose.yamlファイルになりますが、こちらでbuildの項目を指定している場合には注意が必要です。

  • docker-compose.yamlを本番環境用、開発環境用にそれぞれ作成します。

    • 本番環境用 ・・・ docker-compose-prod.yaml
    • 開発環境用 ・・・ docker-compose-dev.yaml
  • build の項目を記述します。

    • context ・・・ Dockerfileの所在

    • dockerfile ・・・ Dockerfileの名称 ※ ただのDockerfileという名称であれば省略可能

    • アプリのディレクトリ直下に存在するDockerfile.prodを指定する場合

    • [docker-compose-prod.yaml]

    version: '3'
    services:
      app:
        build:
          context: .
          dockerfile: "Dockerfile.prod"
          :
    
    • アプリのディレクトリ直下に存在するDockerfile.devを指定する場合
    • [docker-compose-dev.yaml]
    version: '3'
    services:
      app:
        build:
          context: .
          dockerfile: "Dockerfile.dev"
          :
    
    • コンテナの作成・起動を行います。
    # docker-compose-prod.yaml を指定する場合
    $ docker compose -f docker-compose-prod.yaml up -d 
    
    # docker-compose-dev.yaml を指定する場合
    $ docker compose -f docker-compose-dev.yaml up -d 
    
以上

  1. Testdriven.io ↩︎

  2. nc (または netcat) ユーティリティーは、TCP または UDP に関連付けられたさまざまなタスクに使用できます。nc は、TCP 接続を開き、UDP パケットを送信し、任意の TCP および UDP ポートで待機し、ポートスキャンを実行し、IPv4 と IPv6 の両方に対応します。telnet(1) とは異なり、nc は簡単にスクリプト化でき、エラーメッセージを標準出力に送信するのではなく標準エラーに分割します。 ↩︎