docker でアプリ環境構築３

[docker でアプリ環境構築２](https://qiita.com/flour_planaria/items/62995090136ae39f95ff) のつづき



## 初期設定の実施

前回の最後に手動で実行した migrate と collectstatic を docker-compose に組み込んで自動化してみる



## migrate の自動化



##### docker-compose の修正

```docker-compose.yml
  configure:
    image: test_test:latest
    container_name: app_config
    volumes:
      - ./test:/app
      - ./web/static:/static
      - ./logs/test:/app/logs
    command: ./wait-for-it.sh app_db:3306 --timeout=30 --strict -- ./entrypoint.sh
    depends_on:
      - db
      - test
```

docker-compose に後続のサービスとして configure を追加する



```
    image: test_test:latest
    container_name: app_config
    volumes:
      - ./test:/app
      - ./web/static:/static
      - ./logs/test:/app/logs
```

image として作成した test を使用する

volumes も合わせることで、configure で実行した内容を test 側でも利用できるように



```
command: ./wait-for-it.sh app_db:3306 --timeout=30 --strict -- ./entrypoint.sh
```

entrypoint.sh（後述）に migrate の実行を記載しそのまま実行してみたところ、データベースが存在しないためエラーが発生したため、wait-for-it.sh でサービスの起動を待っての実行としている

https://docs.docker.com/compose/startup-order/

https://github.com/vishnubob/wait-for-it

Dockerfile 内で git clone して実行しようとしたけど、うまくいかなかったので事前に wait-for-it.sh だけ test 直下に配置

ちなみに PyPi にも登録されていたので、こっちからやればよかったかなぁ（未検証）

https://pypi.org/project/wait-for-it/



```
depends_on:
      - db
      - test
```

データベースへの反映と test イメージを利用するため depends_on で処理順を指定



##### entrypoint の作成

初期設定実行ファイルとして entrypoint.sh を作成し、docker-compose 内から実行

```entrypoint.sh
#!/bin/sh

python ./manage.py makemigrations
python ./manage.py migrate

```

初期登録データができた場合もここに追記すればいいかなー



## collectstatic の自動化

entrypoint.sh に以下を追記

```entrypoint.sh
python ./manage.py collectstatic --noinput --clear

```

オプションとして、入力なしとクリアを付加している

https://docs.djangoproject.com/en/2.2/ref/contrib/staticfiles/

実行後、しばらくすると（データベースの起動、ファイルクリアがあるからか遅い？）反映される



## まとめ

変更後の各ファイルは以下の通り

```docker-compose.yml
version: '3'

volumes:
  db.volume:

services:

  db:
    image: mysql:8.0.17
    container_name: app_db
    ports:
      - 3306:3306
    volumes:
      - db.volume:/var/lib/mysql
      - ./db:/docker-entrypoint-initdb.d
    command: mysqld --default-authentication-plugin=mysql_native_password --skip-mysqlx
    environment:
      MYSQL_ROOT_PASSWORD: mysql_password
      MYSQL_DATABASE: manage
      TZ: 'Asia/Tokyo'

  test:
    build: ./test
    container_name: app_test
    volumes:
      - ./test:/app
      - ./web/static:/static
      - ./logs/test:/app/logs
    command: uwsgi --socket :8001 --module config.wsgi --logto /app/logs/uwsgi.log
    expose:
      - "8001"
    depends_on:
      - db

  configure:
    image: test_test:latest
    container_name: app_config
    volumes:
      - ./test:/app
      - ./web/static:/static
      - ./logs/test:/app/logs
    command: ./wait-for-it.sh app_db:3306 --timeout=30 --strict -- ./entrypoint.sh
    depends_on:
      - db
      - test

  web:
    image: nginx:1.17.3
    container_name: app_web
    ports:
      - "8080:80"
    volumes:
      - ./web/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./web/static:/static
      - ./logs/web:/var/log/nginx
    depends_on:
      - test

```

```entrypoint.sh
#!/bin/sh

python ./manage.py makemigrations
python ./manage.py migrate

python ./manage.py collectstatic --noinput --clear

```



[test]
├─db/
│  └─init.sql
├─test/
│  ├─config/
│  │  ├─__ init__.py
│  │  ├─settings.py
│  │  ├─urls.py
│  │  └─wsgi.py
│  ├─polls/
│  │  └─チュートリアルで作成した構成
│  ├─Dockerfile
│  ├─entrypoint.sh
│  ├─manage.py
│  ├─requirements.txt
│  └─wait-for-it.sh
├─web/
│  └─nginx.conf
├─.gitignore
└─docker-compose.yml

wait-for-it.sh の配置を忘れずに！

```
chmod +x test/entrypoint.sh
chmod +x test/wait-for-it.sh
```
Linux 環境の場合はsh に実行権限の付与が必要になる