(Docker+Rails6+Nuxt.js+PostgreSQL)=>Heroku 環境構築~デプロイまでの手順書
  • 2020.06.13に公開
  • 2020.06.24に更新
  • Udemy
  • 1. このカテゴリーの歩き方
  • No.4 / 4

この記事を完走すると作れるもの

Dockerを使ったRails6ApiとNuxt.jsのアプリケーションを構築します。

Nuxt.jsのボタンを押すとRailsから「Hello」が返されます。

完成イメージ

2020-06-13 11-23-41

この記事はお急ぎ用

この記事は、公開記事を作成するための下書きです。

そのためコード、コマンドの説明は記述しておりません。

お急ぎでアプリ構築を実感したい人向けの記事になりますのでご了承ください。

コードの詳細はここで公開予定です。今しばらくお待ちください。

作業手順

  1. Dockerを使ってRails6とNuxt.jsの開発環境を構築します。
  2. Rails6とNuxt.jsがAPI通信をするアプリケーションを作成します。
  3. heroku.ymlを使ってRailsをHerokuにデプロイします。
  4. heroku.ymlを使ってNuxt.jsをHerokuにデプロイします。

デモアプリURL

このURLは予告なく変更・削除する場合があります。

https://nuxt-rails-v3-front.herokuapp.com/

仕様

1.開発環境構築

開発環境の全体像

Docker_dev_intro

作業ディレクトリの作成

$ 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"]
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モードのアプリケーションを作成する

参考

Dockerコマンドライン・リファレンス

Railsドキュメント

Railsガイド

  • 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 への変更は、再構築が必要な唯一の場合です。)

    Docker docs

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」となります。

    参考

    PsotgreSQL - Docker Hub

  • ユーザーのパスワードを変更する

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オプションは無くなった模様。

    参考

    Railsドキュメント

  • コントローラーに"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
  • ブラウザにアクセス

    http://localhost:3000/api/v1/hello

  • コンテナの停止・削除・確認

「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の値を変更するように設定しています。

    参考 options - Axios

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エラーが

2020-06-12 17-44-21

  • これはhttp://localhost:8080 から http://localhost:3000 へ、別URLにリクエストを飛ばしているため起こるエラーです。

    Railsもいきなり知らないURLからリクエストが来たのでびっくりしてエラーを吐いたんでしょうね。

    Rails側にこのドメインのリクエストを許可する設定をしましょう。

Nuxt.jsのproxy設定でこのエラーを回避できるようですが、コンテナ経由だとうまく設定できませんでした。今回はサーバー側に設定を行います。

  • コンテナの停止・削除
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も表示されています。

2020-06-12 18-17-51

  • コンテナの停止・削除
「Control」+「C」
root $ docker-compose down
  • api、fornt、root全てをgit にpush

3.Herokuにpush

本番環境の全体像

production image

Herokuに新規登録

https://signup.heroku.com/login

  • 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のインストール

https://devcenter.heroku.com/articles/heroku-cli

  • macOSの「Download the Installer」のボタンをクリック

  • こんな注意事項が出てきた場合

2020-05-20 16-55-15

  • macのシステム環境設定を開き => 「セキュリティとプライバシー」

  • "heroic.pkg"は開発元を確認できないため、使用がブロックされました。の横「このまま開く」のボタンをクリック

2020-05-20 17-00-26

  • あとは手順に沿ってインストール

  • イントールできたか確認

  • どのディレクトリにいても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

参考 Puma Web Server を使用した Rails アプリケーションの展開 - Heroku

Rails用のheroku.yml

  • api直下のheroku.ymlを作成
root $ touch api/heroku.yml

2020年6月24日 訂正

HerokuCLIのプラグイン「manifest」を導入しないため、setupの記述は必要ありません。

削除しました。

setup経由のHerokuアプリケーションの作成は、こちらの記事をご覧ください。

api/heroku.yml
# setup部分は必要なし
# setup:
#   addons:
#     - plan: heroku-postgresql
#       as: DATABASE
build:
  docker:
    web: Dockerfile
  config:
    WORKDIR: app
run:
  web: bundle exec puma -C config/puma.rb

参考 heroku.ymlを使用したDockerイメージの構築 - Heroku

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
  • 成功

2020-06-13 08-51-22

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 Postgresのタイムゾーン設定を変更するにはどうすればよいですか?- Heroku

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のパッケージもインストールするための環境変数

    参考 Heroku へデプロイするには? - Nuxt.js

  • NODE_ENVは自動でproductionに切り替わるので設定の必要なし

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アプリケーションが完成しました。

お疲れ様でした。

エラーや記事の間違い、あと感想を聞かせてくれたら筆者は嬉しいです。

Twitterで待ってまーす。

あなたの力になれること
私自身が独学でプログラミングを勉強してきたので、一人で学び続ける苦しみは痛いほど分かります。そこで、当時の私がこんなのあったら良いのにな、と思っていたサービスを立ち上げました。周りに質問できる人がいない、答えの調べ方が分からない、ここを聞きたいだけなのにスクールは高額すぎる。そんな方に向けた単発・短期間メンターサービスを行っています。
独学プログラマのサービス
Udemyの投稿
1
  • このカテゴリーの歩き方
  • /
  • #01
【お知らせ】UdemyでRails × Nuxt.jsの動画を公開することになりました
2
  • このカテゴリーの歩き方
  • /
  • #02
アプリケーション仕様書
3
  • このカテゴリーの歩き方
  • /
  • #03
このカテゴリーの歩き方(まずはここをチェック)
4
  • このカテゴリーの歩き方
  • /
  • #04
(Docker+Rails6+Nuxt.js+PostgreSQL)=>Heroku 環境構築~デプロイまでの手順書
1
  • Docker入門
  • /
  • #01
Docker for Macをインストールする手順
2
  • Docker入門
  • /
  • #02
分かるDocker解説。仮想環境・コンテナ・Dockerイメージ・Dockerfileとは何か?
3
  • Docker入門
  • /
  • #03
分かるDocker解説。DockerComposeとは何か?
1
  • Dockerを使ったRails+Nuxt.js環境構築
  • /
  • #01
【Docker+Rails6+Nuxt.js】今回作成するアプリの開発環境の全体像を知ろう
2
  • Dockerを使ったRails+Nuxt.js環境構築
  • /
  • #02
【MacOS】Homebrew経由でGitをインストールする方法
3
  • Dockerを使ったRails+Nuxt.js環境構築
  • /
  • #03
Rails6を動かすAlpineベースのDockerfileを作成する(AlpineLinuxとは何か)
4
  • Dockerを使ったRails+Nuxt.js環境構築
  • /
  • #04
Nuxt.jsを動かすAlpineベースのDockerfileを作成する(C.UTF-8とは何か)
5
  • Dockerを使ったRails+Nuxt.js環境構築
  • /
  • #05
.envファイルを使ったdocker-compose.ymlの環境変数設計
6
  • Dockerを使ったRails+Nuxt.js環境構築
  • /
  • #06
Rails6・Nuxt.js・PostgreSQLを動かすdocker-compose.ymlファイルを作成する
7
  • Dockerを使ったRails+Nuxt.js環境構築
  • /
  • #07
docker-compose.ymlを使ってRails6を構築する(PostgreSQLパスワード変更方法)
8
  • Dockerを使ったRails+Nuxt.js環境構築
  • /
  • #08
docker-compose.ymlを使ってNuxt.jsを構築する
1
  • 複数プロジェクトのGit管理
  • /
  • #01
複数プロジェクトで行うGit管理の全体像を理解しよう(Gitサブモジュール解説)
2
  • 複数プロジェクトのGit管理
  • /
  • #02
【Git】既存の子ディレクトリをサブモジュール管理に変更する手順
3
  • 複数プロジェクトのGit管理
  • /
  • #03
【GitHub】秘密鍵の生成・公開鍵を追加・SSH接続するまでを画像で分かりやすく
4
  • 複数プロジェクトのGit管理
  • /
  • #04
【GitHub】リモートリポジトリの追加・サブモジュールのリンク設定を行う
1
  • RailsAPI×Nuxt.js初めてのAPI通信
  • /
  • #01
【Rails6】"Hello" jsonを返すコントローラを作成する
2
  • RailsAPI×Nuxt.js初めてのAPI通信
  • /
  • #02
【Nxut.js】axiosの初期設定を行う(baseURL・browserBaseURLを解説)
3
  • RailsAPI×Nuxt.js初めてのAPI通信
  • /
  • #03
【Rails6】Gem rack-corsを導入してCORS設定を行う(オリジン・CORSとは何か)
1
  • Heroku.ymlを使ったDockerデプロイ
  • /
  • #01
デプロイ準備。Herokuへ新規会員登録を行いHerokuCLIをインストールする
2
  • Heroku.ymlを使ったDockerデプロイ
  • /
  • #02
heroku.yml解説編。Docker環境のRails6をHerokuにデプロイする(1/2)
3
  • Heroku.ymlを使ったDockerデプロイ
  • /
  • #03
HerokuCLI-manifestのデプロイ解説編。Docker環境のRails6をHerokuにデプロイする(2/2)
4
  • Heroku.ymlを使ったDockerデプロイ
  • /
  • #04
Dockerfile解説編。Docker環境のNuxt.jsをHerokuにデプロイする(1/2)
5
  • Heroku.ymlを使ったDockerデプロイ
  • /
  • #05
デプロイ完結編。Docker環境のNuxt.jsをHerokuにデプロイする(2/2)
1
  • モデル開発事前準備
  • /
  • #01
【Rails6】application.rbの初期設定(タイムゾーン・I18n・Zeitwerk)
2
  • モデル開発事前準備
  • /
  • #02
【Rails6】モデル開発に必要なGemのインストールとHirb.enableの自動化
3
  • モデル開発事前準備
  • /
  • #03
【Docker+Rails】A server is already running. Check /tmp/pids/server.pidエラーの対応
4
  • モデル開発事前準備
  • /
  • #04
【Docker】<none>タグのイメージを一括削除する & Rails .gitignoreの編集
1
  • ユーザーモデル開発
  • /
  • #01
Railsユーザーモデル作成。テーブル設計・ユーザー認証設計を理解する
2
  • ユーザーモデル開発
  • /
  • #02
Railsユーザーモデルのバリデーション設定(has_secure_password解説)
3
  • ユーザーモデル開発
  • /
  • #03
Railsバリデーションエラーメッセージの日本語化(ja.yml設定方法)
4
  • ユーザーモデル開発
  • /
  • #04
EachValidatorクラスのカスタムバリデーション設定(Rails6/lib以下読込)
5
  • ユーザーモデル開発
  • /
  • #05
Rails環境ごとにSeedデータ切り替えるseeds.rbの書き方
6
  • ユーザーモデル開発
  • /
  • #06
Rails6から導入された並列テストを理解する
7
  • ユーザーモデル開発
  • /
  • #07
Railsユーザーモデルバリデーションテスティング(name/email/password)
8
  • ユーザーモデル開発
  • /
  • #08
Nuxt.jsからRailsのユーザーテーブルを取得しHerokuにデプロイする
1
  • Nuxt.jsフロント開発事前準備
  • /
  • #01
【Nuxt.js2.13超解説】バージョンアップ手順と6つの新機能+2つの変更点
2
  • Nuxt.jsフロント開発事前準備
  • /
  • #02
Docker AlpineベースのNode.js上で動くNuxt.jsにVuetifyを導入する
3
  • Nuxt.jsフロント開発事前準備
  • /
  • #03
VuetifyにカスタムCSSを導入してオリジナルブレイクポイントを作る
4
  • Nuxt.jsフロント開発事前準備
  • /
  • #04
Nuxt.jsにnuxt-i18nを導入して国際化に対応する
1
  • ログイン前のレイアウト構築
  • /
  • #01
Nuxt.jsのレイアウト・ページ・コンポーネントの役割を理解しよう
2
  • ログイン前のレイアウト構築
  • /
  • #02
Nuxt.js ウェルカムページを構成するコンポーネントファイル群を作成しよう(1/4)
3
  • ログイン前のレイアウト構築
  • /
  • #03
Nuxt.js ウェルカムページにアイキャッチ画像・アプリ名・メニューボタンを表示しよう(2/4)
4
  • ログイン前のレイアウト構築
  • /
  • #04
Nuxt.js addEventListenerでスクロールを検知しツールバーの色を変化させよう(3/4)
5
  • ログイン前のレイアウト構築
  • /
  • #05
Nuxt.js ウェルカムページをレスポンシブデザインに対応させよう(4/4)
6
  • ログイン前のレイアウト構築
  • /
  • #06
Nuxt.js 会員登録ページのレイアウトファイルを作成しよう(1/4)
7
  • ログイン前のレイアウト構築
  • /
  • #07
Nuxt.js 名前、メール、パスワードのコンポーネントファイルを作成しよう(2/4)
8
  • ログイン前のレイアウト構築
  • /
  • #08
Nuxt.js 親子コンポーネント間の双方向データバインディングを実装する(3/4)
9
  • ログイン前のレイアウト構築
  • /
  • #09
Nuxt.js Vuetifyのv-text-fieldを使った会員登録フォームのバリデーション設定(4/4)
10
  • ログイン前のレイアウト構築
  • /
  • #10
Nuxt.js ログインページ実装とHerokuデプロイまで(router. replaceとpushの違いとは)
1
  • ログイン後のレイアウト構築
  • /
  • #01
Nuxt.js ログイン後のツールバーを作成しよう(inject解説)
2
  • ログイン後のレイアウト構築
  • /
  • #02
Nuxt.js アカウントメニューページ・ログアウト機能を実装しよう(nuxt-child解説)
3
  • ログイン後のレイアウト構築
  • /
  • #03
Nuxt.js ログイン後のトップページにプロジェクト一覧を表示しよう
4
  • ログイン後のレイアウト構築
  • /
  • #04
Nuxt.js プロジェクトページにVuetifyのナビゲーションドロワーを追加しよう
5
  • ログイン後のレイアウト構築
  • /
  • #05
Nuxt.js paramsIDからプロジェクトを検索してVuexに保存しよう
1
  • サーバーサイドのログイン認証
  • /
  • #01
JWTとは何か?(ruby-jwtのインストール)
2
  • サーバーサイドのログイン認証
  • /
  • #02
【Rails×JWT】ログイン認証解説とJWT初期設定ファイルの作成
3
  • サーバーサイドのログイン認証
  • /
  • #03
【Rails×JWT】トークン発行とデコードを行うAuthTokenクラスの作成
4
  • サーバーサイドのログイン認証
  • /
  • #04
【Rails×JWT】 ログイン判定を行うAuthenticatorモジュールの作成
5
  • サーバーサイドのログイン認証
  • /
  • #05
【Rails×JWT】UserクラスからJWTを扱うTokenizableモジュールの作成
6
  • サーバーサイドのログイン認証
  • /
  • #06
【Rails×JWT】AuthTokenクラスとAuthenticatorモジュールをテストする
7
  • サーバーサイドのログイン認証
  • /
  • #07
【Rails×JWT】JWTをCookieに保存するログインコントローラーの実装
8
  • サーバーサイドのログイン認証
  • /
  • #08
【Rails×JWT】ログインコントローラーのテストとHerokuデプロイ
1
  • フロントエンドのログイン認証
  • /
  • #01
【Rails×Nuxt.js】クロスオリジン通信でのCookie共有設定
2
  • フロントエンドのログイン認証
  • /
  • #02
【Nuxt.js】Railsからのログイン成功レスポンスをVuexに保存する
3
  • フロントエンドのログイン認証
  • /
  • #03
【Nuxt.js】ローカルストレージの有効期限を暗号化する(crypto-js解説)
4
  • フロントエンドのログイン認証
  • /
  • #04
【Nuxt.js】JWT有効期限内のユーザーをログインしたままにする実装
5
  • フロントエンドのログイン認証
  • /
  • #05
【Nuxt.js】ログイン前後のリダイレクト処理をミドルウェアで実装する
6
  • フロントエンドのログイン認証
  • /
  • #06
【Nuxt.js】ログイン失敗時のトースターをグローバルイベントとして作成する
7
  • フロントエンドのログイン認証
  • /
  • #07
【Nuxt.js】エラーページを作成する
8
  • フロントエンドのログイン認証
  • /
  • #08
【Rails×Nuxt.js】デモプロジェクトの作成とHerokuデプロイ(ログイン認証完)
1
  • 本番環境への対応
  • /
  • #01
【Rails×Nuxt.js】SafariのクロスサイトCookie保存拒否に対応する
独学プログラマ
独学でも、ここまでできるってよ。
CONTACT
Nuxt.js制作のご依頼は下記メールアドレスまでお送りください。