MENU
  • ホーム
  • プログラミング
  • ワードプレス
    • プラグインプラグイン関連記事
    • 賢威賢威のカスタマイズ
    • CSSCSSの関連記事
  • サイト情報
    • プライバシーポリシー
  • ツール
    • メルエディター
    • フリマスパイダー – 疾風
    • フリマスパイダー
    • -ポイ活くんα-
  • お問い合わせ
あらゆるモノにHackする、探究者の読み物。
Let's Hack Tech
  • ホーム
  • プログラミング
  • ワードプレス
    • プラグインプラグイン関連記事
    • 賢威賢威のカスタマイズ
    • CSSCSSの関連記事
  • サイト情報
    • プライバシーポリシー
  • ツール
    • メルエディター
    • フリマスパイダー – 疾風
    • フリマスパイダー
    • -ポイ活くんα-
  • お問い合わせ
Let's Hack Tech
  • ホーム
  • プログラミング
  • ワードプレス
    • プラグインプラグイン関連記事
    • 賢威賢威のカスタマイズ
    • CSSCSSの関連記事
  • サイト情報
    • プライバシーポリシー
  • ツール
    • メルエディター
    • フリマスパイダー – 疾風
    • フリマスパイダー
    • -ポイ活くんα-
  • お問い合わせ
  1. ホーム
  2. プログラミング
  3. 言語別
  4. Python
  5. AWSのEC2にdjangoデプロイ時のトラブルシューティング

AWSのEC2にdjangoデプロイ時のトラブルシューティング

2023 2/02
Python
2020-02-082023-02-02
django

EC2へのDjangoデプロイで無茶苦茶時間食ったので、備忘録がてら、トラブル各種まとめてみます。

ちなみにdjango童貞です。「こうしたらええんやで」っていう諸先輩方いらっしゃいましたらコメントいただければ喜びます。

目次

デプロイ一連の流れ

  • EC2インスタンス作成
  • ポート開放
  • SSH接続で環境整備
  • プロジェクトファイルアップロード
  • セッティングファイルあれこれ
  • 完成

EC2インスタンス作成

EC2インスタンス作成
EC2インスタンス作成
AMI選択
AMI選択

なんか二種類ありますが、違いもよくわかりませんし、多分どっちでもいいです。好きな方で。

セキュリティグループの編集(ポート開放)

セキュリティグループ
セキュリティグループ

インバウンドの方をこんな感じの設定にすればOKです。
ちなみに作成時に編集しなくてもあとから変更できます。

あとは大体ディフォルトのまま進めてOKです。

SSH接続

事前にEC2キーペアを作っていたらそれを紐づけ、そうじゃなければEC2インスタンス生成時に項目があるので、鍵ファイル(.pem)をDLしてローカルに保持しておきます。

SSHクライアントは普段使っているものでOKです。

今回はPycharm組み込みのSSHクライアントを例に接続方法を解説。

リモートサーバーの構成
リモートサーバーの構成

サーバーの構成ボタンを押してさらに進みます。

SSH設定
SSH設定
  • 型:SFTP
  • ホスト:EC2インスタンスのパブリックDNS(IPv4)
  • ユーザー名:ec2-user
  • 認証:Key pair
  • Private key path:EC2コンソールからDLした(.pem)ファイルのパス

ここまで入力して接続テストして、OKならルートパスとかはオートで入力できます。

マッピング(やると便利)

ここ設定しておくとPycharmのプロジェクト(ローカル)とリモートのサーバーを自動で同期できます(多分)

ローカルで編集・保存するたびに指定されたリモートサーバーの対応する位置へアップロードされるようです。

Pycharm SSH マッピング
Pycharm SSH マッピング
SSHターミナルで接続成功
SSHターミナルで接続成功

EC2インスタンスの環境整備

SSHで無事接続できたので、必要な環境を整備していきます。
参考: https://qiita.com/pokotsun/items/1272479e36c5146c6609

参考先ではユーザーを作成してますが、管理めんどくさかったのでディフォルトのec2-userのまま環境整備進めました。

ここではyum使ってますが環境によって適宜aptとかに読み替えてください。

yumで下準備

$ sudo -i
$ yum update -y
$ yum install -y vim git

Python3インストール

$ cd ~
$ sudo yum install -y gcc make zlib1g-dev zlib-devel openssl-devel tk-devel sqlite-devel bzip2 bzip2-devel readline-devel
$ wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tar.xz
$ tar Jxfv Python-3.7.4.tar.xz
$ cd Python-3.7.4/
$ ./configure --prefix=/home/ec2-user/.local/python
$ make
$ make install
# シンボリックリンクを貼る
$ sudo ln -s ~/.local/python/bin/python3 /usr/local/bin/python
$ sudo ln -s ~/.local/python/bin/pip3.7 /usr/local/bin/pip3
$ echo 'export PATH="/home/ec2-user/.local/python/bin:$PATH"' >> ~/.bashrc
$ echo 'alias pip=pip3' >> ~/.bashrc
# 確認
$ python -V
Python 3.7.4
$ pip -V
pip 19.0.3 from /home/ec2-user/.local/python/lib/python3.7/site-packages/pip (python 3.7)

プロジェクトファイルアップロード

アップロードはgithub使ってcloneしてもいいですし、Pycharmから普通にアップしてもいいですし、煮るなり焼くなりお好きに。

ただ、モジュールのインストール手動でやると面倒なので「requirements.txt」だけつくっておきます。

ローカルのプロジェクト直下で以下のコマンド。

$ pip freeze > requirements.txt

アップ後、依存関係復元

$ pip install -r requirements.txt

django→settings.pyの編集

本番環境用にsettings.pyを編集する必要があります。
以下の箇所を見つけて編集。

DEBUG = False # True => Falseにする

# ローカルホスト、リモートIP、リモートホストを追加
ALLOWED_HOSTS = ['127.0.0.1', 'xx.xx.xxx.xxx', 'ec2-xx-xx-xxx-xxx.ap-northeast-1.compute.amazonaws.com']

# staticファイル関係、必要であれば
STATIC_URL = '/static/' # 多分元々こうなってる
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

django童貞の僕としてはなぜdjangoのstaticファイルの構成がこんなめんどい感じなのかわからないまま・・・。

とりあえず、開発時にプロジェクト共通のstaticフォルダとか作ってなくて、app直下にstatic作って対応してた方は上記で問題ないと思います。

staticのファイルを集約する

$ python manage.py collectstatic

なぜこんな面倒なことさせるのか知りませんが、app直下のstaticファルダ内のファイルを集約してproject直下のstaticフォルダにコピーするコマンドです。

これやらないとリモートで見たときにstaticファイルが見つからず404になります。

さらに面倒なことにcollectstaticをやってても403になる場合があります。

サーバーミドルウェアインストールと設定

サーバーはnginxです。なうい(別になうくはないのか?)です。

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

さらにこれも必要なよう。

pip install gunicorn

gunicornはなんかnginxで受け取った処理をさらに中継するのに使うようです。

ここでdjango童貞の僕はこう思いました。

「いや、何でディフォルトのサーバー使わんのや?」

manage.py runserver

でええんちゃうのん?ただただめんどいだけちゃうんか、と。
回答は以下。

参考: https://blog.hirokiky.org/entry/2018/10/06/151830

要約すると、

「なんかわからんけど、とりあえず早いらしい」

なら、まぁ、使っとくか。

nginx→gunicornの流れ

$ sudo vi /etc/nginx/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 /var/run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {


    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;

    index   index.html index.htm;

    upstream app_server {
       server 127.0.0.1:8000 fail_timeout=0;
    }

    server {

        ## ここを書き換える
        listen    80;
        server_name     (EC2のドメイン or IPアドレス);
        client_max_body_size    6G;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
            # 以下4行を追加
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass   http://app_server;
        }

        location /static {
            alias (アプリケーションのstaticファイルの絶対パスを記入);
            expires 5h;
        }

        # redirect server error pages to the static page /40x.html
        #
        error_page 404 /404.html;
            location = /40x.html {
        }

        # redirect server error pages to the static page /50x.html
        #
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ .php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ .php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /.ht {
        #    deny  all;
        #}
    }

}

考えるのめんどくさかったので、設定ファイル全部消してからの完コピです。
マジでありがとうございます。

参考: https://qiita.com/pokotsun/items/1272479e36c5146c6609

サーバーの起動

ここまで設定が完了したらあとはサーバーを立ち上げてアクセスするのみ。

$ sudo service nginx restart
$ gunicorn MyAppName.wsgi --bind=0.0.0.0:8000

MyAppNameはプロジェクト直下の最上位アプリケーション名(settings.pyとかが入っているapp)です。

確認してみればわかりますが、wsgi.pyというファイルがあります。

この状態でAWSのEC2コンソールで確認できるパブリックDNSのアドレスへアクセスするとローカルで見ていたのと同じようにdjangoで作ったWebアプリが確認できるはずです。

ちなみにgunicornはこの状態だとSSHの接続を切ると落ちてしまいますので、普段使いで常時待機状態にするならデーモンとして立ち上げる必要があります。

$ gunicorn MyAppName.wsgi --bind=0.0.0.0:8000 -D

-D オプションをつけるだけです。これでバックグラウンド起動になります。

デーモンで走ってるgunicornサーバーをkillするときは以下コマンド

$ pkill gunicorn

nginxを止めるときはこうです。

$ sudo service nginx stop

ちょっとハマったトラブル集

いくつかハマった箇所があるので紹介します。

SQliteのバージョンエラー

django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17).

3.8以上のSQliteのバージョンを要求されます。
SQliteってバージョンもクソもあるんかよ・・・。とか思いながら、調べました。

参考: https://qiita.com/rururu_kenken/items/8202b30b50e3bfa75821

と、まぁ色々弄くり回してという方法もあるようですが、一番簡単なのはこれです。

$ pip install django==2.1

どうやらdjango2.2以上から出現するエラーのようですので、特に2.2にこだわる理由もなかったので僕はdjangoのバージョンを下げることで対応しました。

Staticファイル群の403

CSSとかJSファイルが403でちゃんと動いてないなってなったらこのパターンだと思います。

ec2-userにパーミッションを振る

参考: https://qiita.com/xKxAxKx/items/f43d1bddbc4fb31013b1

$ sudo chmod o+x /home/ec2-user/

これで一発解決。

Python
AWS django ec2
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする コメントをキャンセル

email confirm*

post date*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

シンプル美と機能性を両立させた、国内最高峰のWordPressテーマ『SWELL』
人気記事
  • IQテストいくつか受けてみました
    ネット上で信憑性がありそうなIQテスト、5種類まとめて受けた結果…
  • hayate
    メルカリの商品を世界最速で購入するためだけのアラートツール
  • 【Python】BeautifulSoupの使い方・基本メソッド一覧|スクレイピング
  • Pythonファイルのexe化
    【悲報】PyInstallerさん、300MBのexeファイルを吐き出すようになる
  • Amazon Echo アレクサのコマンドまとめ
    AmazonEchoの使い方とできる事、アレクサへの指示コマンド一覧
最近の投稿
  • 正規表現処理の濁点でハマった話2024-12-12
  • 保護中: 疾風v2更新履歴2024-05-31
  • 【自営・経営者向け・税金も】クレジットカードガチ勢による最強クレカ解説2023-10-23
  • PyQt5 QListWidget の item削除でtextBoxのフォーカスが奪われる2023-03-05
  • WordPressからのメールが届かない時の調査と解決法2023-02-27
目次
目次