Raspberry Pi 2 Model Bを使ってDjangoアプリを作ろうかなと思いました。
環境構築をどうするかと考えたところ、RaspbianでDockerを動かせると知りました。
Docker comes to Raspberry Pi - Raspberry Pi
Dockerが動くならdocker-composeもいけるのではと思い、調べてみたところ動かしている方々がいました。
そこで、Raspberry Pi 2 Model B + docker-compose上に、Django + PostgreSQLなアプリをデプロイしてみました。
目次
- 環境
- Raspbian 2018-04-18のセットアップ
- デプロイするものを作成
- RaspbianにDockerまわりをインストール
- ソースコードをclone
- manage.pyの実行
- docker-composeによる起動
- 接続確認
- 停止
- いらないものを削除
- Raspbianシャットダウン
- ソースコード
- 参考
環境
- Raspberry Pi 2 Model B
- Raspbian 2018-04-18
- Django 2.0.5
- PostgreSQL
- Dockerイメージは公式配布のもの
なお、DjangoアプリやDockerまわりの設定は、公式チュートリアルを改変したものです。
Quickstart: Compose and Django | Docker Documentation
Raspbian 2018-04-18のセットアップ
以前の記事を参考にセットアップしました。
Python2 + Scapyで、Raspberry Pi 2 Model B をブリッジにできるか試してみた #router_jisaku - メモ的な思考的な
内容としては、
です。
デプロイするものを作成
以下の
- Djangoアプリ
- Dockerfile
- docker-compose.yml
をGitHubにpushしておきます。
Djangoアプリ
今回作成するDjangoアプリは
localhost:8000/myapp/<pk>
にアクセスするとTemplateViewを返す- Django adminを利用可能
- MacではSQLite、Raspbian上ではPostgreSQLを使用
- makemigrationsも実施済
- 環境変数により、DBバックエンドをSQLiteとPostgreSQLのどちらかを利用する
という簡単なものです。
リポジトリにpushしてあるので、今回は省略します。
https://github.com/thinkAmi-sandbox/rpi_docker_django_postgres-sample
なお、requirements.txtも用意しましたが、PostgreSQL用のライブラリとして psycopg2-binary
を指定しました。
リリースノートによると、2.7.4からパッケージが分かれ、 psycopg2-binary
を使うように書かれているためです。
http://initd.org/psycopg/articles/2018/02/08/psycopg-274-released/
そのため、psycopg2を指定するとワーニングが出たため、 psycopg2-binary
を指定しています。
Dockerfile
Docker公式チュートリアルのものです。
FROM python:3 ENV PYTHONUNBUFFERED 1 RUN mkdir /code WORKDIR /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/
docker-compose.ymlの作成
こちらは、公式チュートリアルのものを一部修正しています。
- 外部からPostgreSQLに接続できるよう、dbにポートを追加
- Docker上かどうかを判断するため、
IS_DOCKER
という環境変数を設定- 良い方法でないかもしれませんが、今回はお手軽に...
version: '3' services: db: image: postgres web: build: . command: python3 manage.py runserver 0.0.0.0:8000 volumes: - .:/code ports: - "8000:8000" depends_on: - db
RaspbianにDockerまわりをインストール
- Docker
- docker-compose
をインストールします。
Docker
公式ブログの通り、Dockerをインストールします。
pi@raspberrypi:~ $ curl -sSL https://get.docker.com | sh # Executing docker install script, commit: 36b78b2 + sudo -E sh -c apt-get update -qq >/dev/null + sudo -E sh -c apt-get install -y -qq apt-transport-https ca-certificates curl >/dev/null + sudo -E sh -c curl -fsSL "https://download.docker.com/linux/raspbian/gpg" | apt-key add -qq - >/dev/null Warning: apt-key output should not be parsed (stdout is not a terminal) + sudo -E sh -c echo "deb [arch=armhf] https://download.docker.com/linux/raspbian stretch edge" > /etc/apt/sources.list.d/docker.list + [ raspbian = debian ] + sudo -E sh -c apt-get update -qq >/dev/null + sudo -E sh -c apt-get install -y -qq --no-install-recommends docker-ce >/dev/null + sudo -E sh -c docker version Client: Version: 18.05.0-ce API version: 1.37 Go version: go1.9.5 Git commit: f150324 Built: Wed May 9 22:24:36 2018 OS/Arch: linux/arm Experimental: false Orchestrator: swarm Server: Engine: Version: 18.05.0-ce API version: 1.37 (minimum version 1.12) Go version: go1.9.5 Git commit: f150324 Built: Wed May 9 22:20:37 2018 OS/Arch: linux/arm Experimental: false If you would like to use Docker as a non-root user, you should now consider adding your user to the "docker" group with something like: sudo usermod -aG docker pi Remember that you will have to log out and back in for this to take effect! WARNING: Adding a user to the "docker" group will grant the ability to run containers which can be used to obtain root privileges on the docker host. Refer to https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface for more information.
インストール時のログに従い、 docker
グループに pi
ユーザを追加します。
pi@raspberrypi:~ $ sudo usermod -aG docker pi
念のため、再起動しておきます。
pi@raspberrypi:~ $ sudo shutdown -r now
docker-compose
docker-composeはpipでインストールします。
なお、 sudo
忘れると docker-compose
コマンドが使えなかったので、忘れずにつけておきます。
pi@raspberrypi:~ $ sudo pip install docker-compose ... Successfully installed PyYAML-3.12 backports.ssl-match-hostname-3.5.0.1 cached-property-1.4.2 docker-3.3.0 docker-compose-1.21.2 docker-pycreds-0.2.3 dockerpty-0.4.1 docopt-0.6.2 functools32-3.2.3.post2 jsonschema-2.6.0 texttable-0.9.1 websocket-client-0.47.0
ソースコードをclone
Raspbian上の適当なディレクトリに、GitHubのリポジトリをcloneしておきます。
pi@raspberrypi $ git clone https://github.com/thinkAmi-sandbox/rpi_docker_django_postgres-sample.git .
manage.pyの実行
1回限りの作業
- migrate
- loaddata
- createsuperuser
を docker-compose run
で実行していきます。
migrate
初めて docker-compose コマンドを使ったため、migrate前に色々な設定が走ります *1 。
pi@raspberrypi $ docker-compose run web python manage.py migrate Creating network "docker_django_default" with the default driver Creating docker_django_db_1 ... done Building web Step 1/8 : FROM python:3 ---> 98281429ea18 Step 2/8 : ENV PYTHONUNBUFFERED 1 ---> Running in 913b4e88ef19 Removing intermediate container 913b4e88ef19 ---> 52f2af605dd4 Step 3/8 : RUN mkdir /code ---> Running in 272a8670ae9e Removing intermediate container 272a8670ae9e ---> ab158a0f4822 Step 4/8 : WORKDIR /code Removing intermediate container d991836249af ---> 35eec4df510b Step 5/8 : ADD requirements.txt /code/ ---> 0f31d94edaf2 Step 6/8 : RUN pip install -r requirements.txt ---> Running in ecf1decd7b32 Collecting django (from -r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/23/91/2245462e57798e9251de87c88b2b8f996d10ddcb68206a8a020561ef7bd3/Django-2.0.5-py3-none-any.whl (7.1MB) Collecting psycopg2-binary (from -r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/77/09/4991fcd9a8f4bea1ee3948e1729fa17c184d25bd10809bacc143626361b9/psycopg2-binary-2.7.4.tar.gz (426kB) Collecting pytz (from django->-r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/dc/83/15f7833b70d3e067ca91467ca245bae0f6fe56ddc7451aa0dc5606b120f2/pytz-2018.4-py2.py3-none-any.whl (510kB) Building wheels for collected packages: psycopg2-binary Running setup.py bdist_wheel for psycopg2-binary: started Running setup.py bdist_wheel for psycopg2-binary: still running... Running setup.py bdist_wheel for psycopg2-binary: still running... Running setup.py bdist_wheel for psycopg2-binary: finished with status 'done' Stored in directory: /root/.cache/pip/wheels/60/a9/b1/390d13a4c6ae769c74c56efdd25573d76b9fba441430189658 Successfully built psycopg2-binary Installing collected packages: pytz, django, psycopg2-binary Successfully installed django-2.0.5 psycopg2-binary-2.7.4 pytz-2018.4 Removing intermediate container ecf1decd7b32 ---> 4cb1031555c5 Step 7/8 : ADD . /code/ ---> cfa31851aba0 Step 8/8 : ENV IS_DOCKER true ---> Running in 9d76ae22228f Removing intermediate container 9d76ae22228f ---> dd8368ef0606 Successfully built dd8368ef0606 Successfully tagged docker_django_web:latest WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. Operations to perform: Apply all migrations: admin, auth, contenttypes, myapp, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying myapp.0001_initial... OK Applying sessions.0001_initial... OK
fixture
pi@raspberrypi $ docker-compose run web python manage.py loaddata initial_data Starting docker_django_db_1 ... done Installed 1 object(s) from 1 fixture(s)
createsuperuser
pi@raspberrypi $ docker-compose run web python manage.py createsuperuser Starting rpi_docker_django_postgres_sample_db_1 ... done Username (leave blank to use 'root'): admin Email address: admin@example.com Password: Password (again): Superuser created successfully.
docker-composeによる起動
docker-compose up
で起動します。
pi@raspberrypi $ docker-compose up docker_django_db_1 is up-to-date Creating docker_django_web_1 ... done Attaching to docker_django_db_1, docker_django_web_1 db_1 | The files belonging to this database system will be owned by user "postgres". db_1 | This user must also own the server process. ... db_1 | 2018-05-24 12:39:39.750 UTC [1] LOG: database system is ready to accept connections web_1 | Performing system checks... web_1 | web_1 | System check identified no issues (0 silenced). web_1 | May 24, 2018 - 12:42:26 web_1 | Django version 2.0.5, using settings 'myproject.settings' web_1 | Starting development server at http://0.0.0.0:8000/ web_1 | Quit the server with CONTROL-C.
接続確認
curl
問題なく動作していました。
$ curl http://192.168.10.201:8000/myapp/1/ <div class="container"> ふー </div>
Django admin
Django adminのログイン〜データ作成まで問題なくできました。
追加したデータへのcurlも成功しました。
$ curl http://192.168.10.201:8000/myapp/2/ <div class="container"> ばー </div>
PostgreSQL
psql
を使って、登録したデータを確認します。
接続
まず、Raspbian上で docker-compose ps
でPostgreSQLのポートがRaspbianに転送されているかを確認します。
# docker-compose.ymlファイルが存在するディレクトリにいることを確認 pi@raspberrypi $ ls -al ... -rw-r--r-- 1 pi pi 282 May 26 12:30 docker-compose.yml # PostgreSQLの5432ポートが、Raspbianの9876ポートに転送されていることを確認 pi@raspberrypi $ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------- docker_django_db_1 docker-entrypoint.sh postgres Up 0.0.0.0:9876->5432/tcp docker_django_web_1 python3 manage.py runserve ... Up 0.0.0.0:8000->8000/tcp
次に、RaspbianもしくはMac上で psql
を使って接続します。
# Macの場合 $ psql -h 192.168.10.201 -U postgres -p 9876 psql (10.3, server 10.4 (Debian 10.4-1.pgdg90+1)) Type "help" for help. postgres=#
テーブル一覧とデータの確認
\dt
で、テーブルの一覧を確認します。Djangoのテーブルがあるようです。
postgres=# \dt List of relations Schema | Name | Type | Owner --------+----------------------------+-------+---------- public | auth_group | table | postgres public | auth_group_permissions | table | postgres public | auth_permission | table | postgres public | auth_user | table | postgres public | auth_user_groups | table | postgres public | auth_user_user_permissions | table | postgres public | django_admin_log | table | postgres public | django_content_type | table | postgres public | django_migrations | table | postgres public | django_session | table | postgres public | myapp_foo | table | postgres (11 rows)
続いて、データを確認します。
postgres=# select * from myapp_foo; id | name ----+------ 1 | ふー 2 | ばー (2 rows)
psqlの終了
データが確認できたので、 \q
でpsqlを終了します。
postgres=# \q
停止
Ctrl + C
にて停止します。
^CGracefully stopping... (press Ctrl+C again to force) Stopping docker_django_web_1 ... done Stopping docker_django_db_1 ... done
いらないものを削除
docker-compose down
にて削除します。
# 現在の環境を確認 pi@raspberrypi $ docker-compose ps Name Command State Ports ----------------------------------------------------------------------- docker_django_db_1 docker-entrypoint.sh postgres Exit 0 docker_django_web_1 python3 manage.py runserve ... Exit 137 pi@raspberrypi:~/work/docker_django $ docker-compose images Container Repository Tag Image Id Size ------------------------------------------------------------------------ docker_django_db_1 postgres latest af4e361a5ae8 218 MB docker_django_web_1 docker_django_web latest d0958cc8b3f7 619 MB # いらないものを削除 pi@raspberrypi $ docker-compose down Removing docker_django_web_1 ... done Removing docker_django_web_run_4 ... done Removing docker_django_web_run_3 ... done Removing docker_django_web_run_2 ... done Removing docker_django_web_run_1 ... done Removing docker_django_db_1 ... done Removing network docker_django_default # 削除されていることを確認 pi@raspberrypi $ docker-compose ps Name Command State Ports ------------------------------ pi@raspberrypi $ docker-compose images Container Repository Tag Image Id Size ---------------------------------------------- ## Dockerイメージは残っていることに注意 pi@raspberrypi $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker_django_web latest d0958cc8b3f7 About an hour ago 649MB postgres latest af4e361a5ae8 9 days ago 228MB python 3 98281429ea18 2 weeks ago 608MB
Raspbianシャットダウン
すべて終わったので、Raspbianをシャットダウンしておきます。
pi@raspberrypi $ sudo shutdown -h now Connection to 192.168.10.201 closed by remote host. Connection to 192.168.10.201 closed.
ソースコード
GitHubに上げてあります。
https://github.com/thinkAmi-sandbox/rpi_docker_django_postgres-sample