Python| Django + Gunicorn + Nginx + GCE #05.01

django005.01

GCPのインスタンスを使用してDjangoサイトを公開する。

WSGIサーバーをGunicornを利用して仮想的にDjangoを実行する。

静的コンテンツはNginxを使用する。

環境

環境version備考(コマンド)
Ubuntu18.04 LTS
Python3.6.9python -V
Django3.2.13django-admin –version
Postgres10.19psql –version
Nginx1.14.0nginx -V
Gunicorn20.1.0gunicorn -v

参考サイト

【Djangoの本番環境構築】Ubuntu20.04,Python3.8,Nginx,Gunicorn,PostgreSQL
本記事ではUbuntu20.04,Python3.7,Nginx,Gunicorn,PostgreSQLを利用して、Djangoプロジェクトの本番環境構築の方法について紹介しています。Ubuntuの環境初期設定、PostgreSQLの設定、Virtualenvの仮想環境の構築、Djangoプロジェクトのデプロイ、Gun...

GCE

もし無料枠を使用している場合は、プロジェクトを分けて作成してください。

同一のプロジェクトだと無料枠が外れる可能性があります。

プロジェクトを作成したら「APIを有効にする」。

ゾーンus-central1-a
マシンタイプf1-micro
ディスク標準の永続ディスク
ファイアウォールhttp, https

ファイアーウォール

参考サイト

GCE + Nginx + uWSGI + Django + Supervisor を使ってDjangoアプリをデプロイ - JUNのブログ
はじめに GCE とは Google Cloud Platform Compute Engine の略である。この記事ではWebアプリを公開するところまでを記述してある。 注意点として、この記事ではGCPのアカウント登録等については触れず、既にGCPのアカウントとクレジットカード登録による無料クレジットの獲得まで完了し...

インスタンスにターゲットタグを登録する

1. 左メニューのVPCネットワーク → ファイアーウォール → 新規ファイアーウォールルール作成
2. ターゲット : 指定されたターゲットタグ
3. ターゲットタグ :任意のタグ名
4. ソースIPの範囲 : 0.0.0.0/0で全IP指定
5. プロトコルとポート : tcp8000
6. vmインスタンスの編集からネットワークタグへ任意のタグ名を記載

rootパスワード変更

vmインスタンスから変更

> sudo passwd root

ユーザーグループ登録

参考サイト

Ubuntuユーザ追加とsudo権限付与。ユーザ/グループ操作まとめ | WWWクリエイターズ
UbuntuなどのLinux系OSで、ユーザの追加、ユーザの一覧、ユーザグループの確認、などユーザ関連の編集作業に関するコマンドの紹介です。 サーバーを飛び回る昨今のエンジニア。「あれ、いまユーザどうなってんだっけ?」という確認と編集作業は非常によく発生するかと思います。私は、なんかだかそのたびに毎回ググっている気もす...
> sudo gpasswd -a USER_NAME sudo
> sudo usermod -aG sudo USER_NAME

TeraTerm(ssh接続)

【Ubuntu】公開鍵認証によるSSH接続の設定(公開鍵・秘密鍵の作成)
公開鍵・秘密鍵を作成したことがありますか?公開鍵認証によるSSH接続の設定をやったことがありますか?実は、とても簡単です。この記事では、Ubuntu上で公開鍵と秘密鍵を作成して、それらをもとに公開鍵認証を可能にする方法を解説しています。
> sudo adduser codese
passwd 任意
> whoami
> ssh-keygen
> mv ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
> chmod 600 ~/.ssh/authorized_keys
> id_rsaの中身をコピー

TeraTermでIPを指定してid_rsa.pub(公開鍵)を指定してアクセスする。

設定

日本語パックのインストール

> sudo apt-get -y install language-pack-ja-base language-pack-ja ibus-mozc

日本語への設定

> sudo  localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
> sudo  localectl

Ubuntuアプリ更新

> sudo apt-get update

各種インストール

> sudo apt-get install python3-pip
> sudo apt-get install python3-dev
> sudo apt-get install libpq-dev
> sudo apt-get install postgresql
> sudo apt-get install postgresql-contrib
> sudo apt-get install nginx
> python3 -m venv venv
> source venv/bin/activate
> pip3 install wheel
> pip3 install django
> pip3 install gunicorn
> pip3 install psycopg2

postgresql

初期化

> sudo -u postgres psql
# CREATE DATABASE your_database;
# CREATE USER your_user_name WITH PASSWORD 'yourpassword';
# ALTER ROLE your_user_name SET client_encoding TO 'utf8';
# ALTER ROLE your_user_name SET timezone TO 'Asia/Tokyo';
# GRANT ALL PRIVILEGES ON DATABASE your_database TO your_user_name;
# \q

起動

> ps aux

クラスター情報

> pg_lsclusters

クラスター生成

sudo pg_createcluster 10 main --start
sudo /etc/init.d/postgresql start

pg_hba.conf編集

変更82[local   all             postgres                                md5]
変更87[local   all             all                                     md5]
追加97L[host    all             all             0.0.0.0/0               md5 #追加]
sudo vim /etc/postgresql/10/main/pg_hba.conf
# DO NOT DISABLE!
# If you change this first entry you will need to make sure that the
# database superuser can access the database using some other method.
# Noninteractive access to all databases is required during automatic
# maintenance (custom daily cronjobs, replication, and similar tasks).
#
# Database administrative login by Unix domain socket
# local   all             postgres                                peer
local   all             postgres                                md5

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
# local   all             all                                     peer
local   all             all                                     md5
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            md5
host    all             all             0.0.0.0/0               md5
host    replication     all             ::1/128                 md5

postgresql.conf編集

追加59L[listen_addresses = ‘*’]

sudo vim /etc/postgresql/10/main/postgresql.conf
#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------
# - Connection Settings -
#listen_addresses = 'localhost'         # what IP address(es) to listen on;
listen_addresses = '*'

再起動

> sudo service postgresql restart

Django

settings.py

ALLOWED_HOSTS = ['xxx.xxx.xxx.xxx'] # ここをIPが変わったら変える★★★

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'your_database',
        'USER': 'your_user_name',
        'PASSWORD': 'yourpassword',
        'HOST': '',
        'PORT': '',
    }
}

makemigration

> python manage.py makemigrations
> python manage.py migrate

8000番のポートへのアクセス

> sudo ufw allow 8000

起動

> python3 manage.py runserver 0.0.0.0:8000

http://XXX.XXX.XXX.XXX:8000/でロケットが出ればOK

settings.py内のセキュリティー

> pip3 install django-environ

ベースディレクトリ(manage.pyがあるディレクトリ)に.env ファイルを作成し以下のように環境変数で管理したい情報を記入します。setting.pyを書き換える。

SECRET_KEY=django-insecure-8-m&rybhmn76juc=)a@lrguz&(rmuzdmnji*+3mzyy&*$*i222
DB_NAME=your_database
DB_USER=your_user_name
DB_PASS=yourpassword

import environ

env = environ.Env()
env.read_env('.env')

SECRET_KEY = env('SECRET_KEY')
sudo vim /home/codese/project_name/settings.py
import environ

env = environ.Env()
env.read_env('.env')

SECRET_KEY = env('SECRET_KEY')

Gunicorn

manage.pyディレクトリで以下をたたく。プロジェクト名(project_name)を合わせる。

> gunicorn --bind 0.0.0.0:8000 project_name.wsgi
[2022-05-14 14:34:39 +0900] [13793] [INFO] Starting gunicorn 20.1.0
[2022-05-14 14:34:39 +0900] [13793] [INFO] Listening at: http://0.0.0.0:8000 (13793)
[2022-05-14 14:34:39 +0900] [13793] [INFO] Using worker: sync
[2022-05-14 14:34:39 +0900] [13796] [INFO] Booting worker with pid: 13796

「python3 manage.py runserver 0.0.0.0:8000」を実施しない状態で、IPへアクセスして画面が確認できること!

デーモン再起動(やり直す際はデーモンを再起動すること)

> sudo systemctl daemon-reload

gunicorn自動起動

設定

項目備考
Userユーザー名
Groupグループ名
WorkingDirectoryアプリディレクトリmanage.pyがある場所
ExecStartgunicorn格納パス
sudo vim /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=codese
Group=codese
WorkingDirectory=/home/codese/
ExecStart=/home/codese/venv/bin/gunicorn  \
        --access-logfile - \
        --workers 3 \
        --bind /home/codese/project_name/gunicorn.sock \
        project_name.wsgi:application

[Install]
WantedBy=multi-user.target
sudo vim /etc/systemd/system/gunicorn.socket
[Unit]
Description=gunicorn socket

[Socket]
# ListenStream=/run/gunicorn/gunicorn.sock
ListenStream=/home/codese/project_name/gunicorn.sock
# Our service won't need permissions for the socket, since it
# inherits the file descriptor by socket activation
# only the nginx daemon will need access to the socket
# User=codese
# Optionally restrict the socket permissions even more.
# Mode=600

[Install]
WantedBy=sockets.target

gunicorn操作

登録

> sudo systemctl enable gunicorn.service
> sudo systemctl enable gunicorn.socket

起動

> sudo systemctl start gunicorn

確認

> sudo systemctl status gunicorn
> sudo systemctl status gunicorn.socket

再起動

> sudo systemctl restart gunicorn

停止

sudo systemctl stop gunicorn
sudo systemctl stop gunicorn.socket

確認

curl --unix-socket /run/gunicorn/gunicorn.sock localhost

削除

sudo rm -f /etc/systemd/system/multi-user.target.wants/gunicorn.service

Nginx

sudo vim /etc/nginx/sites-available/project_name
server{
        listen 80;
        server_name XXX.XXX.XXX.XXX;
        location =/fabicon.ico {access_log off; log_not_found off;}
        location /static/{
                root /home/codese/project_name;
        }

        location /{
                include proxy_params;
                proxy_pass http://unix:/home/codese/project_name/gunicorn.sock;
        }
}

サイトのシンボリックリンクを作成

> sudo ln -s /etc/nginx/sites-available/project_name /etc/nginx/sites-enabled/

確認

> sudo nginx -t

8000ポート閉じる

> sudo ufw delete allow 8000

nginx開放

> sudo ufw allow 'Nginx Full'

nginxスタート

> sudo systemctl restart nginx

gunicorn再起動

> sudo systemctl restart gunicorn
タイトルとURLをコピーしました