AWSのEC2インスタンスとRDSインスタンスがある状態からどうすればDjango+Apache(+mod-wsgi)+MySQLでWebアプリを公開できるかです.Webアプリプログラムはあるものとします.なお,情報は2020/1/1時点です.
また,pyenv+Anacondaを使っていますが,この辺はPythonをyum installするとか今時Pipenv使うでしょとかは各自の宗教に合わせてください.
使用したバージョンなど
Python関係
- Python 3.7.4 (anaconda3-2019.10 使用)
- pyenv 1.2.15-9-gac246e16
- Django 3.0.1
- django-el-pagination 3.2.4
- django-maintenance-mode 0.14.0
- django-storages 1.8
- mod-wsgi 4.7.0
- mysqlclient 1.4.6
Apache,MySQL Client
$ httpd -v
Server version: Apache/2.4.41 ()
Server built: Oct 22 2019 22:59:04
$ mysql --version
mysql Ver 8.0.18 for Linux on x86_64 (MySQL Community Server - GPL)
MySQLはバージョン8.0系を使っています.
pyenvとPython3のインストール
pyenvのインストール
デフォルトのpythonは汚したくない.
sudo git clone git://github.com/yyuu/pyenv.git /usr/local/pyenv
% 所有者がsudoはやだ.再帰的に変えてしまう
sudo chown -r ec2-user:ec2-user pyenv
~/.bash_profile
を書き換え
export PATH
export PYENV_ROOT="/usr/local/pyenv"
export GOPATH="$HOME/.go"
export PATH="$GOPATH/bin:$PYENV_ROOT/bin:$PYENV_ROOT/bin/pyenv:$PATH"
eval "$(pyenv init -)"
書き換えたら source .bash_profile
して読み込む.
##Python3のインストール
楽したいのでanacondaいれちゃう.宗教戦争には関わらないです.condaでのインストールは絶対に使わないけど.
# 執筆時点の最新安定版
pyenv install anaconda3-2019.10
# デフォを変える
pyenv global anaconda3-2019.10
Djangoの導入
これは簡単.ただDjangoのバージョンには要注意.後方互換性のない変更もしばしば.
pip install django
その他便利なやつ
% ファイルを扱う
pip install django-storages
% メンテナンスモード
pip install django-maintenance-mode
% s3を扱う
pip install boto3
ウェブサーバ導入
ウェブサーバ導入します.目指せapache+mod-wsgi.
apacheのインストール
sudo yum install httpd
sudo systemctl start httpd
# 確認するなら
sudo systemctl status httpd
# サービスのスタート
sudo systemctl start httpd.service
グローバルIPを指定すればApacheテストページが表示される
Apacheテストページではないものにしたいなら, /etc/httpd/conf/httpd.conf
内を書き換え.
参考にしたページ:
https://qiita.com/saki-engineering/items/5ea8e66b498fc7d4a399
https://miyabi-lab.space/blog/16#200
mod-wsgiの導入
Pythonとapacheをつなぐツール.
インストールのためのコンパイル時にapexとgccが必要になるが,デフォルトでは入っていない.
sudo yum install httpd-devel
sudo yum install gcc
こうすればpipでmod-wsgiは入る
pip install mod_wsgi
連携させる
以下はDjangoで公開するページがある前提.サンプル的なものでも可.
一部参考にしたページ: https://qiita.com/saki-engineering/items/5ea8e66b498fc7d4a399
mod-wsgiの入っている場所を探す.ルートディレクトリに移動してから
$ find -name 'mod_wsgi*.so' 2> /dev/null
./usr/local/pyenv/versions/anaconda3-2019.10/lib/python3.7/site-packages/mod_wsgi/server/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so
よって /usr/local/pyenv/versions/anaconda3-2019.10/lib/python3.7/site-packages/mod_wsgi/server/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so
にある.
Amazon Linux 2なら多分 /etc/httpd/conf/httpd.conf
の最後に
# Load config files in the "/etc/httpd/conf.d" directory, if any.
IncludeOptional conf.d/*.conf
と書いてあるはずなので, /etc/httpd/conf.d/myconf.conf
に
LoadModule wsgi_module /usr/local/pyenv/versions/anaconda3-2019.10/lib/python3.7/site-packages/mod_wsgi/server/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so
WSGIScriptAlias / (wsgi.pyの置いた場所)
WSGIPythonPath (Djangoで書いたwebappプログラムのルートディレクトリ)
WSGIPythonHome (実行したいPythonの実行ファイルの親ディレクトリ; 例: /usr/local/pyenv/versions/anaconda3-2019.10)
Alias /static/ (Djangoで書いたwebappプログラムのstaticファイルのディレクトリ)
<Directory (Djangoで書いたwebappプログラムのルートディレクトリ)>
<Files wsgi.py>
Order deny,allow
Require all granted
</Files>
</Directory>
<Directory (Djangoで書いたwebappプログラムのstaticファイルのディレクトリ)>
Require all granted
</Directory>
とかく. sudo service httpd restart
する.
前やったときは WSGIPythonPath
を指定しなくてよかったのですがなぜでしょう…
MySQLの導入
RDSですでにMySQL8.0のサーバ立ち上げ済みとします.
MySQL 8.0用のクライアントを入れる
参考にしたページ: https://dev.classmethod.jp/cloud/aws/amazon-linux2-mysqlclient/
# リポジトリ追加
$ sudo yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
# 標準の状態で8.0の設定ですが一応有効に
$ sudo yum-config-manager --enable mysql80-community
# Mysql Client Install
$ sudo yum install -y mysql-community-client
$ mysql --version
mysql Ver 8.0.18 for Linux on x86_64 (MySQL Community Server - GPL)
サーバ始動
$ whereis mysql_config
mysql_config:
実はこの時点では mysql_config
がないと怒られる.
$ sudo yum install mysql-devel
すると
$ whereis mysql_config
mysql_config: /usr/bin/mysql_config /usr/share/man/man1/mysql_config.1.gz
そしてPythonからmysqlクライアントにアクセスするためにpipでインストール
pip install mysqlclient
#無限ページネーションしたい
$ pip install django-el-pagination
で入るやつは古かった.2年くらいリリースされていない.じゃあgitから落とせばいい(メンテナンスはきちんとされていてDjango3.0にもすぐに対応されている)
$ git clone https://github.com/shtalinberg/django-el-pagination.git
$ cd django-el-pagination/
$ pip install -e .
しかし,これでやっても動こうとするが,webサイトにアクセスできない. ModuleNotFoundError el_pagination
となってしまう.リンクがうまく張られないことが原因?それともeditableモードなのが原因?
じゃあgitから直接pip installしよう.
pip install git+https://github.com/shtalinberg/django-el-pagination.git
これでできた.
その他の必要な設定(settings.py)は
https://django-el-pagination.readthedocs.io/en/latest/start.html
を参照.
#swap領域の確保
EC2インスタンスのデフォルトのメモリのサイズはありえないほど小さいので必須.
$ sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
2048+0 レコード入力
2048+0 レコード出力
2147483648 バイト (2.1 GB) コピーされました、 31.4376 秒、 68.3 MB/秒
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
スワップ空間バージョン 1 を設定します。サイズ = 2 GiB (2147479552 バイト)
ラベルはありません, UUID=82de405a-d7ef-4ae3-ba93-16baa38c6e2c
$ sudo swapon /swapfile
# 確認
swapon -s
ファイル名 タイプ サイズ 使用済み 優先順位
/swapfile file 2097148 0 -2
# 起動時にswap領域が有効になるように
$ sudo vi /etc/fstab
# 追加
# /swapfile swap swap defaults 0 0
参考: https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-memory-swap-file/
#検索避け
/var/www/html/robots.txt
に
User-agent : *
Disallow : /
を作成,保存する