内容に誤りがあったため、最初に公開したときから大幅に修正を加えました
なぜ書くか
docker公式のrailsのQuickstart のページに、Rails でYay railsする手順は書いてあります。 しかし実はこちらの手順ではDockerfile内でのユーザーがrootのままであるため、そのまま開発を進めようとすると問題が発生します。
hostは一般ユーザーですが、container内はroot のため、コンテナ内で作成したファイルをhost側で何の気なしに編集しようとすると、編集できないという問題です。 この問題はおそらくmacでは起こらないのですが、linuxでdockerをいじるときはあるあるです。 また、rails のように、フレームワークのエンジンがファイルを生成するような場合にcriticalな問題でもあります。host側でエディタを使いたい場合などは、フレームワークが生成したファイルの権限をいちいちsudo で書き換えて、、などする必要があります。面倒でやってられません
なお、host側で作成したファイルはcontainer側で問題なく動かせるので、実行環境としてdockerを使う分には、困ることは少ないでしょう。
今回はrailsなので、権限問題には何かしらの対処が必要です。ここでは素直にイメージ作成時にユーザーを作成する方針を取りました。 別の解決策として、rootless docker (dockerをユーザーモードで使う) も考えられます。ただ、それはそれで過去に何度かややこしい問題に遭遇してるので、今回はやめました。
Dockerfileを書く際にもいろいろ苦労したので、その結果を残します
また、上記docker公式のrailsのQuickstart は少々古く、rails のバージョンが5です。 railsのバージョンを6にして同様の手順をふもうとすると、さらに別の問題が発生します。 それは、Yarn not installed. というエラーで先に進めないことです。
Qiitaで見つかった記事によるとRails6でwebpackerが標準になったことにより、Railsアプリの開発環境にyarnのインストールが必要になったということです。
この yarnのインストール方法も、nodeを経由したりと選択肢が複数あり、いろいろ試行錯誤しました
おおまかにはquickstartと同じです。
Dockerfile
以下のようにDockerfileを作成します。
FROM ruby:2.7.4 ENV LANG C.UTF-8 ENV WORKSPACE=/usr/local/src RUN echo 'deb http://ftp.jp.debian.org/debian sid main ' >> /etc/apt/sources.list && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list # install bundler. RUN apt-get update && \ apt-get install -y vim less && \ apt-get install -y build-essential libpq-dev yarn postgresql-client && \ apt-get clean && \ rm -r /var/lib/apt/lists/* # create user and group. RUN groupadd -r --gid 1000 rails && \ useradd -m -r --uid 1000 --gid 1000 rails # create directory. RUN mkdir -p $WORKSPACE && \ chown -R rails:rails $WORKSPACE USER rails WORKDIR $WORKSPACE RUN gem install bundler # bundle install COPY --chown=rails:rails Gemfile $WORKSPACE/Gemfile RUN bundle install EXPOSE 3000 CMD ["rails", "server", "-b", "0.0.0.0"]
これがrailsのイメージになります ポイントは
- ruby 2.7 を使ってること
- yarnをインストールする部分
- Gemfileのコピー時に --chown オプションを指定していること
です。
Gemfile
Dockerfile内にでてきたGemfileはhost側に作成して、以下のようにしておきます
source 'https://rubygems.org' gem 'rails', '~>6'
docker-compose
DBも含めた全体像を理解したいと思うので、 docker-compose.yml を以下のように作成します
version: "3.9" services: db: image: postgres volumes: - database:/var/lib/postgresql/data environment: - POSTGRES_PASSWORD: password web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle install && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/myapp ports: - "3000:3000" depends_on: - db volumes: database:
特にポイントはないです。
ビルドとDB設定
quickstartの手順と同様、
docker-compose run --no-deps web rails new . --force --database=postgresql
作成されたconfig/database.yml に host, username, passwordを設定します。 こちらもquickstartと同様です。
host: db username: postgres password: password
docker-compose exec web bundle ex rails db:create
すると Yay! がみれます
開発も問題なく行えます
いじょう。
おわりに
開発ができるようになるまで結構苦労したのですが、結論は簡単なものですね。 database.yml の修正などは手動ではなく、ファイルのコピーなどでやるようにするのがよさそうです。
終わりなので苦労した部分もメモを残します
yarnのインストール
詳細は省きますが、nodeのインストール方法は複数あり、私にとってははまりポイントでした。
yarnはnpm 経由でインストールする方法が推奨されているようでした。
私が参考にしたサイトでは、npmはnodeをインストールすると依存パッケージとして同時にインストールされると書いてありましたが、nodeのインストール方法も複数あり、誤った方法でnodeをインストールするとnpm がついてきません。
最終的には、前述の通り、yarnを直接apt-getすることにしました
--chown でコピー時に権限を設定
bundle installする際に、Gemfileの権限がbundle installを実行するユーザーの書き込み可能な権限になっている必要があります。 bundle installは一般ユーザーで実行したいので、Gemfileの権限も合わせます
ちなみに、コピーしてから権限を付与しても一緒のはずです。
追記
bash/make 等は書いてないですがbaseのコードはこちらに作りました