Docker上でPython3, Django2, MySQL5.7の環境作ってみた!

Web開発

dockerインストール済みの状態からスタート。
docker-composeでPython3,Django2のコンテナとMySQL5.7のコンテナを作成するとこまで。

mbazuki:odaimaker hide$ docker --version
Docker version 18.06.1-ce, build e68fc7a

本番環境はEC2を想定しているので、Python3,Django2のコンテナのイメージにAmazon Linux2をつかってみる。
ここを参考にDockerfileなどを作成していく。
https://docs.docker.com/compose/django/

できあがる環境

mbazuki:odaimaker hide$ docker-compose ps
      Name                    Command               State                 Ports              
 --------------------------------------------------------------------------------------------
 odaimaker_db_1    docker-entrypoint.sh mysqld      Up 0.0.0.0:3306->3306/tcp, 33060/tcp
odaimaker_web_1   sh -c sleep 3; python3 man ...   Up      0.0.0.0:8000->8000/tcp

odaimaker_web_1の中。

bash-4.2# cat /etc/system-release
Amazon Linux 2

bash-4.2# python3 -V
Python 3.7.0rc1 (default, Aug  1 2018, 03:51:55) 
[GCC 7.3.1 20180303 (Red Hat 7.3.1-5)]

bash-4.2# pip3 freeze
Django==2.1.2
mysqlclient==1.3.13
pytz==2018.5

Dockerfile

FROM amazonlinux
RUN amazon-linux-extras install python3
RUN pip3 install --upgrade pip
RUN yum install python3-devel mysql-devel gcc
RUN mkdir /home/odaimaker
WORKDIR /home/odaimaker
ADD requirements.txt /home/odaimaker/
RUN pip3 install -r requirements.txt

FROM amazonlinuxだけど実はamazonlinux2が入る。
*今回の例ではサンプルアプリケーションodaimakerを作成する

後でmysqlclientをpipでインストールすることになるが、以下のライブラリがないとエラーになる。

python3-devel mysql-devel gcc

起きるエラー。

Collecting mysqlclient (from -r requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/ec/fd/83329b9d3e14f7344d1cb31f128e6dbba70c5975c9e57896815dbb1988ad/mysqlclient-1.3.13.tar.gz (90kB)
    Complete output from command python setup.py egg_info:
    /bin/sh: mysql_config: command not found
    Traceback (most recent call last):
      File "", line 1, in 
      File "/tmp/pip-install-1abmpp0p/mysqlclient/setup.py", line 18, in 
        metadata, options = get_config()
      File "/tmp/pip-install-1abmpp0p/mysqlclient/setup_posix.py", line 53, in get_config
        libs = mysql_config("libs_r")
      File "/tmp/pip-install-1abmpp0p/mysqlclient/setup_posix.py", line 28, in mysql_config
        raise EnvironmentError("%s not found" % (mysql_config.path,))
    OSError: mysql_config not found
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-1abmpp0p/mysqlclient/
ERROR: Service 'web' failed to build: The command '/bin/sh -c pip3 install -r requirements.txt' returned a non-zero code: 1

gccがないと以下のエラー

Failed building wheel for mysqlclient
  Running setup.py clean for mysqlclient
Failed to build mysqlclient
Installing collected packages: pytz, Django, mysqlclient
  Running setup.py install for mysqlclient: started
    Running setup.py install for mysqlclient: finished with status 'error'
    Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-d7lq3518/mysqlclient/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-u6jux93a-record/install-record.txt --single-version-externally-managed --compile:
    /usr/lib64/python3.7/distutils/dist.py:274: UserWarning: Unknown distribution option: 'long_description_content_type'
      warnings.warn(msg)
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-3.7
    copying _mysql_exceptions.py -> build/lib.linux-x86_64-3.7
    creating build/lib.linux-x86_64-3.7/MySQLdb
    copying MySQLdb/__init__.py -> build/lib.linux-x86_64-3.7/MySQLdb
    copying MySQLdb/compat.py -> build/lib.linux-x86_64-3.7/MySQLdb
    copying MySQLdb/connections.py -> build/lib.linux-x86_64-3.7/MySQLdb
    copying MySQLdb/converters.py -> build/lib.linux-x86_64-3.7/MySQLdb
    copying MySQLdb/cursors.py -> build/lib.linux-x86_64-3.7/MySQLdb
    copying MySQLdb/release.py -> build/lib.linux-x86_64-3.7/MySQLdb
    copying MySQLdb/times.py -> build/lib.linux-x86_64-3.7/MySQLdb
    creating build/lib.linux-x86_64-3.7/MySQLdb/constants
    copying MySQLdb/constants/__init__.py -> build/lib.linux-x86_64-3.7/MySQLdb/constants
    copying MySQLdb/constants/CLIENT.py -> build/lib.linux-x86_64-3.7/MySQLdb/constants
    copying MySQLdb/constants/CR.py -> build/lib.linux-x86_64-3.7/MySQLdb/constants
    copying MySQLdb/constants/ER.py -> build/lib.linux-x86_64-3.7/MySQLdb/constants
    copying MySQLdb/constants/FIELD_TYPE.py -> build/lib.linux-x86_64-3.7/MySQLdb/constants
    copying MySQLdb/constants/FLAG.py -> build/lib.linux-x86_64-3.7/MySQLdb/constants
    copying MySQLdb/constants/REFRESH.py -> build/lib.linux-x86_64-3.7/MySQLdb/constants
    running build_ext
    building '_mysql' extension
    creating build/temp.linux-x86_64-3.7
    gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -flto -fuse-linker-plugin -ffat-lto-objects -flto-partition=none -fPIC -Dversion_info=(1,3,13,'final',0) -D__version__=1.3.13 -I/usr/include/mysql -I/usr/include/python3.7m -c _mysql.c -o build/temp.linux-x86_64-3.7/_mysql.o
    unable to execute 'gcc': No such file or directory
    error: command 'gcc' failed with exit status 1
    
    ----------------------------------------
Command "/usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-d7lq3518/mysqlclient/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-u6jux93a-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-d7lq3518/mysqlclient/
ERROR: Service 'web' failed to build: The command '/bin/sh -c pip3 install -r requirements.txt' returned a non-zero code: 1

requirements.txt

Django
mysqlclient

バージョンを指定しなければ最新版がインストールされる。

docker-compose.yml

version: '3'

services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
    ports:
      - 3306:3306
    volumes:
      - ./mysql/mysql_data:/var/lib/mysql

  web:
    build: . # buildに書かれているパスのDockerfileを参考にしてイメージを構築
    command: sh -c "sleep 3; python3 manage.py runserver 0.0.0.0:8000" # dbコンテナが起動完了していないとエラーが起きるので3秒待ってみる
    volumes:
      - .:/home/odaimaker
    ports:
      - "8000:8000"
    depends_on:
      - db

Djangoプロジェクトを作成

今こんな感じ

mbazuki:odaimaker hide$ ls
Dockerfile		docker-compose.yml	requirements.txt

Djangoプロジェクトを作成する

docker-compose run web django-admin.py startproject odaimaker .

成功するとこうなる

省略
 Successfully built mysqlclient
 Installing collected packages: pytz, Django, mysqlclient
 Successfully installed Django-2.1.2 mysqlclient-1.3.13 pytz-2018.5
 Removing intermediate container e612532eddbd ---> 565ff44f3be9
Successfully built 565ff44f3be9
Successfully tagged odaimaker_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`.
mbazuki:odaimaker hide$ ls -al
total 48
drwxr-xr-x  9 hide  staff   288 10  1 21:04 .
drwxr-xr-x  5 hide  staff   160  9 26 15:26 ..
-rw-r--r--@ 1 hide  staff  6148 10  1 21:03 .DS_Store
-rw-r--r--@ 1 hide  staff   262 10  1 20:54 Dockerfile
-rw-r--r--  1 hide  staff   941  9 23 11:12 docker-compose.yml
-rwxr-xr-x  1 hide  staff   541 10  1 21:04 manage.py
drwxr-xr-x  4 hide  staff   128 10  1 20:21 mysql
drwxr-xr-x  6 hide  staff   192 10  1 21:04 odaimaker
-rw-r--r--@ 1 hide  staff    19 10  1 19:28 requirements.txt

MySQLへ接続するための設定

データベースを作成しておいてください。

odaimaker.setings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST' : 'db',
        'NAME' : 'odaimaker',
        'USER' : 'root',
        'PASSWORD' : 'root',
        'PORT' : '3306',
        'OPTIONS': {
           'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
        },
    }
}

docker-compose.ymlで設定したrootのパスワードをセット。
‘host’は設定したコンテナ名なので今回は’db’

docker-compose up

dokcer-compose up

http://127.0.0.1:8000/ へアクセス。

Web開発
スポンサーリンク
hid3をフォローする
踊りながらWebサービスを個人開発している人のブログ