Amazon Linux 2でDjango実行環境を構築する

Python周りの環境構築はハマりどころが多いと感じています。今回はAmazon Linux 2でDjango実行環境を構築しようとしてハマってしまったので、その解決方法を記載しました。
2021.01.15

コンサル部のtobachi(@toda_kk)です。

Amazon Linux 2でDjango実行環境を構築する際、いくつかハマりどころがありました。

解決まで四苦八苦してしまったので、解決方法を簡単に記載しておきます。

なお、今回はCodeStarやコンテナイメージといった技術要素は用いず、単にAmazon Linux 2を利用したEC2インスタンス上でDjangoを実行する方法を記載しています。

あまり実業務で当てはまるケースはないかもしれませんが、諸事情で ssh からのpython manage.py runserverしなければならなくなった場合にご参考にしていただけますと幸いです。

Python実行環境を構築する

Amazon Linux 2のAMIからEC2インスタンスを起動すると、デフォルトでPythonがインストールされています。

ただし、2021年1月現在、Python 2.7系がインストールされています。3系を使いたい場合は、自分でインストールする必要があります。

pyenvをインストールする

Python実行環境については、いろいろとツールがあるかと思います。基本的にお好きなツールを使えば問題ないかと思いますが、今回はpyenvを利用していきます。

まずOS環境を最新化したあと、pyenv利用に必要なツールをインストールします。具体的には下記にあげたライブラリ群が必要になります。

sudo yum update -y
sudo yum install -y git gcc zlib-devel openssl-devel

続いてgitコマンドを実行してpyenvをインストールし、PATHを通します。

git clone https://github.com/yyuu/pyenv.git ~/.pyenv
pyenv version

# PATHを通す
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
source ~/.bash_profile

sqlite3を最新化する

さて、ここでpyenvを使ってPython3系をインストールしたいところなのですが、後に発生する問題を解決するためにsqlite3ライブラリを最新化しておきます。

Amazon Linux 2ではデフォルトでsqlite3がインストールされているのですが、現時点ではバージョンが3.7.17と少々古いです。Djangoをインストールして実行した際に、ライブラリのバージョンが原因で上手く実行できない場合があります。

Python3にはデフォルトでsqlite3モジュールが含まれているのですが、どうやらPythonインタープリターのセットアップ時にOSにインストールされているsqlite3ライブラリを参照し、Pythonで対応するモジュールをインストールするという動きをしているようです。

また、PythonとDjangoのバージョンは対応関係があるのですが、それぞれのバージョンによっては、Pythonインタープリターがインストールするsqlite3モジュールのバージョンと、Djangoの内部モジュールからimportしているsqlite3のバージョンの間で齟齬が発生してしまう場合があるようです。

そのため、このタイミングでOSのsqlite3ライブラリを最新化しておく必要があります。

Amazon Linux 2ではamazon-linux-extrasでライブラリを管理できますが、sqlite3は対応していないようなのでソースをダウンロードしてコンパイルするという方法を取ります。

SQLiteの公式ページから最新バージョンのソースのURLを確認した上で、下記コマンドを実行します。

# 最新バージョンのURLを指定する
wget https://www.sqlite.org/2020/sqlite-autoconf-3340000.tar.gz
tar xvfz sqlite-autoconf-3340000.tar.gz
cd sqlite-autoconf-3340000

# コンパイル
./configure --prefix=/usr/local
make
sudo make install

# シンボリックリンクを設定してPATHを通す
sudo mv /usr/bin/sqlite3 /usr/bin/sqlite3_old
sudo ln -s /usr/local/bin/sqlite3 /usr/bin/sqlite3
echo export LD_LIBRARY_PATH="/usr/local/lib" >> ~/.bash_profile
source ~/.bash_profile

sqlite3 --version

Python3をインストールする

これでようやくPython3系をインストールする準備が整いました。pyenvを利用して、今回はバージョン3.8.2を指定します。

pyenv install 3.8.2
pyenv global 3.8.2
python -V

Djangoの実行環境を構築する

さて、いよいよDjangoの実行環境を構築していきます。今回はDjango公式で提供されているチュートリアルに従い、プロジェクトを作成してみます。

Djangoをインストールする

Djangoのインストールは公式ドキュメントを参考にすれば問題ないかと思います。

ただ、プロジェクトを作成するdjango-adminを実行するためにはlibffi-develライブラリがインストールされている必要があります。

sudo yum install -y libffi-devel

また、ドキュメントの通りpython -m pip install Djangoを実行するとPATHが通らない場合があるようです(というか自分がその問題にぶつかりました。)

その場合はpip install Djangoを実行すれば良さそうです。

pip install Django
python -m django --version

プロジェクトの作成と実行

続いて、チュートリアルに従ってプロジェクトを作成します。

django-admin startproject mysite

これでようやくDjangoを実行できます。下記コマンドでサーバーを起動しましょう。

cd mysite
python manage.py runserver

おわりに

手順としては以上となります。実際に実行環境を構築してみて、かなりハマりどころが多かったと感じました。

ただし、このハマりどころは利用するライブラリやバージョンに依存していると思われます。例えばpyenvではなく pipenv / virtualenv / pyenv-virtualenv といった別のツールを使い環境を管理していれば、pyenvに依存した問題は回避できるでしょう。

そういう意味では、本記事の記載は限定的なケースではあるのですが、Python周りのバージョン問題はやはり根が深いなと感じました。

ちなみに、pythonシンボリックリンク自体を3系にしてしまう手もあるにはあるのですが、そうするとyumが壊れるという現象が発生するようです。いろいろあるんだなあ。

以上、コンサル部のtobachi(@toda_kk)でした。

参考