如何使用Docker Compose YML文件进行生产环境部署?

13

我在本地主机上有一个Docker应用程序,它运行良好。我正在其中运行PHP,Nginx和Mariadb。

docker-compose.yml文件包含以下代码:

version: '3'

services:
    db:
      build:
        context: ./mariadb
      volumes:
          - "./.data/db:/var/lib/mysql"
          - "./logs/mariadb:/var/log/mysql"
      environment:
          MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
          MYSQL_DATABASE: ${MYSQL_DATABASE}
          MYSQL_USER: ${MYSQL_USER}
          MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      networks:
        - default
    php-fpm:
      build:
          context: ./php7-fpm
          args:
              TIMEZONE: ${TIMEZONE}
      volumes:
          - ${APP_PATH}:/var/www/app
      environment:
          DB_HOST: db
          DB_PORT: 3306
          DB_DATABASE: ${MYSQL_DATABASE}
          DB_USERNAME: ${MYSQL_USER}
          DB_PASSWORD: ${MYSQL_PASSWORD}
      depends_on:
        - db
      networks:
        - default
    nginx:
      build:
        context: ./nginx
        args:
          - 'php-fpm'
          - '9000'
      volumes:
        - ${APP_PATH}:/var/www/app
        - ./logs/nginx/:/var/log/nginx
      ports:
        - "80:80"
        - "443:443"
      depends_on:
        - php-fpm
      networks:
        - default
networks:
  default:
    driver: bridge
一开始我以为只需要一个compose文件,但是当我构建了镜像,将其推到docker hub并在生产服务器上拉取该镜像时,容器无法启动。
我阅读了一些资料,有很多在线资源建议使用 1 到 4 个 Docker 文件,并检查两个 git 分支... 等等。
我明白我至少应该创建另一个名为 docker-compose-prod.yml 的文件,在该文件中,应省略 volumes:port: 属性,但似乎没有明确的指南:
  1. 如何在本地使 docker 工作

  2. 何时以及如何为生产构建容器。

请问有人能为我澄清这个问题吗?
1个回答

11
建议您使用“多个Compose文件”:
使用多个Compose文件可以为不同的环境或不同的工作流自定义Compose应用程序。
以下是一个例子:
(注意:下面省略了一些Compose文件的元素)
docker-compose.yml:
web:
  image: example/my_web_app:latest

docker-compose.dev.yml:

web:
  ports:
    - 80:80
  • 执行docker-compose -f docker-compose.yml -d不会有端口映射。
  • 执行docker-compose -f docker-compose.yml -f docker-compose.dev.yml -d将使docker-compose.dev.yml覆盖一些值docker-compose.yml,以实现您的目标。

详情请参考docker文档,这是官方处理您场景的建议,供您参考。

更新:

您使用了build: context: ./mariadb,因此compose始终可以在文件夹mariadb中找到Dockerfile进行构建,在本地开发服务器或生产服务器上都一样。

刚才的方式会在devprod服务器上都构建镜像,这是您可以遵循的一个选项。

正如您在评论中所说的,另一个选项如下:

但在生产服务器上,我只能拉取和运行镜像,镜像必须事先用prod yml文件构建

那么您可能不想在prod服务器上重新构建镜像?

接下来是一个更新的解决方案,只是一个例子:

docker-compose.yml:

db:
  image: your_maridb_image_name:your_maridb_image_version
  networks:
    - default

docker-compose.dev.yml:

db:
  build:
    context: ./mariadb
  ports:
    - "xxx:xxx"

docker-compose.prod.yml:

db:
  otheroptions_special_for_prod_just_a_example: xxx

1) docker-compose -f docker-compose.yml -f docker-compose.dev.yml -d

这将合并如下内容:

db:
  image: your_maridb_image_name:your_maridb_image_version
  networks:
    - default
  build:
    context: ./mariadb
  ports:
    - "xxx:xxx"

根据 docker-compose 语法,如果提供了 build:context ,compose 将不会从 docker registry 拉取镜像,它只会在 context 中查找 Dockerfile,最后使用你在 image 中指定的名称构建一个镜像,这里是 your_maridb_image_name:your_maridb_image_version。然后,你需要将其推送到 dockerhub,但确实需要停止本地容器。 2) docker-compose -f docker-compose.yml -f docker-compose.prod.yml -d 这将合并如下内容:
db:
  image: your_maridb_image_name:your_maridb_image_version
  networks:
    - default
  otheroptions_special_for_prod_just_a_example: xxx

根据 docker-compose 语法,未提供 build:context,因此 compose 将直接从远程仓库(docker hub)拉取镜像。你还记得在本地开发服务器上完成开发后已将镜像推送到 dockerhub 吗?所以无需再次构建镜像。

你的回答很清晰简单,但我不明白一件事。在生产环境中,我什么时候/在哪里使用docker-compose(第一次执行)?因为我知道在本地,我可以使用第二个执行文件,它会合并两个文件,然后我就有了一个包含端口、卷和所有内容的组合文件,但是在生产服务器上,我只能拉取和运行镜像,而镜像必须预先使用生产yml文件构建,那么当我完成我的应用程序后,我该如何在本地操作?我需要停止Docker,然后使用prod.yml构建它,然后推送它吗? - anon
对于您的第一条评论:实际上我不知道如何删除一个选项,但是您可以始终设置一个最小的 docker-compose.yml,其中包含最常见的选项,然后将不同的内容放入 docker-compose-dev.ymldocker-compose-prod.yml 中,这只是一个解决方法,请查看是否有人可以在您的新问题中帮助您。 - atline
哦,谢谢回答。我一直在尝试让Docker工作,已经三个星期了。只有一个快速问题,你是否遇到过[emerg] 1#1: host not found in upstream "php-fpm:9000" in /etc/nginx/conf.d/upstream.conf:1错误?我一直在处理这个问题,直到现在,这可能是我的应用程序无法正常工作的原因。该问题与文件有关。在本地一切正常,但在生产环境中,nginx由于该错误而退出。 - anon
我认为如果我修复了那个错误,一切都会好起来。我已经在每一个谷歌链接上寻找那个错误,直到我用尽了所有的方法,但仍然无法解决它。我不知道我的应用程序出了什么问题。 - anon
你确定 php-fpm 是你的电脑主机名吗?请检查你的 /etc/hosts 文件以添加绑定或直接使用 IP 地址。你可以在容器中使用 ping php-fpm 来确认。不管怎样,这是另一个问题了。 - atline
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接