いまさらDockerでRails(API)+Rails(worker)+SQS+MySQLの環境を構築してみた
皆さんこんにちは。
料理好きエンジニアの金子です。
普段はiOSの開発メインですが、あるときにRailsのAPIをローカル環境で動かす必要があり、その際に環境構築が結構大変だったので時間短縮を目指してDockerを使って構築してみました。
ちなみにDockerはいままで触ったことはありませんので初Dockerです。
今回はDocker for Macで構築してみました。
Docker for Macのインストール
Docker for Macはhomebrew-caskでインストールすると楽にできます。
brew cask install docker
docker-composeは便利だった
Docker単体でも環境構築できますが、Dockerは1コンテナ1プロセスと言われているのもあり、環境を構築するとなると複数コンテナの管理が必要になってきます。
複数コンテナの管理はdocker-composeを使うと楽です。
具体的には、各コンテナの設定値を1つのyamlファイルで管理でき、コンテナの起動や停止などをまとめて行うことができます。
Docker-composeは、Docker for Macをインストールすると使えるようになりますので、Docker for Macを使う場合別途インストールは不要です。
今回の構成では、docker-compose.ymlは以下のようになります。
version: '3.2' services: fake_sqs: image: feathj/fake-sqs container_name: fake_sqs_container ports: - "9494:9494" environment: VIRTUAL_HOST: "fake_sqs" networks: - default db: image: mysql container_name: db_container command: mysqld --default-authentication-plugin=mysql_native_password environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} networks: - default volumes: - type: bind source: ${DOCKER_VOLUME_PATH}/hoge-db target: /var/lib/mysql - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d api: build: context: . dockerfile: Dockerfile-dev container_name: api_container command: bundle exec rails s -p 3000 -b 0.0.0.0 ports: - "3000:3000" environment: RAILS_ENV: development AWS_REGION: ${HOGE_AWS_REGION} AWS_ACCESS_KEY_ID: ${HOGE_AWS_ACCESS_KEY_ID} AWS_SECRET_ACCESS_KEY: ${HOGE_AWS_SECRET_ACCESS_KEY} networks: - default volumes: - .:/app app: build: context: . dockerfile: Dockerfile-dev container_name: app_container command: bundle exec shoryuken -R -C config/shoryuken.yml environment: RAILS_ENV: development AWS_REGION: ${EAP_AWS_REGION} AWS_ACCESS_KEY_ID: ${EAP_AWS_ACCESS_KEY_ID} AWS_SECRET_ACCESS_KEY: ${EAP_AWS_SECRET_ACCESS_KEY} networks: - default volumes: - .:/app
docker-composeのファイルバージョン
version: ‘3.2’ というところは、docker-composeのファイル形式のバージョンを表しています。
設定によっては各バージョン間で書き方が違ってくる場合があります。
サービスの設定
Servicesにあるfake_sqs, db, api, appというところが各サービス用のコンテナです。
fake_sqsの設定解説
fake_sqs: image: feathj/fake-sqs container_name: fake_sqs_container ports: - "9494:9494" environment: VIRTUAL_HOST: "fake_sqs" networks: - default
今回構築する環境ではワーカーとしてshoryuken+SQSの構成のため、動作させるにはSQSが必要ですが、開発時はfake_sqsで代用することができます。
fake_sqsのDockerイメージが用意されているため、上記のようにイメージを指定して構築できます。
dbの設定解説
db: image: mysql container_name: db_container command: mysqld --default-authentication-plugin=mysql_native_password environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} networks: - default volumes: - type: bind source: ${DOCKER_VOLUME_PATH}/hoge-db target: /var/lib/mysql - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
DBサーバはDockerのMySQL公式イメージを利用して上記のように設定します。
2018/8/15時点ではMySQL8.0.12がインストールされるようですが、このバージョンは認証方式の違いでいろいろ問題がでるのでcommendのところで「mysql_native_password」を設定して調整しています。
Dockerのコンテナ内のデータはコンテナを落とすと消えてしまいます。
開発で使う場合それだと都合がわるいのですが、MySQL公式イメージには初回起動時にスクリプトを実行する機能があるのでそれを利用することで起動時にデータを投入することができます。
「docker-entrypoint-initdb.d」にスクリプトを入れておくと起動時に実行してくれるので、上記の設定ではローカルのディレクトリにマウントしてスクリプトがあれば起動時に実行できるようにしています。
ただ、データ量が多いと毎回実行するのも大変なので、一度投入したデータは継続して使えるようにvolumesを設定してMySQLのデータディレクトリをホストOSにマウントしています。
apiの設定解説
api: build: context: . dockerfile: Dockerfile-dev container_name: api_container command: bundle exec rails s -p 3000 -b 0.0.0.0 ports: - "3000:3000" environment: RAILS_ENV: development AWS_REGION: ${HOGE_AWS_REGION} AWS_ACCESS_KEY_ID: ${HOGE_AWS_ACCESS_KEY_ID} AWS_SECRET_ACCESS_KEY: ${HOGE_AWS_SECRET_ACCESS_KEY} networks: - default volumes: - .:/app
APIサーバはrailsなのでdocker公式イメージの中からrubyのバージョンを合わせたものを使います。
これは環境によってインストールするソフトが変わってくるのでDockerfileに別途定義しています。
FROM ruby:2.4.1 LABEL maintainer="https://github.com/lanchester/HogeFugaPiyo" \ description="Foo Bar Baz" ARG UID=991 ARG GID=991 ARG APPGROUP=webapp ARG APPUSER=webapp ENV APP_ROOT /app ENV LANG C.UTF-8 # 公開ポート EXPOSE 3000 RUN apt-get update && apt-get install -y nodejs build-essential libmagic-dev mysql-client libmysqlclient-dev # ユーザ追加と権限設定 RUN addgroup --gid ${GID} ${APPGROUP} && adduser --home ${APP_ROOT} --shell /bin/sh --disabled-login --gid ${GID} --uid ${UID} ${APPUSER} \ && mkdir -p ${APP_ROOT}/public/system ${APP_ROOT}/public/assets ${APP_ROOT}/public/packs \ && chown -R ${UID}:${GID} ${APP_ROOT}/public # ソースコードコピー COPY --chown=webapp:webapp . ${APP_ROOT} # ユーザ指定 USER ${UID}:${GID} # 作業ディレクトリ変更 WORKDIR ${APP_ROOT} RUN bundle install
appの設定解説
app: build: context: . dockerfile: Dockerfile-dev container_name: app_container command: bundle exec shoryuken -R -C config/shoryuken.yml environment: RAILS_ENV: development AWS_REGION: ${HOGE_AWS_REGION} AWS_ACCESS_KEY_ID: ${HOGE_AWS_ACCESS_KEY_ID} AWS_SECRET_ACCESS_KEY: ${HOGE_AWS_SECRET_ACCESS_KEY} networks: - default volumes: - .:/app
ワーカーはshoryukenを使用していますが、コードベースはAPIサーバと同じなので同じDockerfileを使用しています。
イメージのビルドとコンテナの起動
Docker-compose.ymlファイルを作ったら以下のコマンドでイメージを作成することができます。
docker-compose build
コンテナの起動は以下のコマンドで行います。
docker-compose up
コンテナの停止は以下のコマンドで行います。
docker-compose down
コンテナの状態を確認する
コンテナの状態を確認するのには以下のコマンドを実行します。
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e0ce6bb83def mysql "docker-entrypoint.s…" 22 hours ago Up 22 hours 3306/tcp db_container cccf28542f67 hoge_app "bundle exec shoryuk…" 22 hours ago Up 22 hours 3000/tcp app_container cf63832f327e feathj/fake-sqs "/bin/sh -c /start.sh" 22 hours ago Up 22 hours 0.0.0.0:9494->9494/tcp fake_sqs_container cb251b62456e hoge_api "bundle exec rails s…" 22 hours ago Up 22 hours 0.0.0.0:3000->3000/tcp api_container
コンテナ上でコマンドを実行する
コンテナを立ち上げた後、例えばDBサーバでMySQLのコマンドを使ってデータを操作する場合など、最初はsshで接続していろいろできると思っていましたが、よく考えたらdockerは1コンテナ1サービスであり、実際にsshdをdockerコンテナで動かすべきでないという議論もあるようでした。
コマンドを実行するのであれば以下のように実行することは可能です。
docker exec -it db_container mysql -uroot -p
上記のコマンドでMySQLクライアントで接続して対話的にコマンドを実行することは可能です。
コンテナ間での通信
同じdocker network内であれば名前解決できるため、APIのdatabase.ymlではホスト名を「db」と指定しています。
新しいことや難しい課題に挑戦することにやりがいを感じ、安定やぬるい事は退屈だと感じます。 考えるより先に手が動く、肉体派エンジニアで座右の銘は諸行無常。 大事なのは感性、プログラミングにおいても感覚で理解し、感覚で書きます。
TAG
- Android
- AWS
- Bitrise
- CodePipeline
- Firebase
- HTML
- iOS
- IoT
- JavaScript
- KPI
- Linux
- Mac
- Memcached
- MGRe
- MGReのゆるガチエンジニアブログ
- MySQL
- PHP
- PICK UP
- PR
- Python
- Ruby
- Ruby on Rails
- SEO
- Swift
- TIPS
- UI/UX
- VirtualBox
- Wantedly
- Windows
- アクセス解析
- イベントレポート
- エンジニアブログ
- ガジェット
- カスタマーサクセス
- サーバ技術
- サービス
- セキュリティ
- セミナー・展示会
- テクノロジー
- デザイン
- プレスリリース
- マーケティング施策
- マネジメント
- ラボ
- リーンスタートアップ
- 企画
- 会社紹介
- 会社紹介資料
- 勉強会
- 実績紹介
- 拡張性
- 採用
- 日常
- 書籍紹介
- 歓迎会
- 社内イベント
- 社員インタビュー
- 社長ブログ
- 視察
- 開発環境