2

I've been researching a lot of practices around Docker and have come quite far. But there's one thing that keeps on puzzling me, working with data-only containers.

Here's a brief overview of my current setup:

# 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

The <censored-url> that you see is an image build with this Dockerfile:

FROM busybox
COPY . /app

Now this setup works but I just can't figure out how to handle a new release. My source is in git, when I want to deploy to production I imagine I create a new image (FROM busybox should probably be replaced with my existing image url) and pull in the new image on my production server.

But how do I get the data to update for my web container and such? I also have to make sure my persistent data (/var/lib/mysql) remains.

I hope the question is clear, I'd be happy to clarify when necessary.

4

2 回答 2

2

现在这个设置有效,但我只是不知道如何处理新版本。我的源代码在 git 中,当我想部署到生产环境时,我想我会创建一个新图像(FROM busybox 可能应该替换为我现有的图像 url)并在我的生产服务器上拉入新图像。

除了关于busybox的声明(我没有遵循)之外,这似乎非常正确。通常,您重新构建映像,推送到注册表,然后从生产服务器中提取。正如@Mario Marin 所建议的那样,对标签要聪明一点是值得的,这样您就可以在需要时轻松回滚,并且您确切地知道部署了哪个版本的应用程序。

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

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

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

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

于 2015-04-06T09:27:49.197 回答
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

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

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)
于 2015-04-05T23:29:08.113 回答