Dockerにおける「データ消失」という悪夢
Dockerを使い込んでいる方なら、午前2時にサーバーが突然ダウンしたときのあの「冷や汗」をかく感覚はよくご存知でしょう。重要なデータが入ったDockerボリュームが、跡形もなく消えてしまう恐怖。Dockerボリュームはデータの永続化を可能にしますが、外部へのバックアッププランなしにホストマシン上に放置しておくのは、非常にリスクの高い賭けと言わざるを得ません。
以前、私は Bash スクリプトを書き、ホストマシンに直接 zip や aws-cli をインストールして、Cronjob を設定していました。コンテナが1〜2個ならこれで十分です。しかし、システムがスケールし、複数のサーバーで数十ものスクリプトを管理するようになると、メンテナンスは地獄と化します。本来不要なツールをホストに詰め込むことで、システムは次第に「汚く」なっていきました。
30個のマイクロサービス運用から得た手痛い教訓
あるEコマースプロジェクトで30以上のマイクロサービスを運用していた際、メモリリークの原因を突き止めるためだけに丸2日間を費やしたことがあります。原因は、アプリケーションコンテナの内部でバックアップスクリプトをバックグラウンド実行させていたことでした。実行のたびに500MBのRAMを消費し、それが解放されなかったため、メインのアプリが頻繁にクラッシュしていたのです。この失敗を機に、私は Sidecar Container モデルへ完全に移行しました。半年以上の本番運用を経て、これが最もクリーンで安全な方法であると確信しています。
Sidecar Containerとは何か?なぜバックアップに最適なのか?
オートバイの横に取り付けられたサイドカー(側車)を想像してみてください。Dockerの世界では、Sidecarはメインコンテナと並行して動作し、メインのコードロジックに干渉することなくサポートを行うコンテナを指します。ログの記録、監視、そしてデータのバックアップといった補助的なタスクを担当します。
なぜSidecarがホスト上のスクリプトよりも優れているのでしょうか?
- リソースの分離 (Isolation): Sidecarにエラーが発生しても、メインのアプリを巻き込んでダウンさせることはありません.
- ポータビリティ (Portability): 設定は
docker-compose.yml内に完結します。ファイルを新しいサーバーにコピーするだけで、ホストにツールを追加インストールすることなく、すぐに実行可能です。
実践:Amazon S3へのSidecarバックアップ設定
今回は offen/docker-volume-backup イメージを使用します。これは非常に軽量なツールで、S3やGCSからDropboxまで幅広くサポートしています。
ステップ1:S3情報の準備
あらかじめ、Access Key ID、Secret Access Key、Region、そして Bucket 名を用意しておいてください。IAMユーザーに s3:PutObject 権限があることを確認し、ファイルをクラウドにプッシュできるようにします。
ステップ2:Docker Composeの設定
保存が必要なMariaDBサービスがあると仮定します。docker-compose.yml は以下のように構成されます。
version: '3.8'
services:
db:
image: mariadb:10.6
environment:
MYSQL_ROOT_PASSWORD: secret_password
volumes:
- db_data:/var/lib/mysql
restart: always
backup:
image: offen/docker-volume-backup:latest
bind_volumes_from:
- db
environment:
AWS_ACCESS_KEY_ID: YOUR_ACCESS_KEY
AWS_SECRET_ACCESS_KEY: YOUR_SECRET_KEY
AWS_REGION: ap-southeast-1
S3_ENDPOINT: s3.amazonaws.com
S3_BUCKET_NAME: my-app-backups
S3_PATH: db-backups
BACKUP_CRON_EXPRESSION: "0 2 * * *"
BACKUP_FILENAME: "db-backup-%Y-%m-%dT%H-%M-%S.tar.gz"
BACKUP_RETENTION_DAYS: 30
restart: always
volumes:
db_data:
主要なパラメータの注意点:
bind_volumes_from: Sidecarがdbサービスのすべてのボリュームを自動的に認識し、マウントするための仕組みです。BACKUP_RETENTION_DAYS: 30日以上前の古いバックアップを自動削除することで、ストレージコストを最大70%削減できます。
代替案:Rcloneを使用してGoogle Driveへバックアップする
Google Driveの15GBの無料枠を活用したい場合は、rclone がより柔軟な選択肢となります。以下のように最小限のSidecarを構築できます。
services:
app:
image: wordpress
volumes:
- wp_data:/var/www/html
backup-gdrive:
image: rclone/rclone:latest
volumes:
- wp_data:/data:ro
- ./rclone.conf:/config/rclone/rclone.conf
entrypoint: >
/bin/sh -c "
while true; do
filename=\"backup-$(date +%Y%m%d).tar.gz\"
tar -czf /tmp/$filename /data
rclone copy /tmp/$filename gdrive:MyBackups
rm /tmp/$filename
echo \"$(date) にバックアップが完了しました\"
sleep 86400
done"
volumes:
wp_data:
ヒント:あらかじめローカルマシンで rclone config を実行して設定ファイルを取得し、それをサーバーに配置してください。
運用現場で生き残るための経験則
度重なるトラブル対応を経て、私は4つの黄金律にたどり着きました。
- 常にデータを圧縮する:
tar -gzの使用は必須です。容量の節約だけでなく、クラウドへ転送する際の帯域コスト(Egress)も大幅に削減できます。 - 読み取り専用(Read-Only)を優先する: ボリュームをSidecarにマウントする際は、常に
:roタグを付けてください。これにより、Sidecarが誤ってアプリの元データを上書きしてしまうリスクを防げます。 - 定期的なファイルチェック: ログの「Success」という文字を過信しないでください。月に一度はバックアップファイルをダウンロードして解凍を試しましょう。コピー時にデータベースがロックされていたため、バックアップファイルが0KBだったという苦い経験があります。
- パスワードを絶対にハードコードしない:
.envファイルを使用してください。ハッカーにAWSアカウントをプレゼントしたいのでなければ、Access KeyをGitHubに直接コミットしてはいけません。
おわりに
Sidecar Containerはシステムアーキテクチャをよりプロフェッショナルにするだけでなく、データにとって価値のある「保険」となります。今日15分かけて設定を行うだけで、予期せぬハードウェア障害を恐れることなく、枕を高くして眠ることができるようになるでしょう。

