0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

herokuからdockerのmysqlに移行(メモ書き)

Last updated at Posted at 2022-12-01

円安の影響でherokuの最安料金でさえ貧乏学生が支払う金額としてはキツくなってきたので移行を決意。この時の覚え書き。(MySQLスキーマ変更あたりは泥臭い処理をしてしまっている)

注意) 自分の操作より、もっと良いコマンド操作があると思います。

herokuから PostgreSQLデータをダンプ

dockerでPostgreSQLを起動

  • pg_dumpのためだけにdbを生ダウンロードしたくなかったので、dockerでpostgresを作りました。

(参考リンク🔽)

postgresのdocker コンテナ作成
docker run --name postgres -e POSTGRES_PASSWORD=617e330ed35242e6dca3dc8b0c5629efb0f9a90ecdec07ddc2e532d617ddd8e1 -e POSTGRES_INITDB_ARGS="--encoding=UTF8 --no-locale" -e TZ=Asia/Tokyo -p 5432:5432 -v $PWD:/my_data -d postgres

herokuのPostgresSQLデータをローカルにダンプ

(参考リンク🔽)

アプリ名検索 & herokuのデータベース情報を取得
heroku apps
heroku pg:credentials:url --app (アプリ名)
dockerのPostgreSQLに入る
docker exec -it postgres /bin/bash
データ & スキーマをダンプ
pg_dump --no-acl --no-owner -h (--.amazonaws.com) -U (ユーザ名) -v -a -(データベース名) > /my_data/postgres/(ダンプファイル名)
pg_dump --no-acl --no-owner -h (--.amazonaws.com) -U (ユーザ名) -v --schema-only -(データベース名) > /my_data/postgres/(ダンプファイル名)
  • ()の部分は 適当な値を入れる
  • コマンド実行ごとに パスワードを聞かれる
  • ダンプファイルをdocker外部に取り出したい場合、 『/my_data/欲しい場所』 にする。(PostgreSQLのコンテナ起動時に/my_dataをdocker外部のディレクトリに反映する設定をしているため)

MySQLに移行

ファイル内容

自分はMySQLに接続する側も dockerで連携させた。以下が dockerの例

docker-compose.yml
services:
  db:
    build:
      dockerfile: ./Dockerfile_sql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: user
      DB_USERNAME: user
      MYSQL_PASSWORD: user
      MYSQL_DATABASE: user
    ports:
      - 3306:3306
    volumes:
      - ./mysql:/var/lib/mysql
      - ./postgres:/my_data #移行用データ保存元
    

  api:
    build:
      content: .
      dockerfile: ./Dockerfile
    ports:
      - 8000:8000
    volumes:
      - .:/mysite
    tty: true # コンテナの永続(必要か分からないけど)

    depends_on:
      - db

Dockerfile
FROM python
ENV PYTHONUNBUFFERED 1
RUN mkdir /mysite
# docker内部で実行スタート場所を mysiteディレクトリに
WORKDIR /mysite
#現在のディレクトリ構成を dockerのmysiteフォルダに反映
Add . /mysite 
Dockerfile_sql
FROM mysql:5.7

RUN mkdir /my_data
# postgresに入れた シェルファイルでmysql設定を変更
Add /postgres/change_mysql_utf.sh /my_data/

RUN sh my_data/change_mysql_utf.sh 
change_mysql_utf.sh
#! /bin/sh

## utf8に変更 

sed -i -e "s/\[mysqld\]/\[mysqld\]\ncharacter-set-server=utf8\n/g" ../etc/my.cnf
sed -i -e "s/\[client\]/\[client\]\ndefault-character-set=utf8\n/g" ../etc/my.cnf

utf8に変更する理由

dockerのMySQL起動

  • apiを起動することで、db側も同時に立ち上げる
  • mysqlコンテナIDは docker psで 『(現在フォルダ名)-db-』 と書かれた左側
docker-compose run api
docker exec -it mysqlのコンテナID /bin/bash

(+a)エラー時など?

参考

mysqlフォルダの初期化
rm -r ./mysql
mkdir ./mysql
docker compose up --build -d
  • --buildで docker image生成から行う(しなくて大丈夫かも?)

buildしすぎた時の 実行停止 & キャッシュ削除?(良いのか分からないけどメモ)
docker-compose down --remove-orphans
  • upと runの違いがわかってないので用調べ ↑

Postgresのデータを微調整

以下、ひっかかった時に参考にしたサイト。これを利用し自作ファイルで微調整した。

基本処理
  • 自分はめんどくさくなって、schemaのtable宣言以外(ALTER TABLE関係)も徹底削除した。DB定義をよく変更していた方には良くないかも...

publicについて

timestamp関係

まとめサイト的

おまけ?(自作の変換コード)

MySQL操作

  • mysqlコンテナ内部でmysqlにログイン
    • mysql -u root -proot -h 127.0.0.1 -P 3306
    • rootユーザでしかログインできなかった
    • パスワード、ポート番号などはdocker-compose参考
その他のポイント?
  • djangoの runserverなどは 0.0.0.0を利用して動かさないとダメ
    • python manage.py runserver 0.0.0.0:8000
    • uvicorn main:app --reload --host 0.0.0.0 --port 8000

  • fastAPIの場合、URLは "mysql://root:root@db:3306/user?charset=utf8"
    • host名は docker-composeで作成した場合、サービス名で接続可能らしい?


自分のディレクトリ構成
  • docker-compose.yml
  • Dockerfile
  • Dockerfile_sql
  • * SQL変更pythonファイル
  • postgres
    • change_mysql_utf.sh
    • * ダンプデータ
    • data
      • * SQLのテーブル別tsvファイル

(自分の実際の環境設定と変更している面もあるので、エラーが見つかった場合質問していただけると誤りに気付けて助かります。)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?