|
| 1 | +# `.env` を置けず、リポジトリのクローンもできない実行環境向けの単体定義。 |
| 2 | +# (NASのコンテナマネージャー等、管理画面にYAMLを貼り付けて起動するタイプの環境を想定) |
| 3 | +# |
| 4 | +# docker-compose.yml との違いは2点だけ: |
| 5 | +# 1. `${...}` を使わず、値をYAMLに直接書く(`.env`もシェルの環境変数も無い前提のため) |
| 6 | +# 2. bindマウントを相対パス(./db・./photos)ではなく絶対パスで書く |
| 7 | +# (管理画面から登録する環境では相対パスの基準が分かりにくいため) |
| 8 | +# サービス構成・起動順(db-init → db → db-migrate → app)は本番用と同じ。 |
| 9 | +# |
| 10 | +# 使い方: |
| 11 | +# 1. 「ここだけ編集」の置き場を、そのホストの絶対パスに書き換える |
| 12 | +# 2. SESSION_SECRET に32バイト程度のランダム文字列を設定する(必須) |
| 13 | +# 3. その内容を管理画面に貼り付けて起動する |
| 14 | +# 4. http://<ホスト>:3000/ を開く(初回アクセス時のセットアップで管理者アカウントを作る) |
| 15 | +# |
| 16 | +# 更新は管理画面の「イメージを最新にして再作成」相当の操作(`docker compose pull` + |
| 17 | +# `up -d`)だけでよい。未適用のマイグレーションは db-migrate が自動で当てる。 |
| 18 | +# 特定時点に戻したいときは、下の2つの image のタグを `latest` から |
| 19 | +# `sha-xxxxxxx`(Actionsが付けるコミットSHAタグ)に変える —— ただしマイグレーションは |
| 20 | +# 前進のみで巻き戻せないため、スキーマ変更を伴うリリースを戻すにはDBのリストアが要る。 |
| 21 | +# |
| 22 | +# 通常の(リポジトリを配置できる)環境では docker-compose.yml を使う |
| 23 | +# ——こちらは値の直書きぶん古くなりやすい。 |
| 24 | + |
| 25 | +name: travel-log |
| 26 | + |
| 27 | +# ---- ここだけ編集: データの置き場(すべてホストの絶対パス) ---- |
| 28 | +# db … db-init が中に data/ を作る親ディレクトリ |
| 29 | +# db-data… Postgresの実データ。**必ず db の直下の data にすること** |
| 30 | +# (db-init が /db/data を作って postgres(uid/gid 70)に chown するため) |
| 31 | +# photos … 訪問記録の写真。DBには相対パスだけが入るので、DBと一緒にバックアップする |
| 32 | +# いずれも無ければDockerが自動作成するが、先に作っておくのが確実。 |
| 33 | +x-db-dir: &db-dir "/path/to/travel-log/db" |
| 34 | +x-db-data-dir: &db-data-dir "/path/to/travel-log/db/data" |
| 35 | +x-photos-dir: &photos-dir "/path/to/travel-log/photos" |
| 36 | + |
| 37 | +# ---- ここだけ編集: アプリの設定(.env の代わり) ---- |
| 38 | +# セッションCookieの署名鍵(必須)。32バイト程度のランダム文字列を入れる |
| 39 | +# (生成例: openssl rand -base64 32)。空のままだとログイン時に |
| 40 | +# "SESSION_SECRET is not set" で失敗する。変更すると既存のログインセッションは |
| 41 | +# すべて無効になる(再ログインすれば直る)。 |
| 42 | +x-session-secret: &session-secret "" |
| 43 | +# Googleでログイン(任意)。空のままならメールログインのみ。 |
| 44 | +# 取得方法・リダイレクトURIの設定はREADMEの「Googleログインの設定」参照 |
| 45 | +x-google-client-id: &google-client-id "" |
| 46 | +x-google-client-secret: &google-client-secret "" |
| 47 | +# 公開URL(任意。例: "https://travel.example.com")。 |
| 48 | +# リバースプロキシ越し(HTTPS終端あり)で使う場合、プロキシが X-Forwarded-Proto / |
| 49 | +# X-Forwarded-Host を送らない構成だと、Googleログインのリダイレクトが http:// で |
| 50 | +# 組まれて認証に失敗する。そのときはここに公開URLを書いて明示する。 |
| 51 | +# 直接 http://<ホスト>:3000 で使うなら空のままでよい。 |
| 52 | +x-public-base-url: &public-base-url "" |
| 53 | + |
| 54 | +services: |
| 55 | + # dbの起動前に、bindマウント先(db/data)の作成と所有者調整を行うワンショット |
| 56 | + # (詳細は db/entrypoint.sh の prepare 関数のコメント参照)。 |
| 57 | + db-init: |
| 58 | + image: ghcr.io/rtcode337/travel-log-db-init:latest |
| 59 | + user: root |
| 60 | + volumes: |
| 61 | + - type: bind |
| 62 | + source: *db-dir |
| 63 | + target: /db |
| 64 | + command: ["prepare"] |
| 65 | + restart: "no" |
| 66 | + |
| 67 | + db: |
| 68 | + image: postgres:16-alpine |
| 69 | + depends_on: |
| 70 | + db-init: |
| 71 | + condition: service_completed_successfully |
| 72 | + environment: |
| 73 | + # ホストにポート公開しないコンテナ間だけの接続。変えるなら db-migrate の |
| 74 | + # PG* と app の DATABASE_URL も同じ値に揃えること |
| 75 | + POSTGRES_USER: travel_log |
| 76 | + POSTGRES_PASSWORD: travel_log |
| 77 | + POSTGRES_DB: travel_log |
| 78 | + volumes: |
| 79 | + # db/init はマウントしない。スキーマ本体(01_schema.sql)は db-migrate が流す |
| 80 | + - type: bind |
| 81 | + source: *db-data-dir |
| 82 | + target: /var/lib/postgresql/data |
| 83 | + healthcheck: |
| 84 | + test: ["CMD-SHELL", "pg_isready -U travel_log"] |
| 85 | + interval: 5s |
| 86 | + timeout: 5s |
| 87 | + retries: 10 |
| 88 | + restart: unless-stopped |
| 89 | + |
| 90 | + # スキーマ本体(/init/01_schema.sql)と未適用のマイグレーション(/migrations/*.sql)を |
| 91 | + # 順に適用するワンショット。適用済みリビジョンは schema_migrations テーブルに記録され、 |
| 92 | + # 2回目以降は何もせず終了する。app はこれが正常終了するまで起動しない |
| 93 | + # (古いスキーマのままアプリが動くのを防ぐ)。 |
| 94 | + db-migrate: |
| 95 | + image: ghcr.io/rtcode337/travel-log-db-init:latest |
| 96 | + depends_on: |
| 97 | + db: |
| 98 | + condition: service_healthy |
| 99 | + environment: |
| 100 | + PGHOST: db |
| 101 | + PGUSER: travel_log |
| 102 | + PGPASSWORD: travel_log |
| 103 | + PGDATABASE: travel_log |
| 104 | + restart: "no" |
| 105 | + |
| 106 | + app: |
| 107 | + image: ghcr.io/rtcode337/travel-log:latest |
| 108 | + depends_on: |
| 109 | + db-migrate: |
| 110 | + condition: service_completed_successfully |
| 111 | + environment: |
| 112 | + DATABASE_URL: postgres://travel_log:travel_log@db:5432/travel_log |
| 113 | + # 値は冒頭の「ここだけ編集」にまとめてある |
| 114 | + SESSION_SECRET: *session-secret |
| 115 | + GOOGLE_CLIENT_ID: *google-client-id |
| 116 | + GOOGLE_CLIENT_SECRET: *google-client-secret |
| 117 | + PUBLIC_BASE_URL: *public-base-url |
| 118 | + NODE_ENV: production |
| 119 | + volumes: |
| 120 | + # 訪問記録の写真ファイル置き場(lib/photoStorage.ts)。DBには相対パスのみ保存される |
| 121 | + - type: bind |
| 122 | + source: *photos-dir |
| 123 | + target: /app/photos |
| 124 | + ports: |
| 125 | + # host:container。LAN内からのみ見える状態にしておくこと |
| 126 | + - "3000:3000" |
| 127 | + restart: unless-stopped |
0 commit comments