LoginSignup
4
3

More than 3 years have passed since last update.

Docker(Rails6Api + PostgreSQL + Nuxt.js).push(heroku.yml) = Hello!!SPA

Last updated at Posted at 2020-06-13

この記事の一部が動画になりました

Rails × Nuxt.js = HelloAPIApp - Youtube

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

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

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

完成イメージ

2020-06-13_11-23-41.png

作業手順

  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/

仕様

  • OS ... macを使用しています。
  • Docker for Mac ... インストール済みとします。
  • 使用しているDockerのバージョン ... v 19.03.8
  • Composeファイルにversion: 3.8を指定するので、Dockerはv 19.03以上を使用してください。

参考 Compose file version 3 reference - Docker docs

1.開発環境構築

開発環境の全体像

003_Docker_dev_intro.png

作業ディレクトリの作成

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

参考

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
「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
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
  • ブラウザにアクセス

  • コンテナの停止・削除・確認
「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

2020-06-12_17-47-50.png

  • これは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も表示されています。

2020-06-12_18-17-51.png

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

3.Herokuにpush

本番環境の全体像

production_image.png

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.png

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

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

2020-05-20_17-00-26.png

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

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

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

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.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.png

Herokuに基本的な環境変数をセット

  • コンテナを使わないRailsデプロイの場合、以下の環境変数が初期値として設定されている

  • LANG: en_US.UTF-8

    • ランゲージ(言語)
  • RACK_ENV: production

  • RAILS_ENV: production

    • レイルズ エンブ
    • Railsへ現在の環境を示す変数
  • RAILS_LOG_TO_STDOUT: enabled

    • ログ エスティディ(スタンダート) アウト
    • logを標準で出力するかどうかのフラグ
  • RAILS_SERVE_STATIC_FILES: enabled

  • コンテナ経由の場合、自分で環境変数を設定する必要がある。

  • 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に切り替わるので設定の必要なし

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

お疲れ様でした。

Twitter

4
3
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
4
3