Docker
docker-compose

docker-composeで簡易デプロイ

More than 1 year has passed since last update.

docker-composeで動かしているWebサービスで、新しいイメージを簡単にデプロイする方法を模索していたので、メモしてみます。

※あくまで簡易的なデプロイ方法なので、ダウンタイムが発生します。

例えば以下のような docker-compose.yml/var/www/app に配置して運用しているとします。


docker-compose.yml

version: '2'

services:
app:
image: registry.gitlab.com/your-name/your-project:latest
container_name: app
ports:
- 8080:80
volumes:
- ./data:/app/data
depends_on:
- mongo
mongo:
image: mongo:latest
container_name: mongo
volumes:
- ./mongo:/db/data

ここで使っているregistryに最新のイメージをプッシュした後、このappサービスのコンテナを新しいイメージのものに入れ替えたい、というユースケースです。

以下のようなスクリプトを配置します。


deploy.sh

#!/bin/bash

IMAGE=registry.gitlab.com/your-name/your-project
IMAGE_TAG=latest
CONTAINER_NAME=app
CONTAINER_ID=`docker container ls -aqf "name=$CONTAINER_NAME"`

cd /var/www/app
docker image pull $IMAGE:$IMAGE_TAG
docker-compose stop $CONTAINER_NAME
docker container rm $CONTAINER_ID
docker-compose up --no-deps -d $CONTAINER_NAME
docker image rm `docker image ls -qf "dangling=true" -f "reference=$IMAGE" | tr "\n" " "`




  1. docker image pull ...:新しいイメージをプルします。このとき既存のイメージはタグが外れ、新しいイメージにタグが割り当てられます。


  2. docker-compose stop ...:appサービスのみ停止します。


  3. docker container rm ...:appサービスのコンテナを削除します。


  4. docker-compose up ...:新しいappコンテナを立ち上げます。このとき先程プルした新しいイメージが使用されます。


  5. docker image rm ...docker image ls で、タグが外れた(dangling)古いイメージのIDを取得し、docker image rm でイメージを削除します。

container registryに新しいイメージをプッシュしたあと、(例えばCIからSSH経由で)このdeploy.shを叩くことで、docker-composeのappサービスが新しいイメージのものと入れ替わり、古いイメージが削除されます。

特に最後の古いイメージを削除するのを忘れてしまうと、デプロイの度にサーバーのストレージに古いイメージが溜まり、容量がどんどん圧迫されていくので要注意です。