Closed56

【django + MySql + Docker】環境構築から、GitHub ActionsでDB周りのドキュメントをSchemaSpyで作成→Slackに送信する検証

ピン留めされたアイテム
TatsukiTatsuki

ゴール

  • django + mysql + dockerの環境をローカルに構築する
  • 構築した環境をGithubにあげる
  • Github Actionを使ってプッシュされたタイミングで、SchemaSpyを使ってDB周りのドキュメントを生成する
  • 生成したドキュメントをSlackで共有する
TatsukiTatsuki
TatsukiTatsuki

[django-mysql-docker-test]
という名前の空フォルダ新規作成

中に[Dockerfile]というファイル作成

Dockerfile
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
TatsukiTatsuki

[Dockerfile]と同階層に[requiments.txt]ファイルを作成
mysqlclientは確かpythonでmysqlに接続するときに必要だった気がするので追加

requiements.txt
Django==3.2
mysqlclient
pylint-django
TatsukiTatsuki

[Dockerfile]と同階層に[docker-compose.yml]を追加
これはhttps://book-reviews.blog/build-django-mysql-environment-with-docker-compose/
を参考に設定
(ほぼ同じだが、MySqlのポートに3307を追加)

docker-compose.yml
version: '3'

services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: 'django'
      MYSQL_PASSWORD: 'django'
      MYSQL_DATABASE: 'django'
    ports:
      - 3306:3307
    volumes:
      - mysql:/var/lib/mysql
  web:
    build: .
    command: python3 manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    links:
      - db

volumes:
  mysql:
    driver: local
TatsukiTatsuki

ターミナルで下記を実行
これも参考ページそのまま

docker-compose run web django-admin.py startproject composeexample .
TatsukiTatsuki

コンテナが二つできる
web側動作していないけど、DB設定の誤りだから?
この後確認

TatsukiTatsuki

できたプロジェクトファイルの中にある[settings.py]のDATABASES設定を修正する
デフォルトではSQLiteになってた

settinggs.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django',
        'USER': 'django',
        'PASSWORD': 'django',
        'HOST': 'db',
        'PORT': 3306,
    }
}
TatsukiTatsuki

ターミナル上で何もエラーが出ていなければ
localhost:8000
にアクセス

ブラウザでデフォルトページが表示されていることを確認

TatsukiTatsuki

謎のコンテナがあることを確認。
とりあえず後で検証

TatsukiTatsuki

言語とタイムゾーンを日本にしたかったので、settings.pyを編集

settings.py
LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'

TatsukiTatsuki

dockerを一旦止めて、下記コマンドで再実行しておく
先程のコマンドと違って、起動中でも別コマンド実行可能なので

docker-compose -f docker-compose.yml up -d
TatsukiTatsuki

下記コマンドでDocker内に入る(新規作成フォルダ名を長くしたせいでコンテナ名が長い...)

docker exec -it django-mysql-docker-test_web_1 bash
TatsukiTatsuki

下記コマンドを実行してアプリを作成する

python manage.py startapp polls
TatsukiTatsuki

makemigrations → migrateの順で実行してDB変更情報を登録する

python manage.py makemigrations
python manage.py migrate
TatsukiTatsuki

DB情報を確認する必要があるかもだけど面倒なので割愛

TatsukiTatsuki

【Github Actions検証】
構築した環境をGithubにプッシュ
リポジトリは新規作成

TatsukiTatsuki

djangoのプロジェクトフォルダ内に[.github/workflow]フォルダを作成する
画像のようなフォルダ構成

TatsukiTatsuki

作成した[.github/workflow]フォルダ内に、[github-actions-demo.yml]ファイルを作成する
内容はチュートリアルページと同じにする

name: GitHub Actions Demo
on: [push]
jobs:
  Explore-GitHub-Actions:
    runs-on: ubuntu-latest
    steps:
      - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
      - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
      - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
      - name: Check out repository code
        uses: actions/checkout@v3
      - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
      - run: echo "🖥️ The workflow is now ready to test your code on the runner."
      - name: List files in the repository
        run: |
          ls ${{ github.workspace }}
      - run: echo "🍏 This job's status is ${{ job.status }}."
TatsukiTatsuki

ページによるとブランチを作成しろと書いてあるので、
ブランチ[feature/#1]を作成して、作成ブランチ上で、github-actions-demo.ymlファイルをプッシュする

TatsukiTatsuki

プッシュして、PR作成→マージまで実行したがGithub Actionには追加されず
再度 masterブランチで[test.txt]ファイルを追加してmasterブランチ上でプッシュ

TatsukiTatsuki

プッシュはできているが、actionsには追加されておらず

TatsukiTatsuki

フォルダ名誤っていたので修正して再プッシュ
修正前[workflow]
修正後[workflows]

TatsukiTatsuki

【Github actionでSchemaspyを使ってDBドキュメントを生成する】
やり方が検討つかないので予想
①Github上でDockerを起動
②mysqlのコンテナを対象に、Schemaspyを使ってドキュメント生成

この視点で調査

TatsukiTatsuki

まずローカルで動作することを確認するために[docker-compose.yml]を修正

docker-compose.yml
version: '3'

services:
  db:
    image: mysql:5.7
    container_name: test-mysql
    environment:
      MYSQL_HOST: 'mysqlhost'
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: 'django'
      MYSQL_PASSWORD: 'django'
      MYSQL_DATABASE: 'django'
    ports:
      - 3307:3306
    volumes:
      - mysql:/var/lib/mysql
  web:
    container_name: test-django
    build: .
    command: python3 manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    links:
      - db
  schemaspy:
    container_name: schemaspy
    image: schemaspy/schemaspy:6.1.0
    volumes:
      - ./schemaspy/output:/output
      - ./schemaspy/meta:/meta
    # image: schemaspy/schemaspy:snapshot
    # tty: true
    # volumes:
    #   - ./.dev/schemaspy/output:/output
    depends_on:
      - db
    command: >
      java -jar schemaspy.jar
      -t mysql
      -host db
      -port 3306
      -db django
      -u django
      -p django
      -s django
      -connprops useSSL\\=false

volumes:
  mysql:
    driver: local
TatsukiTatsuki

docker-compose起動
プロジェクトディレクトリに[schemaspy/output]というフォルダが作成されて、中のindex.htmlを確認
適切に出力されていることを確認

TatsukiTatsuki

これだとローカルだけで動作する...?
Github Action上では動作しないのでは?

TatsukiTatsuki

一旦新しいgithub actionのymlファイルを作成して、ローカルと同じようにdocker-compose up -dを叩いてみる

github-schemaspy.yml
name: GitHub Shemaspy test
on: [push]
jobs:
  schemaspy:
    runs-on: ubuntu-latest
    services:
        mysql:
          image: mysql:5.7
          options: >-
            --health-cmd "mysqladmin ping -h localhost"
            --health-interval 20s
            --health-timeout 10s
            --health-retries 10
          env:
            MYSQL_USER: django
            MYSQL_PASSWORD: django
          ports:
            - 3306
    steps:
        - uses: actions/checkout@v2
        - name: compose-run
        shell: bash
        run: |
          docker-compose up -d
TatsukiTatsuki

構文エラーなど色々出たので修正すると、とりあえずDocker-composeは実行できた

github-schemaspy.yml
name: GitHub Shemaspy test
on: [push]
jobs:
  schemaspy:
    runs-on: ubuntu-latest
    steps:
        - uses: actions/checkout@v2
        - name: compose-run
          shell: bash
          run: |
            docker-compose up -d
TatsukiTatsuki

これGithub上で作成された(はずの)schemaspy/outputフォルダを確認すれば良いのでは?
やり方調査

TatsukiTatsuki

フォルダの中身確認したけど、フォルダができていただけだった
そりゃそうか。migrateとかも何もしてない。
やるとしたら、
①docker-composeで起動
②django側のコンテナに入ってmigrate
③schemaspy実行
そんな感じだとできるか?

TatsukiTatsuki

上の①②③まで出来て、index.htmlが生成されていることを確認
あとは
①出力したoutputフォルダをzipで圧縮
②slackで送信
部分ができれば完成

TatsukiTatsuki

現時点でのコード

github-schemaspy.yml
name: GitHub Shemaspy test
on: [push]
jobs:
  schemaspy:
    runs-on: ubuntu-latest
    steps:
        - uses: actions/checkout@v2
        - name: file-check-init
          shell: bash
          run: |
            sudo mkdir -p schemaspy
            sudo mkdir -p schemaspy/output
            sudo chmod 777 schemaspy
            sudo chmod 777 schemaspy/output
            ls
        - name: compose-run
          shell: bash
          run: |
            docker-compose up -d
            sleep 60s
        - name: migrate
          shell: bash
          run: |
            docker exec -t test-django python manage.py migrate
            sleep 60s
        - name: compose-schemaspy
          shell: bash
          run: |
            docker-compose -f docker-compose.yml up --build schemaspy
            sleep 60s
        - name: file-check-1
          shell: bash
          run: |
            ls -a
        - name: file-check-2
          shell: bash
          run: |
            ls -a schemaspy/
            ls -a schemaspy/output/
        - name: file-check-3
          shell: bash
          run: |
            ls -a schemaspy/output/
TatsukiTatsuki
docker-compose.yml
version: '3'

services:
  db:
    image: mysql:5.7
    container_name: test-mysql
    environment:
      MYSQL_HOST: 'mysqlhost'
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: 'django'
      MYSQL_PASSWORD: 'django'
      MYSQL_DATABASE: 'django'
    ports:
      - 3307:3306
    volumes:
      - mysql:/var/lib/mysql
  web:
    container_name: test-django
    build: .
    command: python3 manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    links:
      - db
  schemaspy:
    container_name: schemaspy
    image: schemaspy/schemaspy:6.1.0
    volumes:
      - ./schemaspy/output:/output
      - ./schemaspy/meta:/meta
    # image: schemaspy/schemaspy:snapshot
    # tty: true
    # volumes:
    #   - ./.dev/schemaspy/output:/output
    depends_on:
      - db
    command: >
      java -jar schemaspy.jar
      -t mysql
      -host db
      -port 3306
      -db django
      -u django
      -p django
      -s django
      -connprops useSSL\\=false

volumes:
  mysql:
    driver: local
  
  

TatsukiTatsuki

【ここから二日目】
残作業
・出力したschemaspy/outputフォルダをzipに圧縮する
・zipファイルをslackで送信する

TatsukiTatsuki

【zipファイルに圧縮】
昨日のgithub-schemaspy.ymlの最後に下記を追記するだけ

- uses: montudor/action-zip@v0.1.1
  with:
    args: zip -qq -r schemaspy/output.zip schemaspy/output

args: zip -qq -r 〇〇.zip △△
 ○○ : zipファイルに圧縮した後のファイルパス
 △△ : zipファイルに圧縮する対象のフォルダ/ファイルパス

TatsukiTatsuki

【slackに送信】
・まずtokenの準備をする必要がある
 https://api.slack.com/apps にアクセスして[Create new app]→[From scratch]の順で選択
 アプリの名前を適当に決めて、[Pick a workspace to develop your app in:]は自分のワークスペースを選択
  (ワークスペースが表示されないときにslackのログインアカウントが違うかも?)

TatsukiTatsuki

下にスクロールして、[Scopes]の[BOT Token Scopes]で
・chat:wirte
・files:write
を追加する

TatsukiTatsuki

上にスクロールして、[OAuth Tokens for Your Workspace]で[Install to workspace]を選択
表示された画面で[許可する]を選択する
すると、画面にslackのtokenが表示されるのでコピーしておく

TatsukiTatsuki

slackから、
対象チャンネルに移動して、チャンネル名の部分をクリック
表示されるモーダルから[インテグレーション]のAppから作成したアプリを追加する

TatsukiTatsuki

作成したtokenは、github上で環境変数として持っておく
【やり方】
githubの対象リポジトリから、
[Settings]→[Secrets]→[Actions]→[New repository]を選択する
・Name : お好みの名前 (ここで設定した名称を後ほどGithub actionで設定する)
・Value : slackのtoken
保存

TatsukiTatsuki

github actionを編集する
末尾に下記を追加

github-schemaspy.yml
- name: Upload to slack channel
  uses: adrey/slack-file-upload-action@master
    with:
      token: ${{ secrets.SLACK_TOKEN }}
      path: schemaspy/output.zip
      channel: github-actions-test

withの中身
token : githubの環境変数として保持したslackのtoken(Nameで指定した名称)
path : 送信するファイル名
channel : 送信するファイル名(作成したAppを追加したチャンネル)

TatsukiTatsuki

プッシュすると、作成したファイルが送信されていることを確認できる

TatsukiTatsuki

とりあえずやりたいことはできた!

【残課題】
・docker-compose.ymlに追加したくない
  (開発には不要)

TatsukiTatsuki

【docker-compose.ymlにschemaspyのコンテナを作成せずになんとかする】
local上でうまく動作したコマンドメモ

docker run -v "$PWD/schemaspy:/output" --net="host" schemaspy/schemaspy:snapshot -t mysql -host localhost:3307 -db django -u django -p django -s django
このスクラップは2022/10/30にクローズされました