Docker data only容器和处理新版本

Docker data only容器和处理新版本,docker,production-environment,dockerfile,docker-compose,Docker,Production Environment,Dockerfile,Docker Compose,我一直在研究Docker的很多实践,并取得了很大的进展。 但有一件事一直困扰着我,那就是只使用数据容器 以下是我当前设置的简要概述: # nginx web: extends: file: _common.yml service: web ports: - "80:80" environment: APPLICATION_ENV: prod volumes_from: - data links: - db - redis

我一直在研究Docker的很多实践,并取得了很大的进展。 但有一件事一直困扰着我,那就是只使用数据容器

以下是我当前设置的简要概述:

# nginx
web:
  extends:
    file: _common.yml
    service: web
  ports:
    - "80:80"
  environment:
    APPLICATION_ENV: prod
  volumes_from:
    - data
  links:
    - db
    - redis

# php5-cli
app:
  extends:
    file: _common.yml
    service: app
  environment:
    APPLICATION_ENV: prod
  volumes_from:
    - data
  links:
    - db
    - redis

data:
  image: <censored-url>
  volumes:
    - "/var/lib/mysql"
    - "/app"

# percona
db:
  extends:
    file: _common.yml
    service: db
  volumes_from:
    - data

# redis
redis:
  extends:
    file: _common.yml
    service: redis
现在这个设置可以工作了,但我就是不知道如何处理新版本。 我的源代码是git,当我想部署到生产环境时,我想象我创建了一个新映像(来自busybox的映像可能应该替换为我现有的映像url),并在我的生产服务器上引入新映像

但是,我如何为我的web容器等获取要更新的数据呢?我还必须确保我的持久数据(/var/lib/mysql)仍然存在


我希望问题清楚,必要时我很乐意澄清。

我会从数据容器中删除
/app
目录,并使用docker compose构建它:

web:
  build: .
  extends:
    file: _common.yml
    service: web
  ports:
    - "80:80"
  environment:
    APPLICATION_ENV: prod
  links:
    - db
    - redis

app:
  extends:
    file: _common.yml
    service: app
  environment:
    APPLICATION_ENV: prod
  volumes_from:
    - data
  links:
    - db
    - redis

data:
  volumes:
    - "/var/lib/mysql"

db:
  extends:
    file: _common.yml
    service: db
  volumes_from:
    - data

redis:
  extends:
    file: _common.yml
    service: redis
Dockerfile

FROM busybox

ADD . /app

WORKDIR /app
您可以为不同的版本使用标记,这是我在部署中使用的脚本

DOCKER_HUB_USER="therightplace"
DOCKER_COMPOSE_IMAGE="projectname_web_1"
APP_IMAGE="nicer_name"
REMOTE_IMAGE=${DOCKER_HUB_USER}/${APP_IMAGE}
IMAGE_TAG=$(date -u +"%Y-%m-%dT%H:%M:%SZ" |sed 's/-\|:/_/g')
TAGGED_IMAGE=${REMOTE_IMAGE}:${IMAGE_TAG}
LATEST_IMAGE=${REMOTE_IMAGE}:latest

build_image () {
    echo "Building image: ${TAGGED_IMAGE}"
    docker-compose build web
}

push_tagged_image () {
    echo ${TAGGED_IMAGE}
    # change docker-compose image tag for a nicer one
    docker tag ${DOCKER_COMPOSE_IMAGE} ${TAGGED_IMAGE}
    # push image out to docker hub
    docker push ${TAGGED_IMAGE} && echo "${TAGGED_IMAGE} image pushed to docker hub" \
    || echo "Failed to push ${TAGGED_IMAGE} image to docker hub"
}

push_latest_image () {
    echo ${LATEST_IMAGE}
    # push image out to docker hub
    docker tag ${TAGGED_IMAGE} ${LATEST_IMAGE}
    docker push ${LATEST_IMAGE} && echo "${LATEST_IMAGE} image pushed to docker hub" \
    || echo "Failed to push ${LATEST_IMAGE} image to docker hub"
}
该脚本将构建服务web并将其推送到docker hub。您可以省略推送,只标记图像

您可以使用git哈希,而不是使用发布的时间戳:

IMAGE_TAG=$(git rev-parse --short HEAD)
现在这个设置可以工作了,但我就是不知道如何处理一个新的问题 释放。我的源代码是git,当我想部署到生产环境时 假设我创建了一个新映像(来自busybox的映像可能应该被替换) 使用我现有的图像url)并在我的产品上拉入新图像 服务器

除了关于busybox的声明(我不这么认为),这似乎非常正确。通常,您会重新构建映像,将其推送到注册表,然后从生产服务器中取出。正如@Mario Marin所建议的,在标签方面做得聪明是值得的,这样你就可以在需要的时候轻松地回滚,并且你确切地知道部署了哪个版本的应用程序

但是,我如何为我的web容器等获取要更新的数据呢?我还必须确保我的持久数据(/var/lib/mysql)仍然存在

我假设这是指您的数据容器,您以一种不寻常的方式完成了这项工作。首先,我将拉出mysql目录并将其放入自己的数据容器中。我将使用percona映像来实现这一点,以便正确设置所有权限。当您创建数据容器时,您不会让它一直运行,因此无需担心容器过时;它实际上只是目录的名称空间

下一步是处理应用程序目录,我假设它不是数据,而是代码?在这种情况下,我会将其包含在您的web映像中(根本不使用卷)。在Dockerfile中,我通常会进行git克隆,以使图像保持最新。在开发过程中,您可以使用来自主机的代码在应用程序目录顶部装载一个卷,以便可以立即进行更改


有关数据容器的更多信息,请查看

谢谢您的回答Mario。我的“web”服务实际上是我的web服务器,所以你建议将我的项目文件和我的web服务器捆绑在一个容器中吗?@RickKuipers不,你的web服务器应该只有资产而不是整个项目,即:
/var/www/public/assets
。与应用程序容器中的卷共享此目录。谢谢Adrian Mouat!你已经回答了我所有的问题:)。
IMAGE_TAG=$(git rev-parse --short HEAD)