Docker仅数据容器并处理新版本

时间:2015-04-05 20:49:19

标签: 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

# 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

您看到的<censored-url>是使用此Dockerfile构建的图像:

FROM busybox
COPY . /app

现在这个设置有效,但我无法弄清楚如何处理新版本。 我的源代码是git,当我想部署到生产时,我想我创建了一个新图像(FROM busybox可能应该用我现有的图像URL替换)并在我的生产服务器上提取新图像。

但是如何为我的网络容器更新数据呢?我还必须确保我的持久数据(/ var / lib / mysql)仍然存在。

我希望问题很明确,我很乐意在必要时澄清。

2 个答案:

答案 0 :(得分:2)

  

现在这个设置有效,但我无法弄清楚如何处理新的   发布。当我想部署到生产时,我的源代码是git   想象一下我创建了一个新图像(FROM busybox应该可以替换掉   用我现有的图像url)并在我的制作中拉入新图像   服务器

除了关于busybox的声明(我没有遵循),这似乎非常正确。通常,您重新构建映像,推送到注册表,然后从生产服务器中提取。正如@Mario Marin建议的那样,值得对标签做一些聪明的事情,以便您可以根据需要轻松回滚,并确切知道应用的哪个版本。

  

但是如何为我的网络容器更新数据呢?我还必须确保我的持久数据(/ var / lib / mysql)仍然存在。

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

下一步是处理app目录,我假设它不是数据,而是代码?在这种情况下,我会将其包含在您的Web图像中(根本不要使用卷)。在Dockerfile中,我通常会使用git clone来保持映像的最新状态。在开发期间,您可以使用来自主机的代码在app目录的顶部安装卷,以便您可以立即进行更改。

有关数据容器的更多信息,请查看http://container42.com/2014/11/18/data-only-container-madness/

答案 1 :(得分:1)

我会从数据容器中删除/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

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

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 hash:

,而不是为您的版本使用时间戳
IMAGE_TAG=$(git rev-parse --short HEAD)