Docker Composeで自己ホストを始める — 最初の一歩
本記事はアフィリエイト広告(A8.net)を含みます。価格・仕様は2026年6月時点の目安です。最新は各公式サイトでご確認ください。
TL;DR
- 自己ホスト(セルフホスト)アプリの管理は Docker Compose から始めるのが扱いやすい。理由は 再現性・隔離・更新のしやすさの3点。
- 設定は
docker-compose.ymlという1ファイルに集約する。services/volumes/networks/portsの4要素を押さえれば最小構成は書ける。 - データは named volume か bind mount で必ずコンテナ外に逃がす。これを忘れるとコンテナを作り直した瞬間にデータが消える。
- アップデートは
docker compose pull→docker compose up -dの2コマンドで完結する。 - 複数サービスを1台で公開するなら リバースプロキシを1つ前段に置く。
- バックアップ対象は volume(とパスワードを書いた
.env)。コンテナ本体は使い捨てでよい。
なぜDocker Composeが自己ホストに向くのか
自己ホストを始めると、アプリごとに「依存ライブラリのバージョンが違う」「設定ファイルがOSのあちこちに散る」「アンインストールしても残骸が残る」といった問題に必ずぶつかります。Docker と Docker Compose は、この3つを構造的に解決します。
再現性
docker-compose.yml には、使うイメージのバージョン・公開ポート・環境変数・ボリュームがすべて書かれます。このファイルさえあれば、別のVPSに移しても docker compose up -d で同じ状態を再現できます。「動いていたサーバーが壊れたが、設定を覚えていない」という事態を防げます。
隔離
各サービスはコンテナという独立した環境で動きます。あるアプリが特定バージョンのデータベースを要求し、別のアプリが別バージョンを要求しても、互いに干渉しません。ホストOSの apt で入れたパッケージを汚すこともありません。
更新のしやすさ
イメージのタグを更新して pull し直すだけでバージョンを上げられます。問題があれば古いタグに戻すだけでロールバックできます。OS上に直接インストールした場合の「アップデートで依存が壊れて元に戻せない」リスクを大きく減らせます。
ホームラボ全体の考え方や機材の選び方は 自宅サーバー・ホームラボ入門 も参考にしてください。
Docker Composeの基本構造
docker-compose.yml は YAML 形式のファイルです。主要な要素は次の4つです。
| 要素 | 役割 |
|---|---|
services | 起動するコンテナの定義。アプリ単位で書く |
volumes | データの永続化先。コンテナを消してもデータを残す |
networks | コンテナ間の通信を制御する仮想ネットワーク |
ports | ホストのポートをコンテナのポートに割り当てる公開設定 |
services 以下に書く主なキーは次のとおりです。
| キー | 意味 |
|---|---|
image | 使用するイメージ名とタグ(例: nginx:1.27) |
restart | 再起動ポリシー(unless-stopped が無難) |
ports | "ホスト側:コンテナ側" の形式でポートを公開 |
volumes | "ボリューム名またはパス:コンテナ内パス" でデータを接続 |
environment | コンテナに渡す環境変数 |
env_file | 環境変数をまとめたファイル(.env)を指定 |
最小のdocker-compose.yml例
まずは作業用ディレクトリを作ります。
mkdir -p /opt/myapp && cd /opt/myapp
汎用的なWebアプリ(ここでは静的配信の例として Nginx)を1つ動かす最小構成です。
services:
web:
image: nginx:1.27
container_name: myapp-web
restart: unless-stopped
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
起動します。
docker compose up -d
-d(detached)でバックグラウンド起動します。状態とログは次のコマンドで確認できます。
docker compose ps
docker compose logs -f web
ports の "8080:80" は「ホストの8080番に来たアクセスを、コンテナの80番に転送する」という意味です。ブラウザで http://サーバーのIP:8080 を開くと、./html 以下のファイルが配信されます。
停止と削除は次のとおりです。
docker compose down
down はコンテナとネットワークを削除しますが、named volume のデータは残ります(後述)。
データの永続化 — named volume と bind mount
コンテナは本来「使い捨て」です。down して作り直すと、コンテナ内に書き込んだデータは消えます。データを残すには、コンテナの外にデータを逃がす設定が必要です。方法は2つあります。
| 方式 | 書き方 | 向いている用途 |
|---|---|---|
| named volume | dbdata:/var/lib/mysql | データベースなどDockerに管理を任せたいデータ |
| bind mount | ./config:/etc/app | 設定ファイルなど自分で直接編集したいファイル |
データベースを足した例です。
services:
app:
image: ghcr.io/example/app:1.4
container_name: myapp
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- ./config:/etc/app # bind mount: 設定ファイル
depends_on:
- db
db:
image: postgres:16
container_name: myapp-db
restart: unless-stopped
environment:
POSTGRES_USER: appuser
POSTGRES_PASSWORD: changeme
POSTGRES_DB: appdb
volumes:
- dbdata:/var/lib/postgresql/data # named volume: DBデータ
volumes:
dbdata:
volumes: のトップレベル宣言(最下部の dbdata:)で named volume を定義し、db サービス内でマウントしています。これにより docker compose down してもDBデータは保持されます。
bind mount(./config:/etc/app)は、ホスト上の ./config ディレクトリをそのままコンテナ内に見せる方式です。設定ファイルを手元のエディタで編集したい場合に便利です。
named volume の中身は次のコマンドで確認できます。
docker volume ls
docker volume inspect myapp_dbdata
ボリューム名には自動でプロジェクト名(ディレクトリ名)がプレフィックスとして付くため、dbdata は実際には myapp_dbdata になります。
環境変数と.env
パスワードやAPIキーを docker-compose.yml に直接書くと、ファイルを共有・コミットしたときに漏れます。秘密情報は .env ファイルに分離します。
同じディレクトリに .env を置くと、Compose は自動で読み込みます。
.env:
POSTGRES_USER=appuser
POSTGRES_PASSWORD=ぜったいに推測されない長い文字列
POSTGRES_DB=appdb
docker-compose.yml 側では ${変数名} で参照します。
services:
db:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- dbdata:/var/lib/postgresql/data
volumes:
dbdata:
.env は必ず Git の管理対象から外します。
echo ".env" >> .gitignore
値が正しく展開されているかは、起動前に次のコマンドで確認できます。
docker compose config
config は変数を展開した最終的な設定を出力します。実行前にここで確認しておくと、変数の打ち間違いに気づけます。
アップデート手順
イメージを最新化する手順は2コマンドです。
docker compose pull # 新しいイメージを取得
docker compose up -d # 差分のあるコンテナだけ再作成
up -d は、イメージが更新されたサービスだけを作り直します。データは volume に残っているため、アップデートしてもデータは引き継がれます。
不要になった古いイメージはディスクを圧迫するので、定期的に掃除します。
docker image prune
タグ運用の注意:
latestタグは便利な反面、いつの間にか大きなバージョンに上がって互換性が壊れることがあります。本番ではpostgres:16のようにメジャー(または固定)タグを明示し、更新内容を確認してから上げる運用が安全です。
リバースプロキシで複数サービスを公開する
サービスが増えると、http://IP:8080、http://IP:3000 のようにポート番号で出し分けるのは現実的ではありません。HTTPS化も各サービスごとに行うのは煩雑です。そこで、前段にリバースプロキシを1つ置き、ドメイン名でサービスを振り分けます。
┌──────────────┐
app1.example.com → │ │ → app1 コンテナ
app2.example.com → │ リバース │ → app2 コンテナ
│ プロキシ │
(443/HTTPS) └──────────────┘
代表的な選択肢は次のとおりです。
| プロキシ | 特徴 |
|---|---|
| Nginx | 実績が豊富。設定ファイルを自分で書く |
| Caddy | 設定が簡潔で、Let’s Encrypt による自動HTTPSが標準 |
| Traefik | Composeのラベルから自動でルーティングを生成 |
プロキシと各アプリは、同じ Compose ネットワーク(または共有ネットワーク)に所属させて、サービス名で通信させます。このとき各アプリは ports でホストに直接公開せず、プロキシ経由だけで到達させるのが安全です。HTTPS化(Let’s Encrypt)と組み合わせれば、外部にはプロキシの443番だけを開ければ済みます。
Bitwarden互換の Vaultwardenを自社構築する手順 でも、同じくリバースプロキシ前段でHTTPS化する構成を採用しています。具体的なプロキシ設定の流れはそちらが参考になります。
バックアップ対象は「volume」
Docker Compose 運用でバックアップすべきものは明確です。
| 対象 | バックアップ要否 | 理由 |
|---|---|---|
| named volume / bind mount のデータ | 必須 | アプリの実データ。失うと復旧できない |
.env | 必須 | DBパスワード等。これがないとDBを開けない |
docker-compose.yml | 推奨 | 構成の再現に必要(Gitで管理が理想) |
| コンテナ・イメージ本体 | 不要 | pull で再取得できる使い捨て |
named volume の中身をアーカイブする一例です。busybox コンテナにボリュームをマウントし、ホストの現在ディレクトリへ tar で固めます。
docker run --rm \
-v myapp_dbdata:/data:ro \
-v "$(pwd)":/backup \
busybox tar czf /backup/dbdata-$(date +%F).tar.gz -C /data .
データベース(PostgreSQLなど)の場合は、volume を直接固めるより pg_dump などアプリ純正のダンプを取る方が整合性の面で安全です。取得したバックアップは別の場所へ複製しておきます。バックアップの設計思想は 3-2-1バックアップ戦略 で詳しく扱っています。
どのVPSで動かすか
Docker Compose による自己ホストは、月数百円〜千円台のVPSでも十分始められます。日本国内で実績があり、Dockerをそのまま動かせる代表的な選択肢が以下の2つです。
| VPS | 特徴 |
|---|---|
| ConoHa VPS | 時間課金にも対応。テンプレートやコントロールパネルが整理されていて初学者でも扱いやすい |
| Xserver VPS | レンタルサーバーで実績のあるエックスサーバー運営。コストパフォーマンス重視の構成を組みやすい |
どちらも Ubuntu などの Linux ディストリビューションを選べば、apt で Docker を入れて本記事の手順をそのまま実行できます。スペックは「1vCPU・メモリ1〜2GB」あたりから始めて、動かすアプリの数に応じて上げていくのが現実的です。個人用途のVPS比較は 個人開発者向けVPS選び も参考にしてください。
まとめ
| ポイント | 要点 |
|---|---|
| なぜCompose | 再現性・隔離・更新のしやすさ。yml1ファイルに構成を集約 |
| 基本4要素 | services / volumes / networks / ports |
| データ永続化 | named volume(DB等)と bind mount(設定)でコンテナ外へ |
| 秘密情報 | .env に分離し .gitignore に追加。docker compose config で確認 |
| アップデート | docker compose pull → docker compose up -d |
| 複数公開 | リバースプロキシを前段に1つ置きドメインで振り分け |
| バックアップ | 守るのは volume と .env。コンテナ本体は使い捨て |
Docker Compose は、自己ホストの「動いていたものを再現できない」という最大の不安を構造的に取り除いてくれます。まずは本記事の最小構成を1つ動かし、volume と .env の扱いに慣れることから始めてください。
各サービス公式
VPSの契約は各公式サイトから行えます。