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

Updating a Symfony app with Docker-compose without losing data

我有一个多容器 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" 图像包含我的应用程序的代码,是从以下 Docker 文件构建的:

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 就可以毫无问题地创建所有容器和 运行 它们。但后来我不得不部署一个新版本。

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

当我部署代码更新时,我发布了新版本的 mycode 图像并重新创建了容器。但是由于 /code 卷仍然被 webphp-fpm 使用容器,旧卷不能被新卷替换。我必须停止所有 运行ning 服务才能删除旧卷,如果我使用 docker-compose rm -v 命令,它也会删除 mongodb 数据! 我不能只用一个新版本替换一个卷,而不会停机吗?

所以我有点被困在这里了。我正在考虑有一个永久卷来存储代码并使用 Capist运行o 通过 SSH 更新它,旧的风格。这也将允许我在部署后 运行 学说迁移脚本。但我还有其他问题,因为 Capist运行o 使用符号链接来处理版本,所以我不能只将 /current 文件夹挂载到 /code.

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

少量编辑:

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/

Where to Store Data

Important note: There are several ways to store data used by applications that run in Docker containers. We encourage users of the mongo images to familiarize themselves with the options available, including:

Let Docker manage the storage of your database data by writing the database files to disk on the host system using its own internal volume management. This is the default and is easy and fairly transparent to the user. The downside is that the files may be hard to locate for tools and applications that run directly on the host system, i.e. outside containers.

Create a data directory on the host system (outside the container) and mount this to a directory visible from inside the container. This places the database files in a known location on the host system, and makes it easy for tools and applications on the host system to access the files. The downside is that the user needs to make sure that the directory exists, and that e.g. directory permissions and other security mechanisms on the host system are set up correctly.

the source code is mounted on the /code volume

这就是问题所在,不是你想要的。

代码永远不会进入一个卷,它应该随着图像的变化而变化。卷用于您希望在图像更改之间保留的内容(数据、日志、状态等)。

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

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

如果您的 Dockerfile 用于 myphpfpmmynginx 在不同的目录中,您可以使用 docker build -f path/to/dockerfile .

进行构建

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