LoginSignup
0
0

DockerでRailsの環境構築をした

Posted at

はじめに

DockerでRailsとMysqlが載った環境を用意してその上で何かを作ろうと思います。

手始めとして、以下の事を行っていきたいと思います。

  1. Docker上でRailsとMySQLを動かす

キーワード

Rails, Docker, make, Mysql

目次

  1. 環境
  2. 宣言
  3. やる
  4. まとめ
  5. 参考

環境

  • docker desktop: 20.10.22

でこいつらを動かせるようにしたい

  • rails: 7.0.4
  • ruby: 3.2
  • mysql: 8.0.3

宣言

公式が出している情報のみ引用します(エラー時は別)

使ってみる

Dockerについては前に自分がメモしていた。見返してもあんまり役に立たないですw

https://qiita.com/kajiyai/items/3e55844b9b39cb177128

公式がdockerにrailsをセットアップする方法を出しているが、postgresql版なので適宜読み替えつつ、追っていきます。

https://github.com/docker/awesome-compose/tree/master/official-documentation-samples/rails/

Dockerfileの定義

Dockerfileは環境の依存関係などを定義するときに呼び出すファイルです。rubyのバージョンだけ変更しました。

# syntax=docker/dockerfile:1
FROM ruby:3.2
RUN apt-get update -qq && apt-get install -y nodejs mysql-client
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]

FROM,RUN,WORKDIR,COPY等の命令が何をしているかはだいたいわかりますが、ENTRYPOINT, EXPOSE, CMD等のコマンドが何をしているかよくわからないので調べました。

ENTRYPOINTについて

そもそもエントリーポイントの意味が分かってなかったです。

エントリーポイントとは、プログラムを実行するうえで、プログラムやサブルーチンの実行を開始する場所のこと。プログラム全体のエントリーポイントとなる場所を含むルーチンがメインルーチンである。

https://ja.wikipedia.org/wiki/エントリーポイント#:~:text=エントリーポイントとは、プログラム,がメインルーチンである。

一番初めに処理されるプログラムを指定しているという事ですね。

EXPOSEについて

トランスポート層の設定のドキュメントとして機能するみたいです。実際にポートを開けるにはdocker runコマンドを叩こうとかいてあります。

プロトコルのデフォルトはTCPだけど、オプションでUDPも選べるよと書いてあります。

The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. You can specify whether the port listens on TCP or UDP, and the default is TCP if the protocol is not specified.

The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published. To actually publish the port when running the container, use the -p flag on docker run to publish and map one or more ports, or the -P flag to publish all exposed ports and map them to high-order ports.

https://docs.docker.com/engine/reference/builder/#expose

CMDについて

どうやらCMDとENTRYPOINTは奥が深そうです。

ココでは、IPアドレスを明示してrails serverコマンドを実行したいのね、と理解しておきます。

$ rails server -b '0.0.0.0'

https://railsdoc.com/page/rails_server

Dockerfileのための準備色々

Gemfileの作成

rails new を後のステップで実行するとすぐに更新されますが、vscodeを開き、Gemfileを一時的に作成します。

source 'https://rubygems.org'
gem 'rails', '~>7'
Gemfile.lockの作成
$ touch Gemfile.lock
docker-compose.ymlの作成

posgresql→mysqlに変更してます。

services:
  db:
    image: mysql:latest
    ports:
      - "13306:3306"
    volumes:
      - ./.data/db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

参考

https://hub.docker.com/_/mysql/

コンテナの実行

$ docker compose run --no-deps web rails new . --force --database=mysql

このコマンドを実行した所、次のようなエラーが生じた

ERROR [7/8] COPY entrypoint.sh /usr/bin/

failed to solve: failed to compute cache key: failed to calculate checksum of ref moby::****: "/entrypoint.sh": not found

entrypoint.shファイルをentorypoint.shと名付けていたゆえのエラーだった

再度エラーが

E: Package 'mysql-client' has no installation candidate

Dockerfileの3行目、mysql-clientをdefualt-mysql-clientに変更

RUN apt-get update -qq && apt-get install -y nodejs default-mysql-client

またまたエラーが

exec /usr/bin/entrypoint.sh: no such file or directory

そんなファイル無いよ

stackoverflowのスレ

https://stackoverflow.com/questions/38905135/why-wont-my-docker-entrypoint-sh-execute

改行コードが原因?

https://kakiblo.com/docker-windows/

試したこと

  • entrypoint.shファイルの改行コードをLFに変更した
  • entrypoint.shファイルの先頭行を#!bin/shに変更した
  • Dockerfileの10,11行目の/usr/binを/usr/local/binに変更した

動いた

参考: https://www.baeldung.com/docker-cant-connect-local-mysql

こちらのコマンドで—no-depsを指定しているのでコマンド実行後はファイルが作成されるだけ、が正しい挙動だと思われます

docker compose run はアドホックなタスクに使用するみたいです

$ docker compose run --no-deps web rails new . --force --database=mysql

なにはともあれGemfileが更新されたのでビルドします

$ docker compose build

rails仕様のディレクトリ構成が完成しました

DBを接続

何も変更せずにdocker compose up したらエラー

Can't connect to local MySQL server through socket '/run/mysqld/mysqld.sock' (2)

ローカルのMySQLサーバーと繋げないよ~と言ってそう

database.ymlのhostをlocalhostからdbに変更してみた

またエラー。今度はユーザ名とPWが違うと言ってそう

ActiveRecord::DatabaseConnectionError
There is an issue connecting to your database with your username/password, username: root.
Please check your database configuration to ensure the username/password are valid.

docker desktopのterminalから mysql -u root -pでも入れない

docker-compose.ymlファイルのdb:enfironment:にMYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORDを入力して、再ビルドしてみる

services:
  db:
    image: mysql:latest
    ports:
      - "13306:3306"
    volumes:
      - ./.data/db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

エラーが解決できないので質問を投げた。

https://qiita.com/kajiyai/questions/6bb978839a2b78c8ae03

Postgresqlに変更したらwelcomeページは動いた

まとめ

MySQLで動かそうとしましたが、動きませんでした

Postgresqlでは動きました

MySQLでなければならない理由はないのでPostgresqlで作っていこうかと思いますが、何が問題なのかはっきりせず、もやもやします。お詳しい方、コメントで教えて頂けると幸いです。

次は、以下の記事を元にmakeツールでdockerコマンドを整理してみたいと思います

https://beyondjapan.com/blog/2020/10/makefile-docker/

ではまた。

参考

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