Docker化一个应用程序,其构建过程取决于与另一个容器的通信

时间:2018-07-13 21:29:34

标签: ruby-on-rails docker docker-compose

我有一个Ruby on Rails应用程序,我正在尝试对其进行容器化,以便可以在Docker中进行部署:

version: '3.4'
services:
  db:
    image: postgres
  web:
    container_name: my_rails_app
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - db

作为此应用程序现有构建过程的一部分,当前存在一个脚本,该脚本使用一堆示例数据启动该应用程序的测试版本,并获取要在帮助文件中使用的该应用程序各种功能的多个屏幕截图。 。该脚本已集成到Ruby on Rails的资产管道中,因此它作为常规资产预编译过程的一部分运行(以下Dockerfile有所简化):

FROM ruby:2.2.10 AS build

COPY . /opt/my_rails_app
RUN bundle install

# Generates static assets, including screenshots
RUN bundle exec rake assets:precompile

RUN bundle install --deployment --without development test assets


FROM ruby:2.2.10 AS production

ENV RAILS_ENV=production

COPY . /opt/my_rails_app
COPY --from=build vendor/bundle vendor/bundle
COPY --from=build public/assets public/assets

CMD ["bundle", "exec", "rails", "server"]
EXPOSE 3000

现在这是我的问题:因为此构建步骤启动了Web服务器以获取UI的屏幕截图,所以它需要能够在构建期间 连接到数据库。 (如果没有数据库连接,Web服务器将无法正常运行。)

在旧环境中,这不是问题,因为生产数据库与应用程序安装在同一服务器上,因此我可以将其连接到本地主机。但是,使用Docker时,数据库在docker-compose管理的单独容器中运行。不幸的是,Docker似乎不想让我在构建过程中与该容器交谈:

could not translate host name "db" to address: Name or service not known

我考虑只是将预编译步骤延迟到部署之后;但这会大大减慢容器的部署过程,并要求我在生产容器中再包含50-100个依赖关系,而这些依赖关系本来就不会使用。

我也考虑过在构建容器上安装数据库,但这似乎会使构建速度变慢,并且如果构建容器上的数据库与postgres上的数据库不完全匹配,可能会导致问题。图片提供。

有没有一种方法可以告诉docker在构建过程中 启动容器并设置适当的网络连接?还是没有我上面已经考虑过的其他解决方案的缺点的替代解决方案?

2 个答案:

答案 0 :(得分:1)

有一个<input id="sessionInput" type="hidden" value='<%# Session["UserLogin"] != null ? Session["UserLogin"].ToString() : ""; %>' /> 标志,我想它可以让您在任何docker网络模式下运行构建容器。 然后,您可以创建Postgres容器并在该容器的网络中运行构建容器。

答案 1 :(得分:1)

这是可以做到的,但是目前Docker Compose还没有很好的支持。

您要做的是使用Docker's built-in networking features设置一个包含数据库容器的共享网络,然后在构建过程中将应用程序容器连接到该网络。

在没有Docker Compose的情况下,这将通过启动数据库容器,使用docker network子命令将其连接到docker网络,然后使用docker build --network $network_name_here .构建应用程序容器来实现。

使用Docker Compose,可以通过其应用程序的name属性为应用程序的默认网络配置静态名称,然后对服务build参数使用未记录的network选项,以实现此目的告诉Compose在构建过程中将该网络用于您的应用程序容器:

# Setting network names is only available in version 3.5+
version: '3.5'
services:
  db:
    image: postgres
  web:
    container_name: my_rails_app
    build:
      context: .
      # This isn't listed in the official Docker documentation, but it lets you
      # specify which network to connect the container to during the build
      # process.
      network: myapp_default
    ports:
      - "3000:3000"
    depends_on:
      - db

networks:
  default:
    # Set the name of the default network. If you don't do this the name could
    # change based on your app's ["project name"][1], which would break your
    # build.
    #
    # [1]: https://docs.docker.com/compose/reference/envvars/#compose_project_name
    name: myapp_default

但是,仅凭此点还不够。这是因为默认情况下,Docker Compose不会在构建过程中启动容器的依赖项。要解决此问题,您需要在运行构建之前手动启动数据库容器:

docker-compose up --detach db # Start the database container
docker-compose build # Now run the build

这将允许在构建Web服务时将Web服务连接到db服务。