构build并使用docker-compose中的docker镜像

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

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

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

 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撰写文件有任何build议,我很乐意听到,但是我相信这是另一个问题。

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

您可以使用dobi (免责声明:我是dobi的作者)构build您的图像,并启动撰写。 你的dobi.yaml可能是这样的:

 image=app: image: reponame/appname tags: [latest] compose=dev: files: [docker-compose.yml] project: '{project}' depends: [app] 

你可以使用dobi dev来运行dobi dev来创build镜像(一次),然后开始撰写(相当于docker-compose up -d为了获得交互式日志,你可以运行dobi dev:attach

你还必须删除build: . 从你docker-compose.yml取代它image: reponame/appname:latest

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

他们都引用相同的基本图像,由相同的图像ID反映。 容器名称的行为像符号链接。

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

可以通过构build一次图像并在撰写文件中相应引用它解决此问题,例如

 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以错误的顺序启动服务,则启动某些服务可能会失败或依赖可能过时的映像。

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

我仍然鼓励你这样做。 它使事情更加一致(而且更快!)。 开发一个图像和testing一个多容器应用程序是两回事,应该进行相应的处理。