从docker-compose

时间:2016-10-21 17:54:43

标签: docker docker-compose

我有一个Dockerfile,可以创建一个包含我的图像需要运行的所有依赖项的图像。然后,我将文件作为只读数据卷挂载,并将各种文件设置为入口点。虽然这意味着我不需要多个Dockerfiles,但由于某种原因,每次我向docker-compose文件添加新服务时,我都会创建一个新图像(虽然看起来它只是从缓存中拉出来)。 有没有办法让docker-compose文件构建一次图像,然后让所有服务依赖于新构建的图像?

我知道可以单独构建图像,给它起一个名字,然后让docker-compose文件引用该图像,但这需要2个命令而不是我现在使用的单个docker-compose up

这是我的docker images输出的样子。您可以看到每个服务都创建了自己的图像,这是我不喜欢的。我不完全确定这是否意味着每个图像在磁盘上占用额外的1.3gb,或者它们是否只是引用相同的基本图像(我猜是后者,但是很想知道肯定的),但它仍然污染了泊坞窗图像列表。

REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
docker_http_server_1   latest              a6eac9198c44        5 weeks ago         1.315 GB
docker_test_client     latest              a6eac9198c44        5 weeks ago         1.315 GB
docker_test_client_3   latest              a6eac9198c44        5 weeks ago         1.315 GB
meh                    latest              a6eac9198c44        5 weeks ago         1.315 GB
docker_data_server_1   latest              a6eac9198c44        5 weeks ago         1.315 GB
docker_server1         latest              a6eac9198c44        5 weeks ago         1.315 GB
docker_server2         latest              a6eac9198c44        5 weeks ago         1.315 GB
docker_server          latest              a6eac9198c44        5 weeks ago         1.315 GB
docker_test_client_2   latest              a6eac9198c44        5 weeks ago         1.315 GB
docker_http_server_2   latest              a6eac9198c44        5 weeks ago         1.315 GB
<none>                 <none>              9428e39bd080        5 weeks ago         431.7 MB
<none>                 <none>              08a27b512ded        5 weeks ago         430.3 MB
<none>                 <none>              acc3e230ecaa        5 weeks ago         411.1 MB
<none>                 <none>              96c74b6e7d9d        5 weeks ago         829.2 MB
<none>                 <none>              acf4a5ef1eeb        5 weeks ago         677 MB
<none>                 <none>              8f646f9a5352        5 weeks ago         2.759 GB
<none>                 <none>              ce8fa0a27cde        5 weeks ago         562.3 MB
<none>                 <none>              533cfe78e0d2        5 weeks ago         165.6 MB
redis                  latest              0d1cbfaa41da        7 weeks ago         185 MB
ubuntu                 16.04               bd3d4369aebc        7 weeks ago         126.6 MB
nginx                  latest              4efb2fcdb1ab        8 weeks ago         183.4 MB
hello-world            latest              c54a2cc56cbb        3 months ago        1.848 kB

当前的docker-compose文件:

version: '2'
services:
    data_server_1:
        build: .
        volumes:
            - "..:/buggy:ro"
        entrypoint: "/buggy/buggy_data_server.py"

    http_server_1:
        build: .
        volumes:
            - "..:/buggy:ro"
        entrypoint: "/buggy/buggy_http_server.py"
        links:
            - data_server_1 

    http_server_2:
        build: .
        volumes:
            - "..:/buggy:ro"
        entrypoint: "/buggy/buggy_http_server.py"
        links:
            - data_server_1 

    nginx:
        image: nginx
        ports:
            - "80:80"
            - "443:443"
            - "4242:4242"
        links:
            - data_server_1 
            - http_server_1 
            - http_server_2
        volumes:
            - "../nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
            - "../static:/www/static"
            - "../protos:/www/protos"

    # This is effectively the same as running it on the host machine and host
    # network rather than within the docker network. This is so that we can test
    # to ensure that the tcp listening port works via the public interface
    # rather than through the docker channels.
    test_client:
        build: .
        network_mode: "host"
        volumes:
            - "..:/buggy:ro"
        entrypoint:
            - "/buggy/test_client.py"
            - "--key=/buggy/keys/robot1.key"
            - "--no-gui"
            - "--status"
            - "--buggy-name=Deep Mind (Status)"

    test_client_2:
        build: .
        network_mode: "host"
        volumes:
            - "..:/buggy:ro"
        entrypoint:
            - "/buggy/test_client.py"
            - "--key=/buggy/keys/robot2.key"
            - "--no-gui"
            - "--imu"
            - "--buggy-name=Bender (IMU)"

    test_client_3:
        build: .
        network_mode: "host"
        volumes:
            - "..:/buggy:ro"
        entrypoint:
            - "/buggy/test_client.py"
            - "--key=/buggy/keys/robot3.key"
            - "--no-gui"
            - "--camera"
            - "--buggy-name=Megatron (Camera)"

另外,如果有任何关于如何改进docker-compose文件的建议,我很乐意听到它们,但我相信这是另一个问题。

2 个答案:

答案 0 :(得分:1)

如果您正在寻找更复杂的构建选项,您可能希望在Compose之外查看。正如在其他答案中所说的那样,这里有两个问题(1.构建图像,2。运行容器)。 Compose专注于运行容器。

您可以使用dobi(免责声明:我是dobi的作者)来构建您的图像,然后启动Compose。您的dobi.yaml可能如下所示:

image=app:
  image: reponame/appname
  tags: [latest]

compose=dev:
  files: [docker-compose.yml]
  project: '{project}'
  depends: [app]

您可以使用dobi dev运行以构建图像(一次)并启动Compose(相当于docker-compose up -d。要获取交互式日志,您可以运行dobi dev:attach

您还必须从build: .中移除docker-compose.yml并将其替换为image: reponame/appname:latest

答案 1 :(得分:0)

  

我不完全确定这是否意味着每张图片在磁盘上占用额外的1.3gb,或者它们是否只是引用相同的基本图像

它们都引用相同图像ID反映的相同基本图像。容器名称的行为类似于符号链接。

  

有没有办法让docker-compose文件构建一次图像,然后让所有服务依赖于新构建的图像?

可以解决这个问题,只需构建一次图像并在你的撰写文件中相应地引用它,例如

version: '2'
services:
    data_server_1:
        build: .
        [...]

    http_server_1:
        image: docker_data_server_1
        [...]

    http_server_2:
        image: docker_data_server_1
        [...]

请注意,方法非常脆弱。重命名父文件夹或服务本身将导致问题。如果docker-compose以错误的顺序旋转服务,则启动某些服务将失败或依赖于可能过时的图像。

  

我知道可以单独构建图像,给它起一个名字,然后让docker-compose文件引用该图像,但这需要2个命令而不是我现在使用的单个docker-compose。

我仍然鼓励你这样做。它使事情更加一致(并且更快!)。开发图像和测试多容器应用程序是两回事,应该相应地对待。