部署docker-composer图像时出现混乱

时间:2016-12-25 20:17:48

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

我一直在使用示例ruby-on-rails应用程序并在linux服务器(ubuntu 14.04)中部署docker镜像。

这是我的Dockerfile:

FROM ruby:2.1.5
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /rails_docker_demo
WORKDIR /rails_docker_demo
ADD Gemfile /rails_docker_demo/Gemfile
ADD Gemfile.lock /rails_docker_demo/Gemfile.lock
RUN bundle install
ADD . /rails_docker_demo

# CMD bundle exec rails s -p 3000 -b 0.0.0.0
# EXPOSE 3000

搬运工-compose.yml:

version: '2'
services:
  db:
    image: postgres
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    image: atulkhanduri/rails_docker_demos
    volumes:
      - .:/rails_docker_demo
    ports:
      - "3000:3000"
    depends_on:
      - db

deploy.sh:

#!/bin/bash

docker build -t atulkhanduri/rails_docker_demo .
docker push atulkhanduri/rails_docker_demo

ssh username@ip-address << EOF
docker pull atulkhanduri/rails_docker_demo:latest
docker stop web || true
docker rm web || true
docker rmi atulkhanduri/rails_docker_demo:current || true
docker tag atulkhanduri/rails_docker_demo:latest atulkhanduri/rails_docker_demo:current
docker run -d --restart always --name web -p 3000:3000 atulkhanduri/rails_docker_demo:current
EOF

现在我的问题是我无法使用docker-compose这样的docker-compose up命令来运行应用服务器。

当我取消注释Dockerfile的最后两行,即

CMD bundle exec rails s -p 3000 -b 0.0.0.0    
EXPOSE 3000

然后我可以在端口3000上运行服务器,但收到错误could not translate host name "db" to address: Name or service not known。 (我的database.yml有“db”作为主机。)这是因为我没有使用postgres图像,因为我没有使用docker-compose文件。

编辑:

docker network ls的输出:

NETWORK ID          NAME                DRIVER              SCOPE
b466c9f566a4        bridge              bridge              local               
7cce2e53ee5b        host                host                local               
bfa28a6fe173        none                null                local

P.S:我在互联网上搜索了很多但是还不能使用docker-compose文件。

2 个答案:

答案 0 :(得分:2)

假设

如果我正在阅读你在这里所做的事情,我的回答是假设以下两件事。

  1. 您正在使用docker-compose来运行数据库容器。

  2. 您正在使用普通的docker命令(而不是docker-compose)来启动应用程序服务器(“web”)。

  3. 首先,我建议不要这样做,对两者使用docker-compose要简单得多。但是,我将根据上述内容进行回答,假设有一些正当理由不能使用docker-compose来运行“web”容器。

    关于容器和网络名称

    运行docker-compose命令启动数据库容器时,除其他外,还会发生两件事。

    1. 为容器指定一个新名称,该名称由您运行撰写设置的目录,撰写时的静态名称(db)和数字组成。因此,假设您在目录名myapp中拥有此全部内容,您将拥有一个名为myapp_db_1的新容器。您可以使用docker ps查看其名称。

    2. 如果网桥尚不存在,则会创建一个网桥,名称类似myapp_default - 再次以命名设置所在的目录命名。

    3. 连接到正确的网络

      问题是您的非撰写容器已附加到默认网络(可能是docker_default),但您的数据库容器已附加到myapp_default。这两个网络彼此不了解。你需要连接它们。告诉Web应用程序容器连接到撰写网络可能更有意义。

      首先,获取正确的网络名称。您可以使用docker network ls查看所有网络。它可能看起来像这样:

      $ docker network ls
      NETWORK ID          NAME                       DRIVER              SCOPE
      c1f5764a112b        bridge                     bridge              local
      175efb89adef        docker_default             bridge              local
      5185ff0e1054        myapp_default              bridge              local
      

      获得正确的名称后,请使用--network选项更新运行命令以了解网络。

      docker run -d --restart always --name web \
          -p 3000:3000 --network myapp_default \
          atulkhanduri/rails_docker_demo:current
      

      一旦将其连接到正确的网络,名称“db”应该正确解析。

      如果你使用docker-compose来启动它们,那么这就没有必要了(这是docker-compose为你默默处理的事情之一)。

      让它在您的服务器上运行

      在评论中,您提到您在服务器上有一些compose问题。具体你说:

        

      我是否需要在服务器上复制完整的项目?我不能只从docker镜像运行应用程序吗?实际上,我在服务器中复制了docker-compose并且它为Gemfile引发了错误,然后我复制了Gemfile,然后它说它应该是一个rails应用程序。所以我想我需要在服务器中复制我的完整文件夹。你能确认一下吗?

      让我们看一下Dockerfile的某些部分。我会在线添加一些评论。

      ## Make a new directory, and then make it the current directory
      RUN mkdir /rails_docker_demo
      WORKDIR /rails_docker_demo
      
      ## Copy Gemfile and Gemfile.lock into this directory from outside
      ADD Gemfile /rails_docker_demo/Gemfile
      ADD Gemfile.lock /rails_docker_demo/Gemfile.lock
      
      ## Run the bundle installer, which will install to this directory
      RUN bundle install
      
      ## Finally, copy everything from the outside local dir to here
      ADD . /rails_docker_demo
      

      因此,显然,/rails_docker_demo是容器中的应用程序目录。你在这里安装了很多东西,这将成为你形象的一部分。当您将图像推送到注册表时,然后将其下拉到服务器上(就像在部署脚本中一样),这一切都会随之而来。

      现在让我们来看看(某些)docker-compose.yml。

      services:
        web:
          volumes:
            - .:/rails_docker_demo
      

      在这里,您已经定义了一个卷挂载,将当前目录(docker-compose.yml所在的位置)挂载为/rails_docker_demo。当你这样做时,服务器上发生的任何事情现在都可以在/rails_docker_demo中找到,但是这个mount撤消了我刚才提到的Dockerfile的所有工作。您没有拥有构建映像时安装的资源,而只拥有.目录中服务器上的任何内容。挂载位于映像的现有/rails_docker_demo目录的顶部,隐藏其内容并将其替换为服务器上的任何内容。

      除非有理由将此挂载放在此处,否则您可能只需要从docker-compose.yml中删除该卷挂载。你仍然需要在服务器上使用docker-compose.yml,但你不需要其余部分(当然除了图像)。

      你做的这个装载是有用的 - 用于开发目的。它允许您使用容器来运行应用程序并快速显示代码更改(无需重建映像)。但是在部署的情况下,它只会造成麻烦。

答案 1 :(得分:-1)

尝试移动EXPOSE上面的CMD,.e.g。

FROM ruby:2.1.5
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /rails_docker_demo
WORKDIR /rails_docker_demo
ADD Gemfile /rails_docker_demo/Gemfile
ADD Gemfile.lock /rails_docker_demo/Gemfile.lock
RUN bundle install
ADD . /rails_docker_demo

EXPOSE 3000
CMD bundle exec rails s -p 3000 -b 0.0.0.0