使用Docker-compose更新Symfony应用程序而不会丢失数据

时间:2015-11-26 18:17:12

标签: symfony docker capistrano3 docker-compose

我有一个多容器Symfony应用程序,它使用docker-compose来处理容器之间的关系。为了简化,我有4个主要服务:

code:
  image: mycode
web:
  image: mynginx
  volumes-from:
    - code
  ports:
    - "80:80"
  links:
    - php-fpm
php-fpm:
  image: myphpfpm
  volumes-from:
    - code
  links:
    - mongo
mongo:
  image: mongo

“mycode”图像包含我的应用程序的代码,它是从以下Dockerfile构建的:

FROM composer/composer

RUN apt-get update && apt-get install -y \
            libfreetype6-dev \
            libmcrypt-dev \
            libxml2-dev \
            libicu-dev \
            libcurl4-openssl-dev \
            libssl-dev \
            pkg-config

RUN docker-php-ext-install iconv mcrypt mbstring bcmath json ctype iconv posix intl

RUN pecl install mongo \
 && echo extension=mongo.so >> /usr/local/etc/php/conf.d/mongo.ini

COPY . /code
WORKDIR /code

RUN rm -rf /code/app/cache/* \
 && rm -rf /code/app/logs/* \
 && chown -R root /code/app/cache \
 && chown -R root /code/app/logs \
 && chmod -R 777 /code/app/cache \
 && chmod -R 777 /code/app/logs \
 && composer install \
 && rm -f /code/web/app_dev.php \
 && rm -f /code/web/config.php

VOLUME ["/code", "/code/app/logs", "/code/app/cache"]

首先,部署此应用程序很容易。我只需要做一个简单的docker-compose up -d并创建所有容器并运行它们没有任何问题。但后来我不得不部署一个新版本。

此配置使用卷来存储数据:

  • 源代码安装在/ code卷上,并在3之间共享 容器(代码,网络,php-fpm)。部署时必须用新版本替换它。
  • MongoDb数据在另一个上 音量,仅由mongo容器安装。我必须在部署之间保留这些数据。

当我为我的代码部署更新时,我发布新版本的 mycode 图像并重新创建容器。但由于 web php-fpm 容器仍使用 / code 卷,旧卷无法替换为新卷一。我必须停止所有正在运行的服务来删除旧卷,如果我使用docker-compose rm -v命令,它也会删除mongodb数据! 我不能只使用新版本替换一个卷,没有任何停机时间吗?

所以我有点被困在这里。我正在考虑使用永久卷来存储代码并通过SSH使用Capistrano进行更新,旧样式。这将允许我在部署后运行doctrine迁移脚本。但我有其他问题,因为Capistrano使用符号链接来处理版本所以我不能只将 / current 文件夹挂载到 / code

  • 您是否有解决方案来处理Docker应用程序的部署而不会丢失数据且无需停机?
  • 我应该使用手动脚本而不是docker-compose吗?

2 个答案:

答案 0 :(得分:0)

不要通过Dockerfile复制代码,只需将卷附加到'代码'容器

几乎没有编辑:

code:
  image: mycode
  volumes:
    - .:/code
    - /code
web:
  image: mynginx
  volumes-from:
    - code
  ports:
    - "80:80"
  links:
    - php-fpm
php-fpm:
  image: myphpfpm
  volumes-from:
    - code
  links:
    - mongo
mongo:
  image: mongo

同样的事情适用于mongo将其安装到外部卷,因此当容器关闭时它会持续存在。实际上还有另一种方法,他们在dockerhub页面https://hub.docker.com/_/mongo/

中提到它
  

存储数据的位置

     

重要提示:有几种方法可以存储使用的数据   在Docker容器中运行的应用程序。我们鼓励用户   mongo图像,以熟悉可用的选项,   包括:

     

让Docker通过编写来管理数据库数据的存储   数据库文件使用自己的内部主机系统上的磁盘   卷管理。这是默认设置,简单而公平   对用户透明。缺点是文件可能很难   找到直接在主机上运行的工具和应用程序   系统,即外部容器。

     

在主机系统(容器外)上创建数据目录   将其挂载到容器内可见的目录。这个   将数据库文件放在主机系统上的已知位置,以及   使主机系统上的工具和应用程序可以轻松访问   文件。缺点是用户需要确保   目录存在,例如目录权限等   主机系统上的安全机制设置正确。

答案 1 :(得分:0)

  

源代码安装在/ code volume

这是问题,不是你想要的。

代码永远不会进入卷,它应该在图像更改时更改。卷是指您希望在图像更改(数据,日志,状态等)之间保留的内容。

代码是您在更改容器时要替换的不可变的内容。因此,请完全从/code中删除Dockerfile卷,而是在ADD . /codemynginx Dockerfiles中执行myphpfpm

通过此更改,您可以使用up -d进行部署。它将重新创建已更改的任何容器,并且您的卷将被复制。您不再需要rm

如果您将Dockerfile myphpfpmmynginx放在其他目录中,则可以使用docker build -f path/to/dockerfile .

进行构建

使用主机卷(如另一个答案所示)是另一种选择,但是在开发之外通常不是您想要的。使用主机卷,您仍然可以从dockerfile中删除/code VOLUME