Docker 合并容器
Docker merge containers
我有 运行 多个容器,它们使用 docker-compose.yml 中定义的网络相互连接,我的应用程序 运行 完美,所以我想为那些部署到我的私有存储库的多个容器只创建一个图像(带有标签的图像),我想知道什么是最佳实践。
docker-compose.yml
version: '3.1'
networks:
lemp:
services:
nginx:
build:
context: .
dockerfile: Dockerfile
target: webserver
container_name: webserver
volumes:
- ./src/app:/var/www/html/app
ports:
- "80:80"
networks:
- lemp
php:
build:
context: .
dockerfile: Dockerfile
target: app
container_name: app
volumes:
- ./src/app:/var/www/html/app
ports:
- "9000:9000"
networks:
- lemp
Docker 文件
FROM nginx:1.21.6-alpine AS webserver
COPY ./src/ ./var/www/html
COPY ./nginx/conf.d/app.conf /etc/nginx/conf.d/app.conf
EXPOSE 80 443
FROM php:7.4-fpm-alpine AS app
EXPOSE 9000
不清楚您真正需要什么。您可以将各个容器发布到您的注册表并提供可下载的 Compose 文件供任何人一起使用这些容器,这将分别拉取每个图像。
否则,您需要将所有相关步骤从一个 Dockerfile 复制到另一个。注意:如果您在每个 Dockerfile 中 运行 唯一 entrypoint/commands(进程),那么这被认为是不好的做法。
更新
查看您的示例,您可以将 php-fpm 安装到 Nginx 容器中,复制 PHP 文件,然后只从那里提供静态内容。但是,我肯定会建议保留单独的容器。 Nginx 应该可以替换为反向代理。
此外,您没有正确的 multi-stage Dockerfile(使用 FROM 两次不会合并任何内容),并且您的 Compose 文件只是 运行 相同的图像(上下文)两次两个不同的端口。
您应该计划分发您的 docker-compose.yml
文件,或者它的简化版本,作为 运行 您的组合申请的标准方式。如果它需要两个图像,你需要将两个图像分别推送到你的存储库;不要试图将它们结合起来。请确保图像是 self-contained,这样您就不需要将源代码与图像分开 运行。
docker-compose.yml
文件大致如下所示:
version: '3.8'
services:
nginx:
image: registry.example.com/nginx:${TAG:-latest}
ports:
- '80:80'
php:
image: registry.example.com/php:${TAG:-latest}
在这里指出几件事:我删除了不必要的 networks:
声明(Compose 提供了一个工作正常的 default
网络)和不必要的 container_name:
声明。我为每个图像放置了一个 image:
行来代替 build:
块,并使用环境变量来注入图像标签。对于 php
容器,我删除了 ports:
声明,因为您可能不希望它可以从外部访问。最后,对于两个容器,我都删除了覆盖图像内容的 volumes:
。
在此旁边,放一个 docker-compose.override.yml
文件。这不是你要分发的东西。它可以说:
version: '3.8'
services:
nginx:
build:
context: .
dockerfile: Dockerfile.nginx
php:
build:
context: .
dockerfile: Dockerfile.php
ports:
- '9000:9000'
如果您有两个文件,Compose merges their settings。因此,对于开发人员来说,如果需要,这会添加 ports:
以直接访问 PHP-FPM 服务,并添加 build:
块来解释如何构建两个图像。由于组合的 Compose 配置同时具有 build:
和 image:
,docker-compose build
将构建具有指定名称并标记有您的本地注册表名称的图像。
您应该为每个正在构建的图像创建一个单独的 Docker 文件。 Nginx 映像类似于您已有的映像;对于 PHP-FPM 容器,您需要确保将代码 COPY
放入图像中。
# Dockerfile.nginx
FROM nginx:1.21.6-alpine
COPY ./src/ /var/www/html/
COPY ./nginx/conf.d/app.conf /etc/nginx/conf.d/app.conf
# Dockerfile.php
FROM php:7.4-fpm-alpine
COPY ./src/app/ /var/www/html/app/
现在您可以在本地构建和 运行 应用程序。 Double-check 它工作正常, 没有 volumes:
覆盖图像代码。
docker-compose build
docker-compose up -d
curl http://localhost/
如果这有效,那么您就可以分发它了。选择一个标签(日期戳或当前源代码控制 ID 是不错的选择),构建图像,并将它们推送到 Docker 注册表。
export TAG=20220418
docker-compose build
docker-compose push
现在您可以只复制 docker-compose.yml
文件,但 none 我们接触过的其他文件,可以复制到远程系统,或者将其放入 GitHub 存储库中,或者是其他东西。在该系统上,设置 $TAG
以匹配,并像往常一样设置 运行 docker-compose up
。 Docker 将自动从存储库中提取图像。由于图像是 self-contained,因此您只需要 就是 docker-compose.yml
文件。
scp docker-compose.yml there:
ssh root@there
export TAG=20220418
docker-compose up -d
我有 运行 多个容器,它们使用 docker-compose.yml 中定义的网络相互连接,我的应用程序 运行 完美,所以我想为那些部署到我的私有存储库的多个容器只创建一个图像(带有标签的图像),我想知道什么是最佳实践。
docker-compose.yml
version: '3.1'
networks:
lemp:
services:
nginx:
build:
context: .
dockerfile: Dockerfile
target: webserver
container_name: webserver
volumes:
- ./src/app:/var/www/html/app
ports:
- "80:80"
networks:
- lemp
php:
build:
context: .
dockerfile: Dockerfile
target: app
container_name: app
volumes:
- ./src/app:/var/www/html/app
ports:
- "9000:9000"
networks:
- lemp
Docker 文件
FROM nginx:1.21.6-alpine AS webserver
COPY ./src/ ./var/www/html
COPY ./nginx/conf.d/app.conf /etc/nginx/conf.d/app.conf
EXPOSE 80 443
FROM php:7.4-fpm-alpine AS app
EXPOSE 9000
不清楚您真正需要什么。您可以将各个容器发布到您的注册表并提供可下载的 Compose 文件供任何人一起使用这些容器,这将分别拉取每个图像。
否则,您需要将所有相关步骤从一个 Dockerfile 复制到另一个。注意:如果您在每个 Dockerfile 中 运行 唯一 entrypoint/commands(进程),那么这被认为是不好的做法。
更新
查看您的示例,您可以将 php-fpm 安装到 Nginx 容器中,复制 PHP 文件,然后只从那里提供静态内容。但是,我肯定会建议保留单独的容器。 Nginx 应该可以替换为反向代理。
此外,您没有正确的 multi-stage Dockerfile(使用 FROM 两次不会合并任何内容),并且您的 Compose 文件只是 运行 相同的图像(上下文)两次两个不同的端口。
您应该计划分发您的 docker-compose.yml
文件,或者它的简化版本,作为 运行 您的组合申请的标准方式。如果它需要两个图像,你需要将两个图像分别推送到你的存储库;不要试图将它们结合起来。请确保图像是 self-contained,这样您就不需要将源代码与图像分开 运行。
docker-compose.yml
文件大致如下所示:
version: '3.8'
services:
nginx:
image: registry.example.com/nginx:${TAG:-latest}
ports:
- '80:80'
php:
image: registry.example.com/php:${TAG:-latest}
在这里指出几件事:我删除了不必要的 networks:
声明(Compose 提供了一个工作正常的 default
网络)和不必要的 container_name:
声明。我为每个图像放置了一个 image:
行来代替 build:
块,并使用环境变量来注入图像标签。对于 php
容器,我删除了 ports:
声明,因为您可能不希望它可以从外部访问。最后,对于两个容器,我都删除了覆盖图像内容的 volumes:
。
在此旁边,放一个 docker-compose.override.yml
文件。这不是你要分发的东西。它可以说:
version: '3.8'
services:
nginx:
build:
context: .
dockerfile: Dockerfile.nginx
php:
build:
context: .
dockerfile: Dockerfile.php
ports:
- '9000:9000'
如果您有两个文件,Compose merges their settings。因此,对于开发人员来说,如果需要,这会添加 ports:
以直接访问 PHP-FPM 服务,并添加 build:
块来解释如何构建两个图像。由于组合的 Compose 配置同时具有 build:
和 image:
,docker-compose build
将构建具有指定名称并标记有您的本地注册表名称的图像。
您应该为每个正在构建的图像创建一个单独的 Docker 文件。 Nginx 映像类似于您已有的映像;对于 PHP-FPM 容器,您需要确保将代码 COPY
放入图像中。
# Dockerfile.nginx
FROM nginx:1.21.6-alpine
COPY ./src/ /var/www/html/
COPY ./nginx/conf.d/app.conf /etc/nginx/conf.d/app.conf
# Dockerfile.php
FROM php:7.4-fpm-alpine
COPY ./src/app/ /var/www/html/app/
现在您可以在本地构建和 运行 应用程序。 Double-check 它工作正常, 没有 volumes:
覆盖图像代码。
docker-compose build
docker-compose up -d
curl http://localhost/
如果这有效,那么您就可以分发它了。选择一个标签(日期戳或当前源代码控制 ID 是不错的选择),构建图像,并将它们推送到 Docker 注册表。
export TAG=20220418
docker-compose build
docker-compose push
现在您可以只复制 docker-compose.yml
文件,但 none 我们接触过的其他文件,可以复制到远程系统,或者将其放入 GitHub 存储库中,或者是其他东西。在该系统上,设置 $TAG
以匹配,并像往常一样设置 运行 docker-compose up
。 Docker 将自动从存储库中提取图像。由于图像是 self-contained,因此您只需要 就是 docker-compose.yml
文件。
scp docker-compose.yml there:
ssh root@there
export TAG=20220418
docker-compose up -d