Ruby
Rails
Docker


rails で Web アプリを作ってみよう!

Web アプリを作って、動かして、触って、デプロイしてみよう!


事前準備

docker , bundler はインストールしておいてね


docker


bundler


docker-compose.yml

Dockerfile

docker

をローカルにコピー

TODO: curl でダウンロードできるようにする


やってみよう!

$ mkdir rails_sample && cd rails_sample

$ cp -a ~/Download/Dockerfile ~/Download/docker-compose.yml ~/Download/docker .
remove `Gemfile.lock` in Dockerfile
$ bundle init
$ docker-compose run --rm web bundle exec rails new . -d mysql --skip-test

ここで今日のゴールを

https://rails-sample-fot-lt.herokuapp.com/users/sign_in

(今日はログインやらんけど)

ログインあり&デプロイありの、ハンズオンやりたいと思う人!

希望あれば日程調整しましょう

3時間ぐらい

うまくいけば30分

edit database.yml

  pool: <%= ENV.fetch('RAILS_MAX_THREADS') { 5 } %>

username: <%= ENV.fetch('MYSQL_USERNAME') { 'root' } %>
password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %>
host: <%= ENV.fetch('MYSQL_HOST') { '127.0.0.1' } %>
port: <%= ENV.fetch('MYSQL_PORT') { 3306 } %>

add Gemfile.lock in Dockerfile

$ docker-compose up

$ docker-compose exec web bin/rails g scaffold post content
$ docker-compose exec web bin/rails db:migrate


hands on メモ

$ mkcd rails_sample

$ cp -a ~/Download/Dockerfile ~/Download/docker-compose.yml ~/Download/docker .

remove Gemfile.lock in Dockerfile

$ bundle init

$ docker-compose run --rm web bundle exec rails new . -d mysql --skip-test
create remote repository
$ cp -a ~/Download/Gemfile .

edit database.yml


database.yml

  pool: <%= ENV.fetch('RAILS_MAX_THREADS') { 5 } %>

username: <%= ENV.fetch('MYSQL_USERNAME') { 'root' } %>
password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %>
host: <%= ENV.fetch('MYSQL_HOST') { '127.0.0.1' } %>
port: <%= ENV.fetch('MYSQL_PORT') { 3306 } %>

add Gemfile.lock in Dockerfile

$ docker-compose up

$ docker-compose exec web bundle install
$ docker-compose exec web rails generate simple_form:install
$ docker-compose exec web rails haml:erb2haml
$ docker-compose exec web rails g annotate:install
$ docker-compose exec web bin/rails g scaffold post content
$ docker-compose exec web bin/rails g scaffold user name
$ docker-compose exec web bin/rails db:migrate
$ docker-compose exec web bundle exec rails generate devise:install

add

    %p.notice= notice

%p.alert= alert

in app/views/layouts/application.html.haml

$ docker-compose exec web bundle exec rails g devise:views

$ docker-compose exec web rails generate devise user
$ docker-compose exec web bin/rails db:migrate

add before_action :authenticate_user! in app/controllers/posts_controller.rb and app/controllers/users_controller.rb

add root to: 'post#show' route.rb

access http://localhost:3000/users


heroku deploy

create app in gui

$ heroku login

$ heroku git:remote -a rails-sample-fot-lt
$ git push heroku master
$ heroku addons:create cleardb:ignite
$ heroku config | grep CLEARDB_DATABASE_URL

mysql://[username]:[password]@[hostname]/[db_name]?reconnect=true

$ heroku config:add DB_NAME="[db_name]"
$ heroku config:add DB_USERNAME="[username]"
$ heroku config:add DB_PASSWORD="[password]"
$ heroku config:add DB_HOSTNAME="[hostname]"
$ heroku config:add DB_PORT="3306"
$ heroku run rake db:migrate


コピー用


Dockerfile

FROM ruby:2.6.2

RUN apt-get update --fix-missing \
&& apt-get -y upgrade \
&& apt-get install -qq -y \
nodejs \
mysql-client \
&& apt-get autoremove -y \
&& apt-get clean all \
&& fc-cache -f -v

# Add dumb init to process system events
RUN wget https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 -O /usr/local/bin/dumb-init
RUN chmod +x /usr/local/bin/dumb-init

RUN gem update --system
RUN gem install bundler

WORKDIR /rails_sample
COPY Gemfile Gemfile.lock ./
RUN bundle install --jobs=4 --retry=3

COPY . .

EXPOSE 3000

# Start the main process.
CMD bin/rails server -b 0.0.0.0



docker-compose.yml

version: '3.7'

services:
db:
restart: always
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: password
ports:
- 3306:3306
volumes:
- ./docker/mysql/conf:/etc/mysql/conf.d:rw
- dbdata:/var/lib/mysql

web:
build: .
depends_on:
- db
volumes:
- .:/rails_sample
- "bundle:/usr/local/bundle"
environment:
- MYSQL_HOST=db
command: >
bash -c "
bundle install --quiet &&
docker/bin/start rails"
ports:
- 3000:3000

volumes:
bundle:
dbdata:



docker/mysql/conf/default_authentication.cnf

[mysqld]

default_authentication_plugin=mysql_native_password


docker/bin/rails

#!/bin/sh

docker-compose run --rm backend bin/rails "$@"



docker/bin/start

#!/bin/sh

if [ $# = 0 ]; then
echo "usage:"
echo " start rails: Start rails server"
echo " start rails recreate db: Start rails server recreate db"
echo " start sidekiq: Start sidekiq process"
echo " start sidekiq-web: Start sidekiq web server"
exit 1
fi

case "$1" in
"rails")
bundle exec rails tmp:pids:clear
bundle exec rails log:clear tmp:clear
bundle exec rails server --port 3000 --binding "0.0.0.0"
;;
"rails recreate db")
bundle exec rails tmp:pids:clear
bundle exec rails db:reset
bundle exec rails db:migrate
bundle exec rails log:clear tmp:clear
bundle exec rails server --port 3000 --binding "0.0.0.0"
;;
"rails migrate db")
bundle exec rails db:migrate
;;
"sidekiq")
bundle exec sidekiq
;;
"sidekiq-web")
bundle exec rackup --host "0.0.0.0" --port 9292 lib/sidekiq_web/config.ru
;;
esac