Docker Composeで自己ホストを始める — 最初の一歩

VPS・サーバー選定中級
DockerDocker ComposeSelf-hostedVPSLinux

本記事はアフィリエイト広告(A8.net)を含みます。価格・仕様は2026年6月時点の目安です。最新は各公式サイトでご確認ください。

TL;DR

  • 自己ホスト(セルフホスト)アプリの管理は Docker Compose から始めるのが扱いやすい。理由は 再現性・隔離・更新のしやすさの3点。
  • 設定は docker-compose.yml という1ファイルに集約する。services / volumes / networks / ports の4要素を押さえれば最小構成は書ける。
  • データは named volume か bind mount で必ずコンテナ外に逃がす。これを忘れるとコンテナを作り直した瞬間にデータが消える。
  • アップデートは docker compose pulldocker 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 volumedbdata:/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:8080http://IP:3000 のようにポート番号で出し分けるのは現実的ではありません。HTTPS化も各サービスごとに行うのは煩雑です。そこで、前段にリバースプロキシを1つ置き、ドメイン名でサービスを振り分けます。

                      ┌──────────────┐
  app1.example.com →  │              │ → app1 コンテナ
  app2.example.com →  │ リバース     │ → app2 コンテナ
                      │ プロキシ     │
       (443/HTTPS)    └──────────────┘

代表的な選択肢は次のとおりです。

プロキシ特徴
Nginx実績が豊富。設定ファイルを自分で書く
Caddy設定が簡潔で、Let’s Encrypt による自動HTTPSが標準
TraefikComposeのラベルから自動でルーティングを生成

プロキシと各アプリは、同じ 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 pulldocker compose up -d
複数公開リバースプロキシを前段に1つ置きドメインで振り分け
バックアップ守るのは volume と .env。コンテナ本体は使い捨て

Docker Compose は、自己ホストの「動いていたものを再現できない」という最大の不安を構造的に取り除いてくれます。まずは本記事の最小構成を1つ動かし、volume と .env の扱いに慣れることから始めてください。


各サービス公式

VPSの契約は各公式サイトから行えます。

ConoHa VPS

Xserver VPS

関連記事

VPS・サーバー選定コンテナとVMの違いと使い分け — DockerとVMをいつ選ぶかVPS・サーバー選定PostgreSQLパフォーマンスチューニング: 中小企業DBの遅延を解消する手順VPS・サーバー選定高可用性(HA)構成の最小コスト実装:2台のVPSでフェイルオーバーを組む
記事一覧に戻る