0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

uwsgi+nginx+postgresqlでDjangoの構築(AmazonLinux2)

Posted at

システム要件

OS : AmazonLinux2
python : 3.9.2
sqlite : 3.35.0
Django : 4.0.5
uWSGI : 2.0.20
nginx : 1.20.0
psycopg2-binary : 2.9.3
php : 8.0.18
postgresql : 14.1

ディレクトリ構成

完成後のディレクトリ構成は下記のようになっています。
実行階層が重要になってくるので確認しながら進めてください。
今回はec2-userのホームディレクトリに配置するように構築しています。
(一部省略しています。)

~/
└ uwsgi-tutorial/
    └ mysite
        ├ manage.py
        ├ media/
        ├ mysite/
        │    ├ asgi.py
        │    ├ __init__.py
        │    ├ __pycache__/
        │    ├ settings.py
        │    ├ urls.py
        │    └ wsgi.py
        ├ mysite_uwsgi.ini
        ├ static
        │    └ admin/
        └ test.py

Djangoだけで動かす方法

Djangoには簡単な機能が備わっているので、Django単体でブラウザ上で動かすことも可能です。単体で動かす場合は下記の記事を参照して、上からコマンドをコピペしていくだけで実現します。
venvでDjangoの環境を作成してみたった(Python3.3以降)

構築作業

基本的に公式ドキュメントに沿って進めていきます。
uWSGI公式ドキュメント
Django公式ドキュメント

python3.9.2のインストール

こちらの記事にまとめましたので、参照してください。
記事内のpyenvを使用した方法で進めています。
pythonのバージョン変更方法(aliasとpyenv)

sqliteをアップグレードする

AmazonLinux2ではデフォルトでsqlite3.7.17が入っています。
Djangoはsqlite3.9.0以上でないとエラーが出てしまうので、アップグレードしていきます。
本記事は最終的にはposgresqlを使用していくため、この工程は飛ばすことも可能です。
今回は公式ドキュメントに沿って進めるため、実行していきます。

$ wget https://www.sqlite.org/2021/sqlite-autoconf-3350000.tar.gz
$ tar fxvz sqlite-autoconf-3350000.tar.gz

$ cd sqlite-autoconf-3350000/
$ ./configure
$ make
$ sudo make install

$ sqlite3 --version
3.35.0 2021-03-12 15:10:09 acd63062eb06748bfe9e4886639e4f2b54ea6a496a83f10716abbaba4115500b

共有ライブラリにパスを通しておきます。

vi ~/.bashrc
.bashrc
#一番下に追記する
export LD_LIBRARY_PATH="/usr/local/lib"
$ source ~/.bashrc

pythonとsqlilteのバージョンを変更したら、Djangoの構築に入っていきます。

uWSGIでDjangoを動かす

venvを使って仮想環境でDjangoとuWSGIをインストールしていきます。

$ cd
$ python3 -m venv uwsgi-tutorial
$ cd uwsgi-tutorial
$ source bin/activate

Djangoをインストールして、プロジェクトを作成します。
pythonのバージョンに合わせたバージョンのDjangoがインストールされます。(今回は4.0.5
pipでインストールしたものはpip listでバージョンを確認できます。

$ pip install Django
$ django-admin startproject mysite
$ cd mysite

uWSGIをインストールしてテストページを作成します。

$ pip install uwsgi
$ vi test.py
test.py
# test.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"] # python3
    #return ["Hello World"] # python2

uWSGIを起動してテストページを表示させます。
今回は公式に沿って、8000ポートを使用していきます。

$ uwsgi --http :8000 --wsgi-file test.py

http://パブリックIPアドレス:8000にアクセスして、テストページを表示させてみましょう。
uWSGIが動いていることを確認出来たら、DjangoをuWSGIを使用して表示させていきます。

vi mysite/settings.py
settings.py
#変更前
ALLOWED_HOSTS = []

#変更後
ALLOWED_HOSTS = ['パブリックIPアドレス']
# manage.pyがある階層で実行
$ uwsgi --http :8000 --module mysite.wsgi

再度http://パブリックIPアドレス:8000にアクセスして、Djangoのページが表示されれば成功です。

nginxでDjangoを表示させる

これまでの操作でthe web client <-> uWSGI <-> Djangoまで連携が終了しています。
続いてthe web client <-> the web server <-> the socket <-> uWSGI <-> Pythonの連携を進めていきます。

まずnginxをインストールし、起動させていきます。

$ sudo amazon-linux-extras install nginx1
$ sudo systemctl start nginx.service
$ sudo systemctl enable nginx.service

nginxに設定ファイルを作成していきます。

$ sudo mkdir /etc/nginx/sites-available/
$ sudo vi /etc/nginx/sites-available/mysite_nginx.conf
mysite_nginx.conf
# mysite_nginx.conf

# the upstream component nginx needs to connect to
upstream django {
    # server unix:///path/to/your/mysite/mysite.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 パブリックIPアドレス; # 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 /home/ec2-user/uwsgi-tutorial/mysite/media;  # your Django project's media files - amend as required #projectのパス配下にmediaを配置します。
    }

    location /static {
        alias /home/ec2-user/uwsgi-tutorial/mysite/static; # your Django project's static files - amend as required #projectのパス配下にstaticを配置します。
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  django;
        include     /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
    }
}

/etc/nginx/sites-enabled にシンボリックリンクを作成します。

$ sudo mkdir /etc/nginx/sites-enabled/
$ sudo ln -s /etc/nginx/sites-available/mysite_nginx.conf /etc/nginx/sites-enabled/

nginx.confの最下部に追記して上記で作成した設定ファイルを読み込めるようにします。

$ sudo vi /etc/nginx/nginx.conf
nginx.conf
   ~~~前略~~~
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

    include /etc/nginx/sites-enabled/*;

}
$ sudo systemctl restart nginx.service

Djangoの静的ファイルをnginxで表示させるため、プロジェクト内にコピーします。
まず始めに先ほどmysite_nginx.confで指定したパスにmediastaticディレクトリを作成します。

$ mkdir media
$ mkdir static

続いてプロジェクト配下にあるsettings.pyに追記していきます。

$ vi mysite/settings.py
settings.py
"""
Django settings for mysite project.

Generated by 'django-admin startproject' using Django 4.0.5.

For more information on this file, see
https://docs.djangoproject.com/en/4.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
"""

import os           #追記
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

 
   ~~~中略~~~


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/

STATIC_URL = 'static/'

# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

STATIC_ROOT = os.path.join(BASE_DIR, "static/")   #追記

manage.pyがある階層で実行します。

$ python manage.py collectstatic

ここまで完了したら、uWSGIとnginxの連携を確認するため、テストページを表示させてみましょう。
test.pyのある階層で下記コマンドを実行します。

$ uwsgi --socket :8001 --wsgi-file test.py

http://パブリックIPアドレス:8000にアクセスしてテストページが表示されたら、Djangoの表示も確認してみましょう。
manage.pyのある階層で下記コマンドを実行します。

$ uwsgi --socket :8001 --module mysite.wsgi

UNIXソケットを使用して接続する

UNIXソケットを使用して接続できるようにします。
mysite_nginx.confの内容を修正します。

$ sudo vi /etc/nginx/sites-available/mysite_nginx.conf
mysite_nginx.conf
# mysite_nginx.conf

# the upstream component nginx needs to connect to
upstream django {
     server unix:/run/uwsgi/mysite.sock; # for a file socket #コメントアウトを外し、パスを入力する
    #server 128.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

$ sudo systemctl restart nginx.service

ソケットファイルができるディレクトリを作成し、権限を変更します。
このディレクトリの権限は所有者がuWSGIを実行するユーザー(今回はec2-user)、所有グループがwebサーバーを実行するユーザーグループに設定する必要があります。

$ sudo mkdir /run/uwsgi
$ sudo chown ec2-user:nginx /run/uwsgi/

UNIXソケットを使用して、Djangoを表示できるか確認してみましょう。
manage.pyのある階層で下記コマンドを実行します。
--chmod-socket=666を使用して、ソケットファイルの権限を666にして実行します。

$ uwsgi --socket /run/uwsgi/mysite.sock --module mysite.wsgi --chmod-socket=666

.iniファイルを使用してuWSGIを起動

これまでコマンドで実行していた操作を.iniファイルを作成して、起動できるようにします。

$ vi mysite_uwsgi.ini
mysite_uwsgi.ini
# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /home/ec2-user/uwsgi-tutorial/mysite
# Django's wsgi file
module          = mysite.wsgi
# the virtualenv (full path)
home            = /home/ec2-user/uwsgi-tutorial

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = /run/uwsgi/mysite.sock
# ... with appropriate permissions - may be needed
chmod-socket    = 666
# clear environment on exit
vacuum          = true

起動してブラウザから確認してみましょう。

$ uwsgi --ini mysite_uwsgi.ini

ここまでできたら、仮想環境からでても、簡単にDjangoを立ち上げることが可能です。
以下の操作で試してみます。

$ deactivate
$ pip3 install uwsgi
$ uwsgi --ini mysite_uwsgi.ini

postgresqlとDjangoを連携する

インストールと設定を行う

pythonとpostgresqlを連携させるためにpsycopg2を使用します。
psycopg2のインストールは仮想環境化で行ってください。

$ cd ..   #uwsgi-tutorialがある階層へ移動
$ source bin/activate
$ pip3 install psycopg2-binary

インストールしたらpip listで確認しましょう。

phpとpostgresqlをインストールしていきます。

$ sudo amazon-linux-extras install php8.0 postgresql14

pyenvを使用していた場合は下記のようなエラーがでる可能性があります。

/home/ec2-user/.pyenv/versions/3.9.2/bin/python: No module named amazon_linux_extras

シンボリックリンクをはることで使用できるようになるはずです。

ln -s /lib/python2.7/site-packages/amazon_linux_extras ~/.pyenv/versions/3.9.2/lib/python3.9/site-packages/

必要なツールをインストールしていきます。

$ sudo yum install postgresql-server postgresql-devel postgresql-contrib

データーベースを初期化してから、一時的にパスワードなしでログインできるように設定を変更します。設定ファイルを開き、identの箇所をtrustに変更していきます。

$ sudo postgresql-setup initdb
$ sudo vi /var/lib/pgsql/data/pg_hba.conf
pg_hba.conf
    ~~~前略~~~
# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust #ここを変更
# IPv6 local connections:
host    all             all             ::1/128                 trust #ここを変更
# Allow replication connections from localhost, by a user with the
   ~~~以下略~~~

システムを起動していきます。

$ sudo systemctl start postgresql
$ sudo systemctl enable postgresql
$ psql -h localhost -p 5432 -U postgres

起動できたら、データベースdjango、ユーザー名django、パスワードdjangoを設定していきます。
それぞれの名前は適宜設定してください。
Djangoの推奨設定にも変更していきます。

postgres=# CREATE DATABASE django;
CREATE DATABASE
postgres=# CREATE USER django WITH PASSWORD 'django';
CREATE ROLE
postgres=# ALTER ROLE django SET client_encoding TO 'utf8';
ALTER ROLE
postgres=# ALTER ROLE django SET default_transaction_isolation TO 'read committed';
ALTER ROLE
postgres=# ALTER ROLE django SET timezone TO 'Asia/Tokyo';
ALTER ROLE
postgres=# GRANT ALL PRIVILEGES ON DATABASE django TO django;
GRANT

コマンドに戻り、パスワード認証に設定を変更します。
設定ファイルを開き、peermd5に変更します。

$ sudo vi /var/lib/pgsql/data/pg_hba.conf
pg_hba.conf
     ~~~前略~~~
# "local" is for Unix domain socket connections only
local   all             all                                     md5 #ここを変更
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust
# Allow replication connections from localhost, by a user with the
$ sudo systemctl restart postgresql

ここまででpostgresqlの設定は完了です。

Djangoの設定

次にDjango側の設定を行います。
ユーザー名やデータベース名は適宜変更してください。

$ vi mysite/mysite/settings.py

変更前

settings.py
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

変更後

settings.py
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases

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

設定が終わったら、マイグレーションを行います。

$ cd mysite    #manage.pyがある階層へ
$ python manage.py migrate

ここまでできたら連携は完了です。

起動してみましょう。

$ uwsgi --ini mysite_uwsgi.ini

http://パブリックIPアドレス:8000にアクセスして、ロケットが表示されることを確認しましょう。
スクリーンショット 2022-06-28 153539.png

参考サイト

venvでDjangoの環境を作成してみたった(Python3.3以降)
uWSGI公式ドキュメント
Django公式ドキュメント
pyenvを使ってPython実行環境の構築
(Amazon Linux2(ec2),CentOS7)SQLite3の最新バージョンをインストールする
Django2.2で開発サーバー起動時にSQLite3のエラーが出た場合の対応
Djangoのデプロイ:Nginx、uWSGI
psycopg2をインストールしてPythonからPostgreSQLを操作する
「amazon-linux-extras」→「No module named amazon_linux_extras」になる場合の対処法
DjangoにPostgreSQLを適用する

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?