If you familiar with Docker Application Development, simply clone following repository.
$ git clone https://github.com/wnoguchi/template-rails-with-docker.git awesome-web-app Cloning into 'awesome-web-app'... remote: Counting objects: 9, done. remote: Compressing objects: 100% (7/7), done. remote: Total 9 (delta 1), reused 8 (delta 0), pack-reused 0 Unpacking objects: 100% (9/9), done.
then
cd awesome-web-app/ git ls-files -z | xargs -0 sed -i '' -e 's/myapp/awesome-web-app/g' rm -rf .git/
diff --git a/Dockerfile b/Dockerfile index 04c0d27..fcb3798 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,13 @@ FROM ruby:2.4 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs -RUN mkdir /myapp -WORKDIR /myapp -COPY Gemfile /myapp/Gemfile -COPY Gemfile.lock /myapp/Gemfile.lock +RUN mkdir /awesome-web-app +WORKDIR /awesome-web-app +COPY Gemfile /awesome-web-app/Gemfile +COPY Gemfile.lock /awesome-web-app/Gemfile.lock RUN echo 'install: --no-document' >> ~/.gemrc && \ echo 'update: --no-document' >> ~/.gemrc && \ cp ~/.gemrc /etc/gemrc && \ chmod uog+r /etc/gemrc RUN bundle install -j4 -COPY . /myapp +COPY . /awesome-web-app diff --git a/docker-compose.yml b/docker-compose.yml index 631c085..b3115a5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,11 +3,11 @@ services: db: image: postgres web: - image: myapp + image: awesome-web-app build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - - .:/myapp + - .:/awesome-web-app ports: - "3000:3000" depends_on:
上でやってることをイチからやっていきます。
まずは空ディレクトリを作って cd
する。
myapp
はアプリ名に置換。( awesome-web-app
とか)
mkdir myapp cd myapp
Dockerfile
を直下に作る。
FROM ruby:2.4 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN echo 'install: --no-document' >> ~/.gemrc && \ echo 'update: --no-document' >> ~/.gemrc && \ cp ~/.gemrc /etc/gemrc && \ chmod uog+r /etc/gemrc RUN bundle install -j4 COPY . /myapp
Bundlerで並列処理??bundle installを爆速で処理する方法。 - Qiita
-j4
大事。 4 並列で bundle install
を実行するということ。
今の最新をとってきます。
source 'https://rubygems.org' gem 'rails'
めんどくさい人向け
cat <<EOF >Gemfile source 'https://rubygems.org' gem 'rails' EOF
空の Gemfile.lock
を用意しておく。
touch Gemfile.lock
アプリを識別するタグ名は image
のところ書き換えて。
すなわち myapp
を awesome-web-app
に全置換。
version: '3' services: db: image: postgres web: image: myapp build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/myapp ports: - "3000:3000" depends_on: - db
$ ls -l total 24 -rw-r--r-- 1 wnoguchi staff 259 Feb 3 20:20 Dockerfile -rw-r--r-- 1 wnoguchi staff 43 Feb 3 20:30 Gemfile -rw-r--r-- 1 wnoguchi staff 0 Feb 3 20:30 Gemfile.lock -rw-r--r-- 1 wnoguchi staff 243 Feb 3 20:41 docker-compose.yml
いよいよ Rails アプリケーションを作成する。
docker-compose run web rails new . --force --database=postgresql
–force
で Gemfile
を上書きしています。
ひとしきり rails new
が終わったら コンテナイメージの再ビルドが必要です。
なぜならコンテナイメージ内の Gemfile
が古いままだからです。
docker-compose build
このあたりで一発コミットをかます。
Git をまだ設定していないって?
Gitをインストールしたら真っ先にやっておくべき初期設定 - Qiita
git config --global user.name "First-name Family-name" git config --global user.email "username@example.com" git config --global core.editor 'vim -c "set fenc=utf-8"' git config --global color.diff auto git config --global color.status auto git config --global color.branch auto git config --global push.default simple git config --global core.precomposeunicode true git config --global core.quotepath false
$ git config -l credential.helper=osxkeychain user.name=Wataru NOGUCHI user.email=wnoguchi@pg1x.com core.editor=vim -c "set fenc=utf-8" core.precomposeunicode=true core.quotepath=false color.diff=auto color.status=auto color.branch=auto push.default=simple filter.lfs.process=git-lfs filter-process filter.lfs.required=true filter.lfs.clean=git-lfs clean -- %f filter.lfs.smudge=git-lfs smudge -- %f core.repositoryformatversion=0 core.filemode=true core.bare=false core.logallrefupdates=true core.ignorecase=true
.gitignore
もちょっと使いやすく変えておく。
以下を追加する。
ぼくのかんがえたさいきょうの .gitignore - Qiita
# Temporary Files #--------------------------- # vim [._]*.s[a-w][a-z] [._]s[a-w][a-z] *.un~ Session.vim .netrwhist # Emacs .\#* # Backup files #--------------------------- *~ *.orig *.bak # yyyyMMdd *.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] # yyyyMMddHHmm *.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] # yyyyMMddHHmmss *.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] # OS dependent files #--------------------------- .DS_Store Thumbs.db # Bundler specific #--------------------------- /vendor/bundle/ /.bundle/ # Office specific ~$* *.tmp # Vagrant specific .vagrant/
$ git init Reinitialized existing Git repository in /Users/wnoguchi/repos/myapp/.git/ $ vim .gitignore $ git add -A $ git commit -m "Initial commit." [master (root-commit) 65fdcc1] Initial commit. 78 files changed, 1313 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 README.md create mode 100644 Rakefile create mode 100644 app/assets/config/manifest.js create mode 100644 app/assets/images/.keep create mode 100644 app/assets/javascripts/application.js create mode 100644 app/assets/javascripts/cable.js create mode 100644 app/assets/javascripts/channels/.keep create mode 100644 app/assets/stylesheets/application.css create mode 100644 app/channels/application_cable/channel.rb create mode 100644 app/channels/application_cable/connection.rb create mode 100644 app/controllers/application_controller.rb create mode 100644 app/controllers/concerns/.keep create mode 100644 app/helpers/application_helper.rb create mode 100644 app/jobs/application_job.rb create mode 100644 app/mailers/application_mailer.rb create mode 100644 app/models/application_record.rb create mode 100644 app/models/concerns/.keep create mode 100644 app/views/layouts/application.html.erb create mode 100644 app/views/layouts/mailer.html.erb create mode 100644 app/views/layouts/mailer.text.erb create mode 100755 bin/bundle create mode 100755 bin/rails create mode 100755 bin/rake create mode 100755 bin/setup create mode 100755 bin/spring create mode 100755 bin/update create mode 100755 bin/yarn create mode 100644 config.ru create mode 100644 config/application.rb create mode 100644 config/boot.rb create mode 100644 config/cable.yml create mode 100644 config/database.yml create mode 100644 config/environment.rb create mode 100644 config/environments/development.rb create mode 100644 config/environments/production.rb create mode 100644 config/environments/test.rb create mode 100644 config/initializers/application_controller_renderer.rb create mode 100644 config/initializers/assets.rb create mode 100644 config/initializers/backtrace_silencers.rb create mode 100644 config/initializers/cookies_serializer.rb create mode 100644 config/initializers/filter_parameter_logging.rb create mode 100644 config/initializers/inflections.rb create mode 100644 config/initializers/mime_types.rb create mode 100644 config/initializers/wrap_parameters.rb create mode 100644 config/locales/en.yml create mode 100644 config/puma.rb create mode 100644 config/routes.rb create mode 100644 config/secrets.yml create mode 100644 config/spring.rb create mode 100644 db/seeds.rb create mode 100644 docker-compose.yml create mode 100644 lib/assets/.keep create mode 100644 lib/tasks/.keep create mode 100644 log/.keep create mode 100644 package.json create mode 100644 public/404.html create mode 100644 public/422.html create mode 100644 public/500.html create mode 100644 public/apple-touch-icon-precomposed.png create mode 100644 public/apple-touch-icon.png create mode 100644 public/favicon.ico create mode 100644 public/robots.txt create mode 100644 test/application_system_test_case.rb create mode 100644 test/controllers/.keep create mode 100644 test/fixtures/.keep create mode 100644 test/fixtures/files/.keep create mode 100644 test/helpers/.keep create mode 100644 test/integration/.keep create mode 100644 test/mailers/.keep create mode 100644 test/models/.keep create mode 100644 test/system/.keep create mode 100644 test/test_helper.rb create mode 100644 tmp/.keep create mode 100644 vendor/.keep
default: &default adapter: postgresql encoding: unicode # For details on connection pooling, see Rails configuration guide # http://guides.rubyonrails.org/configuring.html#database-pooling pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> # (snip)
次のように追加する
default: &default adapter: postgresql encoding: unicode # For details on connection pooling, see Rails configuration guide # http://guides.rubyonrails.org/configuring.html#database-pooling pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> host: db username: postgres password: # (snip)
diff --git a/config/database.yml b/config/database.yml index 31181fd..385bb4d 100644 --- a/config/database.yml +++ b/config/database.yml @@ -20,6 +20,9 @@ default: &default # For details on connection pooling, see Rails configuration guide # http://guides.rubyonrails.org/configuring.html#database-pooling pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + host: db + username: postgres + password: development: <<: *default
いよいよ Rails とその関連のコンテナ(PostgreSQL)を起動します。
$ docker-compose up myapp_db_1 is up-to-date Creating myapp_web_1 ... done Attaching to myapp_db_1, myapp_web_1 db_1 | The files belonging to this database system will be owned by user "postgres". db_1 | This user must also own the server process. db_1 | db_1 | The database cluster will be initialized with locale "en_US.utf8". db_1 | The default database encoding has accordingly been set to "UTF8". db_1 | The default text search configuration will be set to "english". db_1 | db_1 | Data page checksums are disabled. db_1 | db_1 | fixing permissions on existing directory /var/lib/postgresql/data ... ok db_1 | creating subdirectories ... ok db_1 | selecting default max_connections ... 100 db_1 | selecting default shared_buffers ... 128MB db_1 | selecting dynamic shared memory implementation ... posix db_1 | creating configuration files ... ok db_1 | running bootstrap script ... ok db_1 | performing post-bootstrap initialization ... ok db_1 | syncing data to disk ... ok db_1 | db_1 | Success. You can now start the database server using: db_1 | db_1 | pg_ctl -D /var/lib/postgresql/data -l logfile start db_1 | db_1 | db_1 | WARNING: enabling "trust" authentication for local connections db_1 | You can change this by editing pg_hba.conf or using the option -A, or db_1 | --auth-local and --auth-host, the next time you run initdb. db_1 | **************************************************** db_1 | WARNING: No password has been set for the database. db_1 | This will allow anyone with access to the db_1 | Postgres port to access your database. In db_1 | Docker's default configuration, this is db_1 | effectively any other container on the same db_1 | system. db_1 | db_1 | Use "-e POSTGRES_PASSWORD=password" to set db_1 | it in "docker run". db_1 | **************************************************** db_1 | waiting for server to start....2017-12-06 03:28:24.625 UTC [41] LOG: listening on IPv4 address "127.0.0.1", port 5432 db_1 | 2017-12-06 03:28:24.625 UTC [41] LOG: could not bind IPv6 address "::1": Cannot assign requested address db_1 | 2017-12-06 03:28:24.625 UTC [41] HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry. db_1 | 2017-12-06 03:28:24.627 UTC [41] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" db_1 | 2017-12-06 03:28:24.636 UTC [42] LOG: database system was shut down at 2017-12-06 03:28:24 UTC db_1 | 2017-12-06 03:28:24.641 UTC [41] LOG: database system is ready to accept connections db_1 | done db_1 | server started db_1 | ALTER ROLE db_1 | db_1 | db_1 | /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/* db_1 | db_1 | 2017-12-06 03:28:24.759 UTC [41] LOG: received fast shutdown request db_1 | waiting for server to shut down....2017-12-06 03:28:24.761 UTC [41] LOG: aborting any active transactions db_1 | 2017-12-06 03:28:24.764 UTC [41] LOG: worker process: logical replication launcher (PID 48) exited with exit code 1 db_1 | 2017-12-06 03:28:24.765 UTC [43] LOG: shutting down db_1 | 2017-12-06 03:28:24.789 UTC [41] LOG: database system is shut down db_1 | done db_1 | server stopped db_1 | db_1 | PostgreSQL init process complete; ready for start up. db_1 | db_1 | 2017-12-06 03:28:24.870 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 db_1 | 2017-12-06 03:28:24.870 UTC [1] LOG: listening on IPv6 address "::", port 5432 db_1 | 2017-12-06 03:28:24.872 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" db_1 | 2017-12-06 03:28:24.882 UTC [59] LOG: database system was shut down at 2017-12-06 03:28:24 UTC db_1 | 2017-12-06 03:28:24.886 UTC [1] LOG: database system is ready to accept connections db_1 | 2017-12-06 04:20:09.867 UTC [1] LOG: received smart shutdown request db_1 | 2017-12-06 04:20:09.870 UTC [1] LOG: worker process: logical replication launcher (PID 65) exited with exit code 1 db_1 | 2017-12-06 04:20:09.871 UTC [60] LOG: shutting down db_1 | 2017-12-06 04:20:09.881 UTC [1] LOG: database system is shut down db_1 | 2018-02-03 11:55:12.200 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 db_1 | 2018-02-03 11:55:12.200 UTC [1] LOG: listening on IPv6 address "::", port 5432 db_1 | 2018-02-03 11:55:12.203 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" db_1 | 2018-02-03 11:55:12.216 UTC [24] LOG: database system was shut down at 2017-12-06 04:20:09 UTC db_1 | 2018-02-03 11:55:12.226 UTC [1] LOG: database system is ready to accept connections web_1 | => Booting Puma web_1 | => Rails 5.1.4 application starting in development web_1 | => Run `rails server -h` for more startup options web_1 | Puma starting in single mode... web_1 | * Version 3.11.2 (ruby 2.4.2-p198), codename: Love Song web_1 | * Min threads: 5, max threads: 5 web_1 | * Environment: development web_1 | * Listening on tcp://0.0.0.0:3000 web_1 | Use Ctrl-C to stop
ブラウザを開いて下記 URL を開く。
ターミナルには以下のようなログが流れるはずだ。
web_1 | Started GET "/" for 172.18.0.1 at 2018-02-03 12:52:26 +0000 web_1 | Cannot render console from 172.18.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255 web_1 | Processing by Rails::WelcomeController#index as HTML web_1 | Rendering /usr/local/bundle/gems/railties-5.1.4/lib/rails/templates/rails/welcome/index.html.erb web_1 | Rendered /usr/local/bundle/gems/railties-5.1.4/lib/rails/templates/rails/welcome/index.html.erb (5.0ms) web_1 | Completed 200 OK in 502ms (Views: 17.9ms)
% docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4fde53d3ee98 myapp "bundle exec rails s…" 4 minutes ago Up 5 minutes 0.0.0.0:3000->3000/tcp myapp_web_1 a2eadc8592b8 postgres "docker-entrypoint.s…" About an hour ago Up About an hour 5432/tcp amaknowledge_db_1 97a6bbebbe7e postgres "docker-entrypoint.s…" 8 weeks ago Up About an hour 5432/tcp myapp_db_1
➜ myapp git:(master) ✗ docker exec -it myapp_web_1 bash root@4fde53d3ee98:/myapp#
止めるときは Ctrl+C
してねって書いてあるけど、 Docker コンテナの場合はこれやっちゃダメ。
この場合はアプリケーションサーバ Puma の強制停止に相当するので pid ファイルが残ってしまう。
終了するときは別ターミナル開いて docker-compose down
するのが正しい。
正しい終了の仕方
$ docker-compose down Stopping myapp_web_1 ... done Stopping myapp_db_1 ... done Removing myapp_web_1 ... done Removing myapp_web_run_2 ... done Removing myapp_web_run_1 ... done Removing myapp_db_1 ... done Removing network myapp_default
間違って終了してしまったとき
すでに Rails のプロセスが起動していると勘違いしてコンテナが異常終了してしまう。
(snip) web_1 | => Booting Puma web_1 | => Rails 5.1.4 application starting in development web_1 | => Run `rails server -h` for more startup options web_1 | Puma starting in single mode... web_1 | * Version 3.11.2 (ruby 2.4.2-p198), codename: Love Song web_1 | * Min threads: 5, max threads: 5 web_1 | * Environment: development web_1 | * Listening on tcp://0.0.0.0:3000 web_1 | Use Ctrl-C to stop Killing myapp_web_1 ... done Killing myapp_db_1 ... done $ myapp git:(master) ✗ docker-compose up Starting myapp_db_1 ... done Starting myapp_web_1 ... done Attaching to myapp_db_1, myapp_web_1 db_1 | 2018-02-03 13:23:31.487 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 db_1 | 2018-02-03 13:23:31.487 UTC [1] LOG: listening on IPv6 address "::", port 5432 db_1 | 2018-02-03 13:23:31.490 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" db_1 | 2018-02-03 13:23:31.502 UTC [24] LOG: database system was interrupted; last known up at 2018-02-03 13:21:33 UTC db_1 | 2018-02-03 13:23:31.804 UTC [24] LOG: database system was not properly shut down; automatic recovery in progress db_1 | 2018-02-03 13:23:31.806 UTC [24] LOG: redo starts at 0/16349D8 db_1 | 2018-02-03 13:23:31.806 UTC [24] LOG: invalid record length at 0/1634B00: wanted 24, got 0 db_1 | 2018-02-03 13:23:31.806 UTC [24] LOG: redo done at 0/1634AC8 db_1 | 2018-02-03 13:23:31.806 UTC [24] LOG: last completed transaction was at log time 2018-02-03 13:21:33.703436+00 db_1 | 2018-02-03 13:23:31.819 UTC [1] LOG: database system is ready to accept connections web_1 | A server is already running. Check /myapp/tmp/pids/server.pid. web_1 | => Booting Puma web_1 | => Rails 5.1.4 application starting in development web_1 | => Run `rails server -h` for more startup options web_1 | Exiting myapp_web_1 exited with code 1 ^CERROR: Aborting.
You can also stop the application with Ctrl-C in the same shell in which you executed the docker-compose up. If you stop the app this way, and attempt to restart it, you might get the following error:
以下のようにする。
rm tmp/pids/server.pid
これで再度 docker-compose up
すればいい。
終了するときは別ターミナル開いて docker-compose down
。忘れずに。
$ docker-compose run web rake db:create Creating network "myapp_default" with the default driver Creating myapp_db_1 ... done Created database 'myapp_development' Created database 'myapp_test'
あとは普通の Rails の開発となんら変わりはしない。
docker-compose run web
をプレフィックスとしてやっていけばいいだけ。
よく使うコマンドを列挙しておく。
docker-compose up docker-compose down docker-compose run web rake db:create docker-compose run web rake db:migrate docker-compose run web rails generate scaffold question title:string description:string
あとは Rails Guide を読んどけばいいでしょう。