快速入门: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。
停止申请
要停止应用程序,请在项目目录中运行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
本地主机上使用。