ちょっとしたサービスを作りたいと思い、勉強しながらConoHa VPS上でDocker環境を構築中です。
docker-composeを使って、「nginx+Django+postgreSQL」を立ち上げることができたので、備忘録としてその方法をまとめたいと思います。
環境は以下です。
- ConoHa VPS (メモリ 1GB/CPU 2Core/SSD 100GB)
- Ubuntu 18.04.4 LTS
- Docker: 19.03.8 (2020/3/22 執筆時点の最新)
- Docker Compose: 1.25.4 (2020/3/22 執筆時点の最新)
- nginx: latest (2020/3/22 執筆時点では、1.17.9が最新)
- Python: 3.8 (2020/3/22 執筆時点の最新)
- Django: 3.0.4 (2020/3/22 執筆時点の最新)
- psycopg: 2.8.4 (2020/3/22 執筆時点の最新)
- uWSGI: 2.0.18 (2020/3/22 執筆時点の最新)
- postgres: latest (2020/3/22 執筆時点では、12.2が最新)
目次
事前準備
事前に以下の準備が必要です。
- Docker、Docker ComposeをインストールしたLinuxサーバ
もし、まだ準備されていないようなら、以下に導入方法をまとめたので、よろしければご覧になってください。
※仮想専用サーバのConoHa VPS上での構築を想定していますが、Linuxであれば同じ手順を踏襲することができると思います。
docker-composeで「nginx+Django+postgreSQL」を立ち上げる
作業ディレクトリとしてホームディレクトリに「work」を作成し、以下のようなディレクトリ構成を作成していきます。
work
|-- db
| `-- dbdata
|-- django
| |-- Dockerfile
| `-- requirements.txt
|-- docker-compose.yml
|-- nginx
| |-- conf
| | `-- mysite_nginx.conf
| `-- uwsgi_params
`-- src
|-- manage.py
|-- mysite
| |-- __init__.py
| |-- asgi.py
| |-- settings.py
| |-- urls.py
| `-- wsgi.py
`-- static
ホスト側のサーバとコンテナ側の構成イメージは以下のような関係となります。
「docker-compose.yml」を作成する
以下のコマンドで「docker-compose.yml」を作成します。
このファイルはDocker Composeで立ち上げるコンテナの定義をしています。
$ vi ~/work/docker-compose.yml
【編集内容】
version: '3.5'
services:
nginx:
image: nginx:latest
container_name: nginx
volumes:
- ./nginx/conf:/etc/nginx/conf.d
- ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
- ./src/static:/static
ports:
- '80:80'
depends_on:
- django
django:
build: ./django
container_name: django
expose:
- '8001'
volumes:
- ./src:/code
command: uwsgi --socket :8001 --module mysite.wsgi
depends_on:
- db
db:
image: postgres:latest
container_name: db
volumes:
- ./db/dbdata:/var/lib/postgresql/data
expose:
- '5432'
environment:
- POSTGRES_USER=hogehoge
- POSTGRES_PASSWORD=password
- POSTGRES_DB=testDB
image: nginx:latest
、image: postgres:latest
でnginxとPostgreSQLの最新のイメージをDocker Hubから自動でダウンロードしてくれます。build: ./django
は./djangoにあるDockerfileからDockerイメージをビルドしてくれます。volumes:
でホスト側からコンテナ側へボリュームをマウントすることができます。(ホスト側とコンテナ側で共有ディレクトリを作るイメージ) 後で作成するnginxコンフィグなどをマウントしています。django:
の- ./src:/code
とnginx:
の- ./src/static:/static
でdjango:
の/codeとnginx:
の/staticをホスト側の./srcを介してつなげています。これにより、static関連のファイルをDjangoにアクセスせず、nginxから取得できるようにしています。ports:
でホスト側のポートとコンテナ側のポートをつなげることができます。nginxは- "80:80"
とすることで、HTTPの80番ポートをつなげています。expose:
はコンテナ側でのみ公開するポートを指定できます。django:
とdb:
はホスト側からの接続はしないため、expose:
でコンテナ側のみ公開するポートを指定します。environment:
で環境変数を指定できます。db:
にはDB接続するためのユーザ名やパスワード、DB名を指定しています。depends_on:
は依存関係を定義することができます。docker-containerコマンドを実施したときに、依存関係のコンテナが出来上がるのを待って、自コンテナの立ち上げをすることができます。
「django/Dockerfile」を作成する
以下のコマンドで「django/Dockerfile」を作成します。
このファイルはdjangoコンテナのイメージを定義するファイルになります。
$ mkdir -p ~/work/django/
$ vi ~/work/django/Dockerfile
【編集内容】
FROM python:3.8
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/
FROM python:3.8
でpythonのバージョン3.8のDockerイメージをDocker Hubからダウンロードします。RUN pip install -r requirements.txt
で「requirements.txt」で定義されたライブラリをインストールする。※「requirements.txt」は下記で作成する。
「django/requirements.txt」を作成する
以下のコマンドで「django/requirements.txt」を作成します。
このファイルはdjangoコンテナのイメージにインストールするライブラリを定義するファイルになります。
$ vi ~/work/django/requirements.txt
【編集内容】
Django==3.0.4
psycopg2==2.8.4
uwsgi==2.0.18
「nginx/conf/mysite_nginx.conf」を作成する
以下のコマンドで「nginx/conf/mysite_nginx.conf」を作成します。
このファイルはnginxのコンフィグファイルになります。
$ mkdir -p ~/work/nginx/conf/
$ vi ~/work/nginx/conf/mysite_nginx.conf
【編集内容】
upstream django {
ip_hash;
server django:8001;
}
server {
listen 80;
server_name dockerhost;
charset utf-8;
client_max_body_size 75M;
location /static {
alias /static;
}
location / {
uwsgi_pass django;
include /etc/nginx/uwsgi_params;
}
}
- 「docker-compose.yml」でコンテナ側の公開ポートは80番と設定したので、nginxの監視ポートとして、80番ポートを設定します。
server_name
にはホスト側のIPアドレスを設定する必要があるのですが、dockerhost
という変数がホスト側のIPアドレスを格納しているので、それを使用します。location /static
でnginxにstaticファイルのアクセスがあったら、/staticを返すようにしています。これで、staticファイルはDjangoまでアクセスしないようにしています。location /
で80番ポートへアクセスあったら、uwisgiを介してdjango:8001
へ通信が引き継がれます。ここら辺の書き方は、Djangoにuwisgiを使ってアクセスするときの一般的な書き方です。(自分もあまり詳しくないです。。。)
「nginx/uwsgi_params」を作成する
以下のコマンドで「nginx/uwsgi_params」を作成します。
このファイルはuwsgiサーバで使用するパラメータを定義するファイルになります。
$ vi ~/work/nginx/uwsgi_params
【編集内容】
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
その他で使用するディレクトリを作成する
あとは、以下のコマンドで、DBマウント用の「~/work/db/dbdata」、Djangoのプロジェクトファイル格納用の「~/work/src」ディレクトリを作成します。
$ mkdir -p ~/work/db/dbdata
$ mkdir -p ~/work/src
- 「~/work/db/dbdata」配下のファイルはPosreSQLのコンテナ生成時に自動でできあがります。ただし、コンテナ側で実行する権限がroot権限のため、dbdata配下はroot権限となってしまうことに注意です。
- 「~/work/src」配下のファイルは、コマンドを入力することで Djangoのプロジェクトファイルを作成します。やり方は後述します。
Djangoのプロジェクトを作成する(/src配下のファイルを作成する)
/src配下にはDjangoのプロジェクトファイルが入るので、ここではその設定を行います。
Djangoのプロジェクトファイルを作成するには、Djangoの環境が構築されたサーバ上で「django-admin startproject
」というコマンドを実行する必要があります。
そのため、上で定義したdjangoコンテナを一度立ち上げて、djangoコンテナ上でDjangoプロジェクトを作成する「django-admin startproject
」というコマンドを実行する。
djangoコンテナ上でコマンドを打つのは、以下のようなコマンドをホスト側で実行すればOK
$ cd ~/work/
$ docker-compose run django django-admin startproject mysite .
docker-compose run django
で、djangoコンテナを立ち上げています。- その後、
django-admin startproject mysite .
がdjangoコンテナ 上で実行されるコマンドです。
【実行結果】
これを実行後、/srcディレクトリを確認すれば、Djangoのプロジェクトファイルが出来上がっているはずです。
`-- src
|-- manage.py
`-- mysite
|-- __init__.py
|-- asgi.py
|-- settings.py
|-- urls.py
`-- wsgi.py
Djangoのプロジェクトファイルを編集する
Djangoのデフォルトの設定では、外部からのアクセスが禁止されているので、外部からのアクセスを有効にします。また、DjangoからDBにアクセスできるように、DBの設定やstaticファイルをnginxからアクセスできるように、 staticファイルをsrc/staticに統合する設定を行います。
以下のコマンドで、「~/work/src/mysite/settings.py」を変更します。
$ sudo vi ~/work/src/mysite/settings.py
【変更点】
ALLOWED_HOSTS = ["*"]
# ~~~~
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'testDB',
'USER': 'hogehoge',
'PASSWORD': 'password',
'HOST': 'db',
'PORT': 5432,
}
}
# ~~~~
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
また、以下のコマンドで、staticファイルを/src/staticに集約させます。
$ docker-compose run django ./manage.py collectstatic
コンテナを起動させる
これで、設定は終了です。
最後に、Docker Composeを実行して、コンテナを起動させます。
$ cd ~/work
$ docker-compose up
【実行結果】
以下のように表示されればOK
Starting db ... done
Starting django ... done
Starting nginx ... done
Djangoにアクセスしてみる
ブラウザから、「http://サーバのIPアドレス」にアクセスしてみてください。
ドメインを設定しているなら、「http://ドメイン名」でもアクセスできるはずです。
以下のように、ロケットが表示されればうまくDjangoが起動しています。
関連情報
本記事では、「nginx+Django+postgreSQL」の構成を構築する手順を記載しましたが、この方法ではhttpsアクセスの対応ができていません。https対応を自作するのもありですが、「https-portal」という自動で証明書の更新をしてくれる便利なコンテナがあります。「https-portal」を踏まえたうえで上記構成を見直したものを以下の記事でまとめました。よろしければご覧になってください。
その他、ConoHa上でDockerを導入したり、Webアプリを立ち上げたりした内容を以下の記事でまとめました。こちらもよろしければご覧になってください。
参考
- Quickstart: Compose and Django(公式ドキュメント)
- docker-compose + Django + postgreSQL + nginxで開発環境を構築 | It's interesting.
広告
Dockerをやるなら以下の書籍がオススメです。
Dockerとは何か?から複数のコンテナを管理することができるDocker Compose、Kubernetesまでまとめられています。
ConoHa VPS
は初期費用不要で月に数百円で利用できる仮想サーバのサービスです。以下のような方には非常にオススメのサービスとなっています!
- 勉強がてらLinuxの環境をちょっと触ってみたい
⇒管理者権限が実行可能なLinuxサーバ環境が構築可能です! - スモールスタートでサービスを提供して、うまくいったら規模をスケールアップしたい
⇒後からメモリサイズやCPU数などのスケールアップ/スケールダウン可能です! - AWSやGCPなどのクラウドサービスは高いので、もっと安くサーバ構築したい
⇒初期費用なし、月数百円(1時間単位も可)で利用可能です!
以上!
コメント