CentOS8にDjango+Reactで作成したアプリをリリースしてみた
はじめに
Django+Reactで作成したアプリをリリースしてみたので、その道のりをまとめてみました。
Django公式を参考しています。
今回作ったアプリの詳細は記載していませんが、所々(モジュールのインストール等)でアプリ固有の手順が入っています。
仮想環境の作成
venvで今回デプロイするアプリ用の環境を用意します。
$ python3.6 -m venv mysite
仮想環境の有効化
$ source ~/mysite/bin/activate
または
$ . ~/mysite/bin/activate
モジュールのインストール
$ sudo dnf groupinstall 'development tools'
$ sudo dnf install python3-devel
今回のアプリに使用したモジュールをインストールします。
$ pip install Django
$ pip install django-cors-headers
$ pip install uwsgi
$ pip install tensorflow
$ pip install Keras
$ pip install numpy
$ pip install Pillow
プログラムの配置
– React関連のファイル:/home/user/mysite/src/client
– Djangoのファイル:/home/user/mysite/src/server
に置いてあるものとします。
以下のコマンドで
– React関連のファイル:/var/www/mysite
– Django関連のファイル:/usr/bin/mysite
にコピーします。
$ sudo mkdir -p /var/www/mysite
$ sudo cp -r /home/user/mysite/src/client/* /var/www/mysite
$ sudo mkdir -p /usr/bin/mysite
$ sudo cp -r /home/user/mysite/src/server/* /usr/bin/mysite
nginxの設定
インストール
$ sudo dnf -y install nginx
$ sudo systemctl enable --now nginx
設定
uwsgi_paramsをコピー
$ sudo cp /etc/nginx/uwsgi_params /usr/bin/mysite/
nginx.confの編集
$ cd /etc/nginx
$ sudo vi nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx; // 実行ユーザを変更したい場合は書き換えが必要
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*; // 追加
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name ababa.ddo.jp;
charset utf-8;
root /var/www/mysite;
index index.html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
try_files $uri /index.html;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers PROFILE=SYSTEM;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
mysite_nginx.confの編集
$ sudo mkdir /etc/nginx/sites-available
$ sudo mkdir /etc/nginx/sites-enabled
$ cd /etc/nginx/sites-available
$ sudo vi mysite_nginx.conf
# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
server unix:///usr/bin/mysite/webapi/webapi.sock; # for a file socket
# server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 8000;
# the domain name it will serve for
server_name localhost; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /usr/bin/mysite/webapi/media; # your Django project's media files - amend as required
}
location /static {
alias /usr/bin/mysite/webapi/static; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /usr/bin/mysite/uwsgi_params; # the uwsgi_params file you installed
}
}
権限付与
sudo chown -R nginx /var/lib/nginx
シンボリックリンクの設定
$ cp /etc/nginx/sites-available/mysite_nginx.conf /home/user/mysite
$ sudo ln -s /home/user/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/
静的ファイルのデプロイ
$ sudo cd /usr/bin/mysite/webapi/
$ sudo vi settings.py
以下を追記します。
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
staticフォルダとmediaフォルダを作成します。
$ sudo mkdir /usr/bin/mysite/webapi/static
$ sudo mkdir /usr/bin/mysite/webapi/media
$ python manage.py collectstatic
$ sudo systemctl restart nginx
Djangoアプリケーションを実行
$ cd /usr/bin/mysite
$ sudo vi mysite_uwsgi.ini
# mysite_uwsgi.ini file
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = /usr/bin/mysite/webapi
# Django's wsgi file
module = webapi.wsgi
# the virtualenv (full path)
home = /home/user/mysite
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 10
# the socket (use the full path to be safe
socket = /usr/bin/mysite/mysite.sock
# ... with appropriate permissions - may be needed
# chmod-socket = 664
# clear environment on exit
vacuum = true
uwsgi --ini mysite_uwsgi.ini --chmod-socket=666
システム全体にuWSGIをインストール
$ deactivate
$ sudo pip install uwsgi
emperorモードでの実行
$ sudo mkdir /etc/uwsgi
$ sudo mkdir /etc/uwsgi/vassals
# シンボリックリンクを作成
$ sudo ln -s /usr/bin/mysite/mysite_uwsgi.ini /etc/uwsgi/vassals/
# 実行
$ uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data
システムの起動時にuWSGIを起動
Djangoのページには「/etc/rc.local」を使用した自動起動の方法が紹介されていますが、現在は非推奨となっているためsystemdを使用しました。
以下の記事が詳しいです。
/etc/systemd/system/mysite.serviceの作成
$ cd /etc/systemd/system
$ sudo vi mysite.service
[Unit]
Description=mysiteのサービス
After=local-fs.target
ConditionPathExists=/opt/mysite/bin
[Service]
ExecStart=/opt/mysite/bin/startup.sh
Restart=no
Type=simple
[Install]
WantedBy=multi-user.target
$ sudo chown root:root mysite.service
$ sudo chmod 644 mysite.service
/opt/mysite/bin/startup.sh
$ sudo mkdir -p /opt/mysite/bin
$ sudo chmod 755 /opt/mysite/bin
$ cd /opt/mysite/bin
$ sudo vi startup.sh
#!/bin/bash
uwsgi --emperor /etc/uwsgi/vassals --uid my-user --gid my-user
$ sudo chown root:root /opt/mysite/bin/startup.sh
$ sudo chmod 755 /opt/mysite/bin/startup.sh
起動
$ sudo systemctl daemon-reload
$ sudo systemctl enable mysite.service
$ sudo systemctl start mysite.service
$ sudo systemctl status mysite.service
HTTPS化
$ sudo mkdir -p /opt/mysite/bin
$ cd /usr/local
$ git clone https://github.com/certbot/certbot
$ cd certbot
$ sudo mkdir -p /opt/mysite/bin
$ ./certbot-auto certonly --standalone -t
パッケージのインストールを聞かれるので、「y」。
メールアドレスを指定します。
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel): my-mail@example.com
ライセンスに同意します。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
メールアドレスを登録していいか聞かれているので、お好きなほうを選択します。
ここではNoを選択しました。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
登録したいドメインを入力します。
Please enter in your domain name(s) (comma and/or space separated) (Enter 'c'
to cancel): ababa.ddo.jp
以下のように表示されれば成功です。
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/ababa.ddo.jp/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/ababa.ddo.jp/privkey.pem
Your cert will expire on 2020-08-26. To obtain a new or tweaked
version of this certificate in the future, simply run certbot-auto
again. To non-interactively renew *all* of your certificates, run
"certbot-auto renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
以下のように表示された場合、nginxを停止してやり直しば成功するはずです。
Problem binding to port 80: Could not bind to IPv4 or IPv6.
nginxの設定ファイルを修正し、nginxを再起動します。
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name ababa.ddo.jp;
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/mysite;
}
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name ababa.ddo.jp;
ssl on;
ssl_certificate /etc/letsencrypt/live/ababa.ddo.jp/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ababa.ddo.jp/privkey.pem;
}
証明書の更新
$ sudo crontab -e
// 毎週月曜日に更新する
0 0 * * 1 /usr/local/certbot/certbot-auto renew && /bin/systemctl reload nginx
ディスカッション
コメント一覧
まだ、コメントがありません