快速入门:Compose和Rails

预计阅读时间:8分钟

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

定义项目

首先设置构建应用程序所需的文件。该应用程序将在包含其依赖项的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
COPY ../compose /myapp

# 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参考》

接下来,打开一个编辑器并创建一个Gemfile仅加载Rails的引导程序。稍后将被覆盖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

小费

您可以对此文件使用a.yml.yaml扩展名。

建立项目

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

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

首先,Composeweb使用来为服务构建映像Dockerfile。该--no-deps告诉撰写不启动链接服务。然后,它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

连接数据库

该应用程序现在可以启动,但是您还没有启动。默认情况下,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启动应用程序:

$ docker-compose up

如果一切顺利,您应该会看到一些PostgreSQL输出。

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

最后,您需要创建数据库。在另一个终端中,运行:

$ docker-compose run web rake db:create

这是该命令的输出示例:

$ docker-compose run web rake db:create

Starting rails_db_1 ... done
Created database 'myapp_development'
Created database 'myapp_test'

查看Rails欢迎页面!

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

在Mac的Docker桌面和Windows的Docker桌面http://localhost:3000上,在Web浏览器上转到来查看Rails Welcome。

Rails的例子

停止申请

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

$ 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

重新启动应用程序

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

重建应用程序

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

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

ports:
  - "3001:3000"

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

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

更多撰写文档

文档docsdockercompose编排容器