この記事の一部が動画になりました
Rails × Nuxt.js = HelloAPIApp - Youtube
この記事を完走すると作れるもの
Dockerを使ったRails6ApiとNuxt.jsのアプリケーションを構築します。
Nuxt.jsのボタンを押すとRailsから「Hello」が返されます。
完成イメージ
作業手順
- Dockerを使ってRails6とNuxt.jsの開発環境を構築します。
- Rails6とNuxt.jsがAPI通信をするアプリケーションを作成します。
- heroku.ymlを使ってRailsをHerokuにデプロイします。
- heroku.ymlを使ってNuxt.jsをHerokuにデプロイします。
デモアプリURL
このURLは予告なく変更・削除する場合があります。
https://nuxt-rails-v3-front.herokuapp.com/
仕様
- OS ... macを使用しています。
- Docker for Mac ... インストール済みとします。
- 使用しているDockerのバージョン ... v 19.03.8
- Composeファイルに
version: 3.8
を指定するので、Dockerはv 19.03以上を使用してください。
1.開発環境構築
開発環境の全体像
作業ディレクトリの作成
$ mkdir nuxt_rails_v3_dockerfile_test && cd $_
root $ git init
root $ mkdir {api,front}
root $ cd api
api $ touch {Dockerfile,Gemfile,Gemfile.lock}
api $ ls
Dockerfile Gemfile Gemfile.lock
api/Dockerfile
FROM ruby:2.7.1-alpine
ARG WORKDIR
ENV RUNTIME_PACKAGES="linux-headers libxml2-dev make gcc libc-dev nodejs tzdata postgresql-dev postgresql git" \
DEV_PACKAGES="build-base curl-dev" \
HOME=/${WORKDIR} \
LANG=C.UTF-8 \
TZ=Asia/Tokyo
# ENV test(このRUN命令は確認のためなので無くても良い)
RUN echo ${HOME}
WORKDIR ${HOME}
COPY Gemfile* ./
RUN apk update && \
apk upgrade && \
apk add --no-cache ${RUNTIME_PACKAGES} && \
apk add --virtual build-dependencies --no-cache ${DEV_PACKAGES} && \
bundle install -j4 && \
apk del build-dependencies
COPY . .
CMD ["rails", "server", "-b", "0.0.0.0"]
Dockerfile参考
Nuxt.js + Rails(API) on DockerのHello Worldするべ!
api/Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 6.0.0'
frontディレクトリの作業
api $ cd ../front
front $ touch Dockerfile
front/Dockerfile
FROM node:14.4.0-alpine
ARG WORKDIR
ARG CONTAINER_PORT
ENV HOME=/${WORKDIR} \
LANG=C.UTF-8 \
TZ=Asia/Tokyo \
HOST=0.0.0.0
# ENV check(このRUN命令は確認のためなので無くても良い)
RUN echo ${HOME}
RUN echo ${CONTAINER_PORT}
WORKDIR ${HOME}
EXPOSE ${CONTAINER_PORT}
rootディレクトリの作業
front $ cd ..
root $ touch {.gitignore,.env,docker-compose.yml}
root $ ls -a
. .git docker-compose.yml
.. .gitignore front .env api
.gitignore
/.env
.env
# commons
WORKDIR=app
CONTAINER_PORT=3000
API_PORT=3000
FRONT_PORT=8080
# db
POSTGRES_PASSWORD=password
docker-compose.yml
version: '3.8'
services:
db:
image: postgres:12.3-alpine
environment:
TZ: UTC
PGTZ: UTC
POSTGRES_PASSWORD: $POSTGRES_PASSWORD
volumes:
- ./api/tmp/db:/var/lib/postgresql/data
api:
build:
context: ./api
args:
WORKDIR: $WORKDIR
environment:
POSTGRES_PASSWORD: $POSTGRES_PASSWORD
volumes:
- ./api:/$WORKDIR
depends_on:
- db
ports:
- "$API_PORT:$CONTAINER_PORT"
front:
build:
context: ./front
args:
WORKDIR: $WORKDIR
CONTAINER_PORT: $CONTAINER_PORT
command: yarn run dev
volumes:
- ./front:/$WORKDIR
ports:
- "$FRONT_PORT:$CONTAINER_PORT"
depends_on:
- api
Dockerイメージを作る
root $ docker-compose build
# 成功
Successfully built af6dbf3f1f30
Successfully tagged nuxt_rails_v3_blogtest_front:latest
# 確認
root $ docker images
Railsアプリの作成
root $ docker-compose run --rm api rails new . -f -B -d postgresql --api
- run <任意オプション> <サービス名> <コマンド>... サービスに対してコマンドを実行する
- --rm (runオプション) ... コンテナstop時に自動でコンテナを削除する
- rails new . ... 今いるディレクトリ内でrailsアプリを作成する(新たなディレクトリを作成しない)
- -f (rails newオプション) ... ファイルが存在する場合に上書きする(Gemfileを対象としている)
- -B (rauls newオプション) bundle installをしない(後で再buildするので)
- -d (rails newオプション) ... 使用するデータベースを指定する
- --api ... APIモードのアプリケーションを作成する
参考
- Gemfileが書き変わり、ruby v2.7.1、Rails 6.0.0系が使用されていることを確認する
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.7.1'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3', '>= 6.0.3.1'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
...
-
Gemfileが書き変わったのでもう一度apiのDockerイメージを再ビルドする
-
公式ドキュメントにあるようにGemfileまたはDockerfileを書き換えた場合は再buildする、と覚えておきましょう。
参考
新しいGemfileを入手したので、イメージを再度ビルドする必要があります。(これと、GemfileまたはDockerfile への変更は、再構築が必要な唯一の場合です。)
root $ docker-compose build api
Rails DB設定
api/config/database.yml
default: &default
adapter: postgresql
encoding: unicode
host: db # 追加
username: postgres # 追加(デフォルトの名前)
password: <%= ENV["POSTGRES_PASSWORD"] %> # 追加
...
- 設定が完了したらDB作成コマンドを実行する(初回のみ)
root $ docker-compose run --rm api rails db:create
# 成功
Created database 'app_development'
Created database 'app_test'
Railsの起動を確認する
root $ docker-compose up api
-
ブラウザで確認 http://localhost:3000
-
コンテナの停止
「Control」 + 「C」
root $ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------
nuxt_rails_v3_blogtest_api_1 rails server -b 0.0.0.0 Exit 1
nuxt_rails_v3_blogtest_db_1 docker-entrypoint.sh postgres Up 5432/tcp
- 停止したコンテナを削除する
-
-f
オプション ... 削除しますか?の確認なしで削除する
root $ docker-compose rm -f
root $ docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------
nuxt_rails_v3_blogtest_db_1 docker-entrypoint.sh postgres Up 5432/tcp
- DBコンテナが削除できていない
- こんな時は
down
コマンドを実行する -
docker-compose down
... コンテナの停止と削除を同時に行う
root $ docker-compose down
root $ docker-compose ps
Name Command State Ports
------------------------------
【コラム】postgreSQLのパスワードを変更したい場合
- コンテナを起動
docker-compose up -d db
- postgreSQLの中に入る
docker-compose exec -u <ユーザー名> db psql
-
ここのユーザー名は指定がない限り「postgres」となります。
参考
-
ユーザーのパスワードを変更する
postgres=# ALTER USER <ユーザー名> WITH PASSWORD '新たなパスワード';
# 例
ALTER USER postgres WITH PASSWORD 'password';
- パスワードがセットされているか確認する
postgres=# SELECT * FROM pg_shadow;
# OK
usename | usesysid | passwd |
postgres | 10 |md532e12f215ba27cb750c9e093ce4b5127 |
- postgreSQLから抜ける
postgres=# \q
- 起動コンテナの停止・削除
docker-compose down
- 変更後はRailsのパスワードも変更しておきましょう
config/database.yml
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password: <新たなパスワード>
...
【コラム】終わり
Nuxt.jsアプリの作成
- Nuxt.jsアプリ作成コマンドの実行
root $ docker-compose run --rm front yarn create nuxt-app
Q,アプリ名はこれで良いですか? (Yes: Enter)
? Project name (app)
Q,アプリの説明はこれで良いですか? (Yes: Enter)
? Project description (My splendid Nuxt.js project)
Q,アプリの製作者はこれで良いですか? (自分の名前を記述 + Enter)
? Author name () andou
Q,JavaScriptとTypeScriptどっち使う? (JavaScript: Enter)
? Choose programming language (Use arrow keys)
❯ JavaScript
TypeScript
Q,パッケージマネージャーはどちらですか? (Yarn: Enter)
? Choose the package manager (Use arrow keys)
❯ Yarn
Npm
Q,CSSフレームワークはどれにしますか? (とりあえず使わない: None選択 + Enter)
? Choose UI framework (Use arrow keys)
❯ None
Ant Design Vue
...
Q,サーバーフレームワークはどれにしますか? (使わない: None選択 + Enter)
? Choose custom server framework (Use arrow keys)
❯ None (Recommended)
AdonisJs
...
Q,導入するモジュールを選択してください。 (Axios: Axios選択中にスペースkey + Enter)
? Choose Nuxt.js modules
❯◯ Axios
◯ Progressive Web App (PWA) Support
◯ DotEnv
Q,文法チェックツールを選択してください。 (ESLint: ESLint選択中にスペースkey + Enter)
? Choose linting tools
❯◯ ESLint
◯ Prettier
◯ Lint staged files
◯ StyleLint
Q,テストフレームワークを選択してください。 (使わない: None選択 + Enter)
? Choose test framework (Use arrow keys)
❯ None
Jest
AVA
# レンダリングモードをお選びください。 (Single Page App: Single Page Appに矢印 + Enter)
? Choose rendering mode (Use arrow keys)
Universal (SSR)
❯ Single Page App
Q,開発ツールをお選びください。 (使わない: そのままEnter)
Choose development tools
n)
❯◯ jsconfig.json (Recommended for VS Code)
◯ Semantic Pull Requests
# アプリ作成開始...
.
.
# アプリ完成
🎉 Successfully created project app
- アプリの起動確認
root $ docker-compose up front
-
ブラウザで確認 http://localhost:8080
-
コンテナの停止・削除
front停止:「Control」 + 「C」
api/db停止: docker-compose stop
削除: docker-compose rm -f
確認: docker-compose ps
2.Rails x Nuxt API
下準備
- docker-compose.ymlに環境変数を用意する
docker-compose.yml
api:
build:
context: ./api
args:
WORKDIR: $WORKDIR
environment:
POSTGRES_PASSWORD: $POSTGRES_PASSWORD
API_DOMAIN: "localhost:$FRONT_PORT" # 追加
...
front:
build:
context: ./front
args:
WORKDIR: $WORKDIR
CONTAINER_PORT: $CONTAINER_PORT
API_URL: "http://localhost:$API_PORT" # 追加
- forntのDockerfileに環境変数を受け取る設定をする
front/Dockerfile
FROM node:14.4.0-alpine
ARG WORKDIR
ARG CONTAINER_PORT
# 追加
ARG API_URL
ENV HOME=/${WORKDIR} \
LANG=C.UTF-8 \
TZ=Asia/Tokyo \
# \ 追記
HOST=0.0.0.0 \
# 追加
API_URL=${API_URL}
# ENV check(このRUN命令は確認のためなので無くても良い)
RUN echo ${HOME}
RUN echo ${CONTAINER_PORT}
# 追加
RUN echo ${API_URL}
WORKDIR ${HOME}
EXPOSE ${CONTAINER_PORT}
- Dockerfileを書き換えたので再ビルトする
root $ docker-compose build front
- これでRails、Nuxt.js共にAPI用の環境変数を参照できるようになった
RailsにHelloを返すAPIを作成
- helloコントローラーを作成する
root $ docker-compose run --rm api rails g controller api::v1::hello
# 成功
create app/controllers/api/v1/hello_controller.rb
invoke test_unit
create test/controllers/api/v1/hello_controller_test.rb
-
api::v1::hello
... 子ディレクトリのapi/v1内にherlloコントローラーを作成する -
テストファイルを作成しない
--skip-test-framewor
オプションは無くなった模様。参考
-
コントローラーに"Hello"を返すアクションを作成
api/app/controllers/api/v1/hello_controller.rb
class Api::V1::HelloController < ApplicationController
# 追加
def index
render json: "Hello"
end
end
- rootを追加する
api/config/routes.rb
Rails.application.routes.draw do
# 追加
namespace :api do
namespace :v1 do
# api test action
resources :hello, only:[:index]
end
end
end
- アクションを確認する
root $ docker-compose up api
-
ブラウザにアクセス
-
コンテナの停止・削除・確認
「Control」 + 「C」
root $ docker-compose down
root $ docker-compose ps
- Gitにpushしとく
Nuxt.js Axiosの設定を行う
- Axiosの共通設定ファイルを作成する
root $ cd front
front $ touch plugins/axios.js
front/plugins/axios.js
export default ({ $axios }) => {
// リクエストログ
$axios.onRequest((config) => {
console.log(config)
})
// レスポンスログ
$axios.onResponse((config) => {
console.log(config)
})
// エラーログ
$axios.onError((e) => {
console.log(e.response)
})
}
- このファイルを読み込むように設定
front/nuxt.config.js
...
plugins: [
'plugins/axios' // 追加
],
本番用にaxiosのベースURLを設定する
2020年6月23日 訂正
baseURLは、環境変数のAPI_URLを優先するため、ここの設定は必要ありませんでした。
baseURL: process.env.API_URLを削除しました。
front/nuxt.config.js
...
axios: {
// サーバーサイドで行うリクエストに使用されるURL
// baseURL: process.env.API_URL
// クライアントサイドで行うリクエストに使用されるURL(デフォルト: baseURL)
// browserBaseURL: <URL>
},
-
Nuxt.jsのSAPモードでAPI通信を行う場合は、クライアントからリクエストを飛ばすだけなので
browserBaseURL
にAPI_URLを設定します。 -
デフォルトのURLは
baseURL
です。 -
そこで今回はbaseURL
にAPI_URLを設定し、browserBaseURL
の値を変更するように設定しています。
Nuxt.jsにAPIリクエストボタンを作成
front/pages/index.vue
<template>
<div>
<button
type="button"
name="button"
@click="getMsg"
>
RailsからAPIを取得する
</button>
<div
v-for="(msg, i) in msgs"
:key="i"
>
{{ msg }}
</div>
</div>
</template>
<script>
export default {
data () {
return {
msgs: []
}
},
methods: {
getMsg () {
this.$axios.$get('/api/v1/hello')
.then(res => this.msgs.push(res))
}
}
}
</script>
- 準備完了。コンテナ起動
front $ cd ..
root $ docker-compose up
- http://localhost:8080にアクセス
- ボタンを押すとCORSエラーが
- これはhttp://localhost:8080 から http://localhost:3000 へ、別URLにリクエストを飛ばしているため起こるエラーです。
- Railsもいきなり知らないURLからリクエストが来たのでびっくりしてエラーを吐いたんでしょうね。
- Rails側にこのドメインのリクエストを許可する設定をしましょう。
Nuxt.jsのproxy設定でCORSエラーを回避できるようですが、コンテナ経由だとうまく設定できませんでした。今回はサーバー側に設定を行います。
- コンテナの停止・削除
root $ docker-compose down
RailsのCORSエラーに対応
api/Gemfile
# 26行目のコメント外す
gem 'rack-cors'
- GemfileはDockerfileに関連するファイルなので、再ビルドします。
- Gemfileを書き換えたら再ビルドと覚えておきましょう。
root $ docker-compose build api
# 確認
root $ docker-compose run --rm api bundle info rack-cors
# OK
* rack-cors (1.1.1)
...
- 設定ファイルを編集
- コメントを外して、
origins
の部分を書き換えます。
api/config/initializers/cors.rb
# Be sure to restart your server when you modify this file.
# Avoid CORS issues when API is called from the frontend app.
# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests.
# Read more: https://github.com/cyu/rack-cors
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins ENV["API_DOMAIN"] || ""
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
- 以上で完了。確認しよう
root $ docker-compose up
- レスポンスの成功を表す200が返ってきました。Helloも表示されています。
- コンテナの停止・削除
「Control」+「C」
root $ docker-compose down
- api、fornt、root全てをgit にpush
3.Herokuにpush
本番環境の全体像
Herokuに新規登録
-
First name ... 名前
-
Last name ... 名字
-
Email address ... メール
-
Company name ... 無記入でOK
-
Role ... Herokuを利用する目的
迷ったら、Hobbyist(趣味)、Professional Developer(プロフェショナル開発者)のどちらかでOK -
Country ... Japan
-
Primary development language ... 今回はRubyを選択
-
「Create Free Account」をクリック
-
メールフォルダを開きHerokuからのメールを確認
-
メールのリンクをクリックしてメール認証完了
-
次はパスワードの設定
文字、数字、記号を含む8文字以上のパスワード
Heroku CLIのインストール
-
macOSの「Download the Installer」のボタンをクリック
-
こんな注意事項が出てきた場合
-
macのシステム環境設定を開き => 「セキュリティとプライバシー」
-
"heroic.pkg"は開発元を確認できないため、使用がブロックされました。の横「このまま開く」のボタンをクリック
-
あとは手順に沿ってインストール
-
イントールできたか確認
-
どのディレクトリにいてもOKなので下記コマンドを実行
% heroku --version (もしくは -v)
heroku/7.39.5 darwin-x64 node-v12.16.2
Heroku用にpumaの設定
api/config/puma.rb
workers Integer(ENV.fetch("WEB_CONCURRENCY") { 2 })
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count
preload_app!
rackup DefaultRackup
port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
on_worker_boot do
ActiveRecord::Base.establish_connection
end
Rails用のheroku.yml
- api直下のheroku.ymlを作成
root $ touch api/heroku.yml
api/heroku.yml
2020年6月24日 訂正
HerokuCLIのプラグイン「manifest」を導入しないため、setupの記述は必要ありません。
削除しました。
「manifest」によるHerokuアプリケーションの作成は、こちらの記事をご覧ください。
# setup:
# addons:
# - plan: heroku-postgresql
# as: DATABASE
build:
docker:
web: Dockerfile
config:
WORKDIR: app
run:
web: bundle exec puma -C config/puma.rb
Herokuアプリの作成
- apiディレクトリに移動
root $ cd api
- Herokuにログイン
api $ heroku login
# Enterキー
heroku: Press any key to open up the browser to login or q to exit:
# 成功
Logging in... done
Logged in as <Heroku email>
- appの作成
api $ heroku create <app name>
# 例) heroku create my-app
# 成功
Creating ⬢ <app name>... done
https://<app name>.herokuapp.com/ | https://git.heroku.com/<app name>.git
- 確認
api $ heroku open
Herokuに基本的な環境変数をセット
-
コンテナを使わないRailsデプロイの場合、以下の環境変数が初期値として設定されている
-
LANG: en_US.UTF-8
- ランゲージ(言語)
-
RACK_ENV: production
- ラックエンブ
- Rackへ現在の環境を示す変数
- rack ... Ruby言語で開発されたhttp送受信処理を担当するモジュールのこと
- https://railsguides.jp/rails_on_rack.html
-
RAILS_ENV: production
- レイルズ エンブ
- Railsへ現在の環境を示す変数
-
RAILS_LOG_TO_STDOUT: enabled
- ログ エスティディ(スタンダート) アウト
- logを標準で出力するかどうかのフラグ
-
RAILS_SERVE_STATIC_FILES: enabled
- サーバー スタティック ファイルズ
- publicディレクトリからの静的ファイルの提供の有無を切り替えるフラグ
- https://devcenter.heroku.com/changelog-items/617
-
コンテナ経由の場合、自分で環境変数を設定する必要がある。
-
LANG、TZについてはDockerfileで設定しているため、Herokuに自動で設定される。
-
ここではそれ以外を設定する。
api $ heroku config:set RACK_ENV=production RAILS_ENV=production RAILS_LOG_TO_STDOUT=enabled RAILS_SERVE_STATIC_FILES=enabled
- 確認
api $ heroku config
# 成功
RACK_ENV: production
RAILS_ENV: production
RAILS_LOG_TO_STDOUT: enabled
RAILS_SERVE_STATIC_FILES: enabled
RailsアプリをHerokuにデプロイ
- Gitにコミット
api $ git add -A
api $ git commit -m "add_hello_api"
- heroku.yml経由でデプロイする場合はHerokuのstackをコンテナに変更する必要がある
api $ heroku stack:set container
- 確認
api $ heroku stack
# 成功
cedar-14
* container
heroku-16
heroku-18
- push
api $ git push heroku master
HerokuDB設定
- PostgreSQLのアドオンを追加
api $ heroku addons:create heroku-postgresql:hobby-dev
- 確認
api $ heroku addons
Add-on Plan Price State
──────────────────────────────────────────────── ───────── ───── ───────
heroku-postgresql (postgresql-dimensional-xxxxx) hobby-dev free created
- HerokuDB初期化
api $ heroku run rails db:migrate
DB初期化時のエラー
ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `rails credentials:edit`
-
これは「暗号化された
secret_key_base
が見れないぞ!開くための鍵をくれ。」というエラーです。 -
鍵は「api/config/master.key」にあります。
-
この「master.key」はGitの管理下に置かれていないので、本番環境になったとたんエラーとなったんですね。
-
このように、開発環境で動くのに本番環境ではエラーになることはこれからの開発で多々あります。まずGitの管理外ファイル周りを疑ってみてください。
Herokuにマスターキーを追加する
- 環境変数としてマスターキーを追加します。
- api/config/master.keyの値をコピーして
RAILS_MASTER_KEY
という変数に値をセットしてください。
api $ heroku config:set RAILS_MASTER_KEY=<master key>
# 間違った場合は値を入れ替えてもう一度setすればOK
api $ heroku config:set RAILS_MASTER_KEY=<new master key>
参考 Rails 5.2 で ActiveSupport::MessageEncryptor::InvalidMessage - Qiita
- もう一度DBの初期化を行う
api $ heroku run rails db:migrate
# 成功
Running rails db:migrate on ⬢ ...
Herokuタイムゾーンの確認
- Dockerfileで指定したタイムゾーンがHerokuに設定されているか確認
# Herokuアプリに入る
api $ heroku run sh
~$ date
# ISTになっていれば日本時間
Fri Jun 5 09:17:55 JST 2020
# 抜ける
~$ exit
Heroku PostgreSQLのタイムゾーンの確認
- PostgreSQLの名前確認
api $ heroku pg:info
...
# 名前
Add-on: postgresql-dimensional-xxxxx
- PostgreSQLに入る
api $ heroku pg:psql <PostgreSQLの名前>
# 例) heroku pg:psql postgresql-dimensional-xxxxx
# タイムゾーン確認
:DATABASE=> show timezone;
# OK
TimeZone
----------
Etc/UTC
(1 row)
# 抜ける
:DATABASE=> \q
Heroku postgresqlのタイムゾーンの考え方
Herokuアプリの確認
api $ heroku open
- トップページは「ページが見つかりません」になると思うので「/api/v1/hello」にアクセスする
- helloが表示されていれば成功
4.Nuxt.jsをHerokuにデプロイ
デプロイ用のDockerfileに変更
- デプロイ用にDockerfileを編集
front/Dockerfile
FROM node:14.4.0-alpine
ARG WORKDIR
ARG CONTAINER_PORT
ARG API_URL
ENV HOME=/${WORKDIR} \
LANG=C.UTF-8 \
TZ=Asia/Tokyo \
HOST=0.0.0.0 \
API_URL=${API_URL} \
# 追加
NPM_CONFIG_PRODUCTION=false
# ENV check(このRUN命令は確認のためなので無くても良い)
RUN echo ${HOME}
RUN echo ${CONTAINER_PORT}
RUN echo ${API_URL}
WORKDIR ${HOME}
# 追加
COPY package*.json ./
RUN yarn install
COPY . .
RUN yarn run build
# ここまで
EXPOSE ${CONTAINER_PORT}
-
Nuxt.jsのSPAモードでは、
heroku config:set
で設定した環境変数を参照できない。そこでDockerイメージ内で環境変数を設定し、nuxt build
することでNuxt.jsに環境変数を渡す -
NPM_CONFIG_PRODUCTION=false
... devDependenciesのパッケージもインストールするための環境変数 -
NODE_ENVは自動でproductionに切り替わるので設定の必要なし
-
COPY package*.json ./
... ローカルのpackageから始まる全てのファイルを、作業ディレクトリの直下にコピー
package.jsonとpackage-lock.jsonが対象になります。 -
RUN yarn install
...
ちょっと豆知識。筆者がコピペで間違えたトコ。
ネットでは、Alpineベースのnodeイメージでyarn
をインストールしている記事があります。
当初は何も疑わずyarnをインストールしていましたが、Alpineベースのnodeイメージには最初からyarnが入っています。
(この記事を含む)ネットの情報はすぐに当てにせず、自分のDockerfileと見比べて何が必要か考える癖をつけましょう。助けられた記事 alpine-linuxにyarnを入れる
Nuxt.js用のheroku.ymlを設定
- frontディレクトリに移動
api $ cd ../front
- heroku.ymlファイルの作成
front $ touch heroku.yml
front/heroku.yml
build:
docker:
web: Dockerfile
config:
WORKDIR: app
API_URL: <RailsアプリのURL>
# 例) API_URL: https://my-app.herokuapp.com
run:
web: yarn run start
Herokuアプリの作成
- Herokuにログイン
front $ heroku login
# Enterキー
heroku: Press any key to open up the browser to login or q to exit:
# 成功
Logging in... done
Logged in as <Heroku email>
- appの作成
front $ heroku create <app name>
Nuxt.jsアプリをHerokuにpush
- Gitの初期化
- Nuxt.jsアプリは.gitディレクトリが無いので初期化が必要
front $ git init
- Gitにコミット
front $ git add -A
front $ git commit -m "add_index.vue_hello_api"
- heroku.yml経由でデプロイする場合はHerokuのstackをコンテナに変更する必要がある
api $ heroku stack:set container
- エラーが出た場合
› Error: Missing required flag:
› -a, --app APP app to run command against
› See more help with --help
-
GitとHerokuアプリの紐付けがうまくできていないエラー。参照先が分からない。アプリ名を指定してくれ!と言われている。
-
アプリ名を指定するのも良いが、ここでは
git remote
にHerokuのURLを追加することでも解決する。 -
HerokuのGitURLを調べる
front $ heroku info -a <Herokuのアプリ名>
# 例) heroku info -a my-app-front
# このURLをコピー
Git URL: https://git.heroku.com/<Herokuのアプリ名>.git
- Git remoteに追加する
front $ git remote add heroku https://git.heroku.com/<Herokuのアプリ名>.git
- 確認する
front $ git remote -v
# 成功
heroku https://git.heroku.com/<Herokuのアプリ名>.git (fetch)
heroku https://git.heroku.com/<Herokuのアプリ名>.git (push)
- もう一度stackコマンドを実行
front $ heroku stack:set container
- 確認
front $ heroku stack
# 成功
cedar-14
* containe
- Nuxt.jsをHerokuにpush
front $ git push heroku master
- アプリを開く
front $ heroku open
RailsにAPIドメインをセットする
-
Nuxt.jsアプリのボタンを押すとCORSエラーが返ってくる。
-
これは、Rails側のcors設定に、本番用のドメインが入っていないために起こるエラー。
-
そこでRails環境変数をセットする
-
apiディレクトリに移動
front $ cd ../api
- 環境変数API_DOMAINをセット
api $ heroku config:set API_DOMAIN=<Nuxt.jsアプリのドメイン>
# 例) heroku config:set API_DOMAIN=my-app.herokuapp.com
- 確認(最終的なRailsの環境変数)
api $ heroku config
API_DOMAIN: <Nuxt.jsアプリのドメイン>
DATABASE_URL: <databaseのURL>
RACK_ENV: production
RAILS_ENV: production
RAILS_LOG_TO_STDOUT: enabled
RAILS_MASTER_KEY: <マスターキー>
RAILS_SERVE_STATIC_FILES: enabled
5.完成
これでDcokerを使ったRails6Api + Nuxt.jsのAPIアプリケーションが完成しました。
お疲れ様でした。