Quickstart: Compose and Rails

预计阅读时间:8分钟

本快速入门指南向您展示了如何使用 Docker Compose 设置和运行 Rails/PostgreSQL 应用程序. 在开始之前,安装 Compose .

Define the project

首先设置构建应用程序所需的文件. 该应用程序将在包含其依赖项的 Docker 容器中运行. 使用名为Dockerfile的文件定义依赖项. 首先,Dockerfile 包括:

# syntax=docker/dockerfile:1
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]

这会将您的应用程序代码放入一个镜像中,该镜像构建一个包含 Ruby、Bundler 和所有依赖项的容器. 有关如何编写 Dockerfile 的更多信息,请参阅Docker 用户指南Dockerfile 参考.

接下来,打开一个编辑器并创建一个仅加载 Rails 的引导程序Gemfile . 这将很快被rails new覆盖.

source 'https://rubygems.org'
gem 'rails', '~>5'

创建一个空的Gemfile.lock文件来构建我们的Dockerfile .

$ touch Gemfile.lock

接下来,提供一个入口点脚本来修复特定于 Rails 的问题,该问题会在某个server.pid文件预先存在时阻止服务器重新启动. 每次容器启动时都会执行此脚本. entrypoint.sh包括:

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

最后, docker-compose.yml是魔法发生的地方. 该文件描述了组成您的应用程序(数据库和 Web 应用程序)的服务,如何获取每个人的 Docker 映像(数据库仅在预先制作的 PostgreSQL 映像上运行,而 Web 应用程序是从当前目录构建的),以及将它们链接在一起并公开 Web 应用程序端口所需的配置.

version: "3.9"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

Tip

您可以为此文件使用.yml.yaml扩展名.

Build the project

有了这些文件,您现在可以使用docker-compose run生成 Rails 框架应用程序:

$ docker-compose run --no-deps web rails new . --force --database=postgresql

首先,Compose 使用Dockerfileweb服务构建映像. --no-deps告诉 Compose 不要启动链接服务. 然后它使用该图像在新容器内运行rails new . 完成后,您应该已经生成了一个新的应用程序.

列出文件.

$ ls -l

total 64
-rw-r--r--   1 vmb  staff   222 Jun  7 12:05 Dockerfile
-rw-r--r--   1 vmb  staff  1738 Jun  7 12:09 Gemfile
-rw-r--r--   1 vmb  staff  4297 Jun  7 12:09 Gemfile.lock
-rw-r--r--   1 vmb  staff   374 Jun  7 12:09 README.md
-rw-r--r--   1 vmb  staff   227 Jun  7 12:09 Rakefile
drwxr-xr-x  10 vmb  staff   340 Jun  7 12:09 app
drwxr-xr-x   8 vmb  staff   272 Jun  7 12:09 bin
drwxr-xr-x  14 vmb  staff   476 Jun  7 12:09 config
-rw-r--r--   1 vmb  staff   130 Jun  7 12:09 config.ru
drwxr-xr-x   3 vmb  staff   102 Jun  7 12:09 db
-rw-r--r--   1 vmb  staff   211 Jun  7 12:06 docker-compose.yml
-rw-r--r--   1 vmb  staff   184 Jun  7 12:08 entrypoint.sh
drwxr-xr-x   4 vmb  staff   136 Jun  7 12:09 lib
drwxr-xr-x   3 vmb  staff   102 Jun  7 12:09 log
-rw-r--r--   1 vmb  staff    63 Jun  7 12:09 package.json
drwxr-xr-x   9 vmb  staff   306 Jun  7 12:09 public
drwxr-xr-x   9 vmb  staff   306 Jun  7 12:09 test
drwxr-xr-x   4 vmb  staff   136 Jun  7 12:09 tmp
drwxr-xr-x   3 vmb  staff   102 Jun  7 12:09 vendor

如果您在 Linux 上运行 Docker,则rails new由 root 拥有. 发生这种情况是因为容器以 root 用户身份运行. 如果是这种情况,请更改新文件的所有权.

$ sudo chown -R $USER:$USER .

如果你在 Mac 或 Windows 上运行 Docker,你应该已经拥有所有文件的所有权,包括那些由rails new生成的文件.

现在您已经有了一个新的 Gemfile,您需要再次构建映像. (这以及对Gemfile或 Dockerfile 的更改应该是您需要重建的唯一时间.)

$ docker-compose build

Connect the database

该应用程序现在可以启动了,但您还没有完成. 默认情况下,Rails 期望数据库在localhost上运行 - 因此您需要将其指向db容器. 您还需要更改数据库和用户名以与postgres图像设置的默认值保持一致.

config/database.yml的内容替换为以下内容:

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password
  pool: 5

development:
  <<: *default
  database: myapp_development


test:
  <<: *default
  database: myapp_test

您现在可以使用docker-compose up启动应用程序. 如果一切顺利,您应该会看到一些 PostgreSQL 输出:

$ docker-compose up

rails_db_1 is up-to-date
Creating rails_web_1 ... done
Attaching to rails_db_1, rails_web_1
db_1   | PostgreSQL init process complete; ready for start up.
db_1   |
db_1   | 2018-03-21 20:18:37.437 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db_1   | 2018-03-21 20:18:37.437 UTC [1] LOG:  listening on IPv6 address "::", port 5432
db_1   | 2018-03-21 20:18:37.443 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1   | 2018-03-21 20:18:37.726 UTC [55] LOG:  database system was shut down at 2018-03-21 20:18:37 UTC
db_1   | 2018-03-21 20:18:37.772 UTC [1] LOG:  database system is ready to accept connections

Finally, you need to create the database. In another terminal, run:

$ docker-compose run web rake db:create
Starting rails_db_1 ... done
Created database 'myapp_development'
Created database 'myapp_test'

View the Rails welcome page!

就是这样. 您的应用程序现在应该在 Docker 守护程序的端口 3000 上运行.

在 Docker Desktop for Mac 和 Docker Desktop for Windows 上,在 Web 浏览器上访问http://localhost:3000以查看 Rails Welcome.

Rails example

Stop the application

要停止应用程序,请在项目目录中运行docker-compose down . 您可以使用启动数据库的同一终端窗口,也可以使用可以访问命令提示符的另一个终端窗口. 这是停止应用程序的干净方法.

$ docker-compose down

Stopping rails_web_1 ... done
Stopping rails_db_1 ... done
Removing rails_web_run_1 ... done
Removing rails_web_1 ... done
Removing rails_db_1 ... done
Removing network rails_default

Restart the application

要重新启动应用程序,请在项目目录中运行docker-compose up .

Rebuild the application

如果您对 Gemfile 或 Compose 文件进行更改以尝试一些不同的配置,则需要重新构建. 有些更改只需要docker-compose up --build ,但完全重建需要重新运行 docker docker-compose run web bundle install以将Gemfile.lock中的更改同步到主机,然后是 docker docker-compose up --build .

这是第一种情况的示例,不需要完全重建. 假设您只是想将本地主机上的公开端口从我们第一个示例中的3000更改为3001 . 更改 Compose 文件以通过主机上的新端口3001公开容器上的端口3000 ,然后保存更改:

ports:
  - "3001:3000"

现在,使用docker-compose up --build重建并重新启动应用程序.

在容器内部,您的应用程序运行在与之前相同的端口3000上,但 Rails Welcome 现在可以在本地主机上的http://localhost:3001上使用.

More Compose documentation

documentation, docs, docker, compose, orchestration, containers

by  icopy.site