Synology NASのDockerでもComposeが動くので、今回はSynology NASを活用したより実践的なWebアプリケーションサーバーを構築について解説します。Webフレームワークは様々な種類がありますが、今回はPythonで実装されたDjangoのWebアプリサーバーDjango3.0.x + MySQL + Nginxの開発環境をDockerコンテナ上で構築してみます。
目次
NASで本番環境に近いWebアプリサーバーを立てる
Djangoにはrunserverで起動できるWebサーバーが付属していますが、この開発サーバーをプロダクション環境で使用することは推奨されていません。むしろ絶対使うな、禁止と明記されています。1
開発・検証だけならDjango付属の開発用サーバーでも問題ありませんが、小規模開発の場合、インフラエンジニアはいるようでいないようなものなので、初めから本番環境に近いような開発環境を構築すれば、環境差異トラブルに見舞われることなくメリットも大きいくなるかなと考えました。
幸い、手持ちのSynology NASがDockerに対応していて、Dockerの本番環境も普及しつつあるとの話なので2、公式のドキュメントを参考にDocker環境でDjango3.0系のWebアプリサーバーの構築方法を解説します。
環境構成
今回使用する環境は以下の表のようになります。Synology NAS上で構成しているのが少し特殊ですが、Linux環境みたいなものなので他の環境でも大きな差はないと思います。
Djangoは2.2以降になるとマイグレ時にpymysqlを理由に拒否されてしまうので、新たな推奨ドライバのmysqlclientを使用します。
項目 | Version |
Synology DS916+ | DSM 6.2.2-24922 Update4 |
Docker | 18.09.8 |
Docker-Compose | 1.24.0 |
Python | 3.8.3 |
Django | 3.0.6 |
MySQL | 5.7 |
Nginx | 1.18 |
uWSGI | 2.0.17 |
mysqlclient | 1.4.6 |
ディレクトリ構成
3層アーキテクチャにするので、Python・Nginx・MySQLでディレクトリを分けます。今回はSynology NASで構築しているので、DSM上でパパっとディレクトリを作ってしまいます。
django
├── docker-compose.yml
├── mysql
├── sql
├── nginx
│ ├── conf
│ │ └── app_nginx.conf
│ └── uwsgi_params
└── python
├── Dockerfile
└── requirements.txt
Pythonの環境設定
Dockerfile
FROM python:3.8.3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code/
WORKDIR /code/
ADD requirements.txt /code
RUN pip install -r requirements.txt
ADD . /code
requirements.txt
Django==3.0.6
uwsgi==2.0.17
mysqlclient==1.4.6
django-bootstrap4==1.1.1
pytz==2019.3
soupsieve==1.9.5
sqlparse==0.3.0
asgiref==3.2.3
beautifulsoup4==4.8.2
Django2.2以降ではMySQLドライバーにmysqlclientを必要とします。Django2.1以前まで対応していたpymysqlを使おうとするとマイグレ時に
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.
エラーが表示されてDjangoプロジェクト作成が進まないので「mysqlclient==1.4.6」に変更します。mysqlclient以下にはDjangoアプリサーバーに必要なもの以外にもいろいろ入っていますが、用途に合わせてお好みで削除・追加してください。
Nginxの設定
app_nginx.conf
Nginxの設定ファイルを作成します。uwsgiの設定やポート設定・アップロードの容量制限などはここで定義します。
バージョンを非表示にするため.confのhttpディレクティブに server_tokens off; を追加します。その他にも、本番環境に使用する場合には本番用の.confを定義します。今回は開発用なので簡単に定義
upstream django {
ip_hash;
server python:8001;
}
server {
listen 8000;
server_name 127.0.0.1;
charset utf-8;
location /static {
alias /static;
}
location / {
uwsgi_pass django;
include /etc/nginx/uwsgi_params;
}
}
server_tokens off;
uwsgi-params
nginxのuWSGIモジュール用の設定ファイルです。
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;
MySQLの設定
sql/init.sql
djangoでtestを実行する際にDB作成を許可するため、以下を記述します。
GRANT ALL PRIVILEGES ON test_todoList.* TO 'user'@'%';
FLUSH PRIVILEGES;
docker-compose.yml
それぞれのコンフィグファイルが作成出来たらComposeファイルを作成してディレクトリのトップに入れておきます。
使用するポートを変更する場合はDocker composeのポート定義のほか、各コンテナのコンフィグファイルのポート設定も変更しなければならないので注意です。
Djangoプロジェクトの実行
# docker-compose run python django-admin.py startproject app .
プロジェクトを実行するといくつかのファイルとディレクトリが作成されて、下記のディレクトリ構成になります。
django
├── docker-compose.yml
├── mysql
├── sql
├── nginx
│ ├── conf
│ │ └── app_nginx.conf
│ └── uwsgi_params
├── python
│ ├── Dockerfile
│ └── requirements.txt
├── src
│ ├── app
│ │ ├── __init__.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ └── manage.py
└── static
MySQL 接続設定を追記
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'todoList',
'USER': 'user',
'PASSWORD': 'password',
'HOST': 'db',
'PORT': '3306',
}
}
ついでに日本語化とタイムゾーンの設定・デバッグモードの処理も書き加えておきます
settings.py
ALLOWED_HOSTS = ['サーバーのIPアドレス']
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
マイグレーションの実行
マイグレーションを実行します。この時、構成したディレクトリやファイルに不備があるとエラーが発生します。
docker-compose run python ./manage.py makemigrations
docker-compose run python ./manage.py migrate
管理者の設定
Djangoの管理画面にログインするためのユーザー設定を行います。メールアドレスやパスワードを入力します。
docker-compose run python ./manage.py createsuperuser
コンテナを起動
docker-compose up -d
ここで初めてNginxとPythonコンテナが起動します。正常に起動するのを確認できたら、マイグレ用に構成されたPythonコンテナは削除してOKです。
そのまま放置しても問題ありませんが、Synology Dockerの場合は大量に構成されるコンテナがGUI上の管理の邪魔になるので消してしまいます。
アクセスしてブラウザから動作を確認
http://ホストのIPアドレス:8000にアクセスして、下記の画面が表示されればOKです。
CSS適応
Django管理画面にログインするとCSSが適応されていないので、静的ファイルを読み込むようsettings.pyに定義します。
settings.py
STATIC_URL = '/static/'
STATIC_ROOT = '/static'
# docker-compose run python ./manage.py collectstatic
参考
- Quickstart: Compose and Django | Docker Documentation
- Docker-Composeで作るDjango開発環境(Django + MySQL + uWSGI + Nginx)
- Django+Nginx+MySQLの開発環境をDockerで構築する|Qiita