前書き
railsとvue.jsを同一コンテナ内で環境構築することはやったことがあったんですが、フロントエンドとバックエンドのコンテナを分けるのが最近のトレンドだと耳にしたのでHelloWorldに挑戦してみました!
こちらの記事を参考にさせていただきました!ありがとうございました!
参考→https://qiita.com/at-946/items/08de3c9d7611f62b1894
postgresqlからmysql、nuxt.jsをnpmからyarn、railsのコンテナをalpineからdebianに変更しています。
今回作る環境
ruby:2.6.5
rails:6.0.3
mysql:8.0
nuxt.js(yarn)
vuetify
コンテナの準備
ディレクトリ構成
/
|--front/
| |--Dockerfile
|--back/
| |--Dockerfile
| |--Gemfile
| |--Gemfile.lock #空ファイル
| |--entrypoint.sh
|--docker-compose.yml
フロントコンテナ内のDockerfile
FROM node:12.5.0-alpine
ENV HOME="/myapp" \
LANG=C.UTF-8 \
TZ=Asia/Tokyo
WORKDIR ${HOME}
RUN apk update && \
apk upgrade && \
npm install -g npm && \
npm install -g @vue/cli
ENV HOST 0.0.0.0
EXPOSE 3000
バックコンテナ内のDockerfile
FROM ruby:2.6.5
RUN 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 \
&& apt-get update -qq \
&& apt-get install -y nodejs yarn \
&& mkdir /myapp
ENV HOME="/myapp" \
LANG=C.UTF-8 \
TZ=Asia/Tokyo
WORKDIR ${HOME}
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . ${HOME}
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 6.0.3', '>= 6.0.3.1'
# !/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
version: '3'
services:
db:
container_name: db
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
# 3307にしているのは筆者の環境では3306がpc自体のMySQLで使われているためです。3306:3306の方がいいかもです。
ports:
- '3307:3306'
command: --default-authentication-plugin=mysql_native_password
volumes:
- mysql-data:/var/lib/mysql
back:
container_name: back
build: back/
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- ./back:/myapp
ports:
- "3000:3000"
depends_on:
- db
stdin_open: true
tty: true
command: bundle exec rails server -b 0.0.0.0
front:
container_name: front
build: front/
command: yarn dev
volumes:
- ./front:/myapp
ports:
- 8080:3000
#depends_onでbackコンテナへのリンクを張っています。
depends_on:
- back
volumes:
mysql-data:
driver: local
ここまで写し終わったら
$ docker-compose build
これでdockerimageが作成され、コンテナの準備ができました!
nuxt.jsのHelloWorld
参考記事とほとんど変わらないので書くのがはばかられますが、少し違うので一応書いておきます。
まずはnuxt.jsのアプリを作成します。
途中の選択画面でエンターだけでなくスペースを押す必要がある項目もあるので注意してください。
$ docker-compose run --rm front npx create-nuxt-app
? Project name --> myapp # アプリ名
? Project description --> myapp # アプリの説明
? Author name --> me # アプリの作成者
? Choose the package manager --> Yarn
? Choose UI framework --> Vuetify
? Choose custom server framework --> None
? Choose Nuxt.js modules --> Axios
? Choose linting tools --> -
? Choose test framework --> None
? Choose rendering mode --> Universal (SSR)
これでnuxtアプリの完成です!
フロントコンテナを立ち上げて確認してみましょう!
$ docker-compose up front
http://localhost:8080
にアクセスしていい感じになってたらいい感じです。(語彙)
(参考)ホットリロードがうまくいかない時は冒頭の参考記事に解決法が記載されているのでそちらを参考にしてください。
→ https://qiita.com/at-946/items/08de3c9d7611f62b1894
Rails(Api)のHelloWorld
apiモードでrailsアプリを作ります。
$ docker-compose run --rm back rails new . -f -d mysql --api
次にDBを接続します。
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV.fetch("MYSQL_USERNAME", "root") %>
password: <%= ENV.fetch("MYSQL_PASSWORD", "password") %>
host: <%= ENV.fetch("MYSQL_HOST", "db") %>
ドメイン許可の設定をします。行頭に追記してください。
(ここに2日かかりました。これを書きたいがためにこの記事を書いたと言っても過言ではないです。)
Rails.application.config.hosts << 'back'
## 省略##
以降は参考記事と全く同じなので省略します。(サボれるところはサボる主義です。)
gitの設定
axiosでpostできたら、次にgitの設定をします。
railsはnewするときにgit initしてしまうのでbackディレクトリだけgit管理される状況になってしまいます。
$ cd ./back
$ sudo rm -rf .git
$ cd ..
sudoはいらないかもです。
この後に
$ git init
を打って完了です。
セキュリティ的にいいのかはわからないんですが、
#.nuxt
#dist
#sw.*
#node_modules/
#jspm_packages/
と、この5つをコメントアウトしておかないと他のパソコンでdocker-compose upが使えなかったので参考にしてみてください。
あとがき
いやー、ハマりましたね。ただやっぱなんとなくこの構成かっこいい、、かっこよくない?
というわけで参考になれば嬉しいです。よろしければLGTMお願いします!(露骨な媚び)
それではまた!