2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Ruby on Rails 7 + React を fly.io にデプロイした時のlog

Posted at

個人開発を始めるにあたりローカルの開発を久々に作ったその時のlog
fly.ioにもデプロイできるようにして公開したくなったらできるように準備するところまでやります

色々直したいところはあるので気が向いたら修正する

docker compose での開発環境作成

手元で動かして確認したいので docker compose で動くようにする

参考にした記事

ほとんど記事に記載されている通りrubyのバージョンとDBをpostgresqlに変更しています

下記のファイルを用意した

  • Dockerfile
  • compose.yaml
  • entrypoint.sh
  • Gemfile
  • Gemfile.lock

Dockerfileを作成する

FROM ruby:3.2.2

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 \
  && curl -fsSL https://deb.nodesource.com/setup_14.x | bash \
  && apt-get install -y nodejs cron \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* \
  && mkdir /app-name

RUN npm install --global yarn
RUN yarn install --network-timeout 600000

WORKDIR /app-name
COPY Gemfile /app-name/Gemfile

COPY Gemfile.lock /app-name/Gemfile.lock

RUN bundle install

COPY . /app-name

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"]
entrypoint.sh
#!/bin/bash
set -e

rm -f /app-name/tmp/pids/server.pid

exec "$@"

docker-compose.yml を作成する

compose.yaml
services:
  db:
    image: postgres
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    networks:
      - db-net
  web:
    build: .
    stdin_open: true
    command: /bin/sh -c "rm -f tmp/pids/server.pid && ./bin/dev"
    ports:
      - "3000:3000"
    depends_on:
      - db
    volumes:
      - .:/app-name
    networks:
      - web-net
      - db-net

networks:
  web-net: {}
  db-net: {}
source "https://rubygems.org"

ruby "3.2.2"

gem "rails", "~> 7.0.4"

Gemfile.lock は空のファイル作成するだけ

ファイルが準備できたらビルドする

docker-compose build

rails new をします
記事を参考にesbuild を指定しています

docker-compose run web rails new . --database=postgresql -a propshaft --javascript=esbuild

ビルドが終わったら database.yml の接続情報を編集する

config/database.yml
development:
  <<: *default
  database: diy_pc_rooms_development
  host: db
  username: <%= ENV['POSTGRES_USER'] %>
  password: <%= ENV['POSTGRES_PASSWORD'] %>

とりあえずあげてみる

docker compose up

db がないと怒られるのでcreateする

docker compose run web rails db:create

ここまででhttp://0.0.0.0:3000/にアクセスするとrailsの画面がでる

0.0.0.0_3000_.png

Reactを追加する

とりあえず "/" のパスを設定する

app/controllers/homes_controller.rb
class HomesController < ApplicationController
  def index
  end
end
config/routes.rb
Rails.application.routes.draw do
  root 'homes#index'
end
app/views/homes/index.html.erb
<h1>Homes#index</h1>
<p>Find me in app/views/homes/index.html.erb</p>

ここまでで一旦表示できるか/にアクセスして確認しておく

reactとreact-domを追加する

docker-compose run --rm web yarn add react react-dom

参考にした記事のようにrails new時にエラーは発生しなかった
またrails javascript:install:esbuild が実行されているように見えたので特にコマンドは実行する必要がなかった
ただpackage.jsonにbuildコマンドの追加は必要なので下記の記述を追加する

package.json
"scripts": {
    "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets"
}

これで下準備は終わりです

viewごとにReactをPropsを設定できるようにしていく
idとdataを使ってPropsを渡せるようにMount.tsxを追加する

app/javascript/Mount.tsx
import React from 'react'
import { createRoot } from 'react-dom/client'

const Mount = (Component, mountNodeId) => {
  const mountNode = document.getElementById(mountNodeId)
  const props = JSON.parse(mountNode.getAttribute("data"))
  createRoot(mountNode).render(<Component {...props} />)
}

export default Mount

indexで表示する簡単なcomponentsを作成する

app/javascript/components/Hello.tsx
import React from 'react'

const Hello = ({ name }) => <h1>Hello, {name}!</h1>

export default Hello
app/views/homes/index.html.erb
<%= content_tag :div, id: "hello", data: {name: "kiitan"}.to_json do %><% end %>

application.jsapplication.tsxに拡張子を変更し下記の記述を追加する

app/javascript/application.tsx
import Mount from './Mount'
import Hello from './components/Hello'

Mount(Hello, 'hello')

この状態で開発環境にアクセスすると Hello, kiitan! と表示されていればReactの表示ができています

fly.ioにデプロイしてみる

ここまではローカルのdocker環境で開発を進めてきました
今回fly.ioを使ってみたかったのでデプロイしてみる
ドキュメントを眺めながらやった

flyコマンドを入れる
brew で入れられるようなので自分はbrewで入れました

brew install flyctl

コマンドを打つとブラウザが開くのでログインできる

fly auth login

セットアップコマンドを実行する
アプリの名前やリージョンを聞かれるので選択していきます
今回はPostgresqlをりようするのでこちらを作る選択だけしておきます

fly launch

デプロイコマンドを実行する

fly deploy

デプロイが完了したら fly open で開くことができます

今のままではRuby on Railsのhostのエラーが発生します
エラー画面に書いているようにhostsを development.rb に追加します

config/environments/development.rb
config.hosts << "xxxx.fly.dev"

もう一度デプロイすると The asset 'application.js' was not found in the load path. が発生すると思います
これはyarn buildのコマンドをローカル環境ではoremanのProcfile.devにて実行するようになっていますがfly.ioでは実行されていないためです
そこで手っ取り早くDockerfileを修正してコマンドを走らせます

FROM ruby:3.2.2

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 \
  && curl -fsSL https://deb.nodesource.com/setup_14.x | bash \
  && apt-get install -y nodejs cron \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* \
  && mkdir /app-name

WORKDIR /app-name

# ここを追加
+ COPY package.json /app-name/package.json
+ COPY yarn.lock /app-name/yarn.lock
+ RUN npm install --global yarn
+ RUN yarn install --frozen-lockfile --network-timeout 600000

COPY Gemfile /app-name/Gemfile

COPY Gemfile.lock /app-name/Gemfile.lock

RUN bundle install

COPY . /app-name

COPY entrypoint.sh /usr/bin/

RUN chmod +x /usr/bin/entrypoint.sh
RUN yarn build

ENTRYPOINT ["entrypoint.sh"]

EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]

修正後再度デプロイすれば問題なく表示できるようになっています
一旦画面が表示できたので満足

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?