メインコンテンツにスキップ ナビゲーションにスキップ フッターにスキップ
期間限定:デザインパートナープログラム。BUSINESSプランはずっと無料

サービス

Rediaccfile、サービスネットワーキング、自動開始を使用してコンテナ化されたサービスをデプロイおよび管理します。

サービス

このページでは、以下の内容を説明します:コンテナ化されたサービスのデプロイと管理、Rediaccfile、サービスネットワーキング、開始/停止、一括操作、自動開始。

Rediaccfile

Rediaccfileは、サービスの開始と停止方法を定義するBashスクリプトです。(別プロセスとして実行されるのではなく)ソースされるため、関数は同じシェルコンテキストを共有し、エクスポートされたすべての環境変数にアクセスできます。ファイル名はRediaccfileまたはrediaccfile(大文字小文字を区別しない)で、リポジトリのマウントされたファイルシステム内に配置する必要があります。

Rediaccfileは2つの場所で検出されます:

  1. リポジトリマウントパスのルート
  2. マウントパスの第1レベルサブディレクトリ(再帰的ではありません)

隠しディレクトリ(.で始まる名前)はスキップされます。

ライフサイクル関数

Rediaccfileは最大2つの関数を含みます:

関数実行タイミング目的エラー動作
up()開始時サービスの開始(例:renet compose -- up -dルートの失敗はクリティカル(すべて停止)。サブディレクトリの失敗は非クリティカル(ログに記録し、続行)
down()停止時サービスの停止(例:renet compose -- downベストエフォート - 失敗はログに記録されますが、すべてのRediaccfileが常に試行されます

両方の関数はオプションです。関数が定義されていない場合、サイレントにスキップされます。

実行順序

  • 開始(up): ルートRediaccfileが最初、次にサブディレクトリがアルファベット順(AからZ)。
  • 停止(down): サブディレクトリが逆アルファベット順(ZからA)、最後にルート。

環境変数

Rediaccfile関数の実行時、以下の環境変数が利用可能です:

変数説明
REDIACC_WORKING_DIRリポジトリのマウントパス/mnt/rediacc/mounts/abc123
REDIACC_REPOSITORYリポジトリGUIDa1b2c3d4-e5f6-...
REDIACC_NETWORK_IDネットワークID(整数)2816
DOCKER_HOSTこのリポジトリの隔離デーモン用Dockerソケットunix:///var/run/rediacc/docker-2816.sock
{SERVICE}_IP.rediacc.jsonで定義された各サービスのループバックIPPOSTGRES_IP=127.0.11.2

{SERVICE}_IP変数は.rediacc.jsonのスロットマッピングから自動生成され、Rediaccfile関数が実行される前にエクスポートされます。命名規則では、サービス名を大文字に変換し、ハイフンをアンダースコアに置き換え、_IPを付加します。例えば、スロット0listmonk-appというサービスはLISTMONK_APP_IP=127.0.11.2になります。

警告:Rediaccfile内でsudo dockerを使用しないでください。 sudoコマンドは環境変数をリセットするため、DOCKER_HOSTが失われ、Dockerコマンドがリポジトリの隔離デーモンではなくシステムデーモンを対象にします。これによりコンテナの隔離が壊れ、ポート競合が発生する可能性があります。Rediaccは-Eなしのsudo dockerを検出すると実行をブロックします。

Rediaccfile内ではrenet composeを使用してください。DOCKER_HOSTを自動的に処理し、ルート検出用のネットワーキングラベルを注入し、サービスネットワーキングを設定します。リバースプロキシ経由でサービスを公開する方法の詳細については、ネットワーキングを参照してください。Dockerを直接呼び出す場合は、sudoなしでdockerを使用してください。Rediaccfile関数は既に十分な権限で実行されます。sudoを使用する必要がある場合は、環境変数を保持するためにsudo -E dockerを使用してください。

renetはリモートロー・レベルツールです。ワークステーションから通常のユーザー作業フローを行う場合は、rdc repo uprdc repo downなどのrdcコマンドを優先してください。rdc vs renetを参照してください。

#!/bin/bash

up() {
    echo "Starting services..."
    renet compose -- up -d
}

down() {
    echo "Stopping services..."
    renet compose -- down
}

重要: docker composeの代わりに常にrenet compose --を使用してください。renet composeラッパーは、ホストネットワーキング、IPアロケーション、およびrenet-proxyに必要なサービスディスカバリラベルを強制適用します。CRIUチェックポイント/リストア機能はrediacc.checkpoint=trueラベル付きコンテナに追加されます。直接的なdocker composeの使用はRediaccfileのバリデーションで拒否されます。詳細についてはネットワーキングを参照してください。

ケーパビリティラベル

コンテナはデフォルトで最小限のLinuxケーパビリティセットで動作します。サービスが追加のケーパビリティを必要とする場合は、docker-compose.ymlにラベルを追加してオプトインします:

ラベル付与されるもの用途
rediacc.checkpoint=trueCHECKPOINT_RESTORESYS_PTRACENET_ADMINCRIUチェックポイント/リストア(ライブマイグレーション、保存と再開)
rediacc.wireguard=trueNET_ADMIN/dev/net/tun デバイスコンテナ内でWireGuardクライアントを実行
services:
  vpn:
    image: alpine
    labels:
      - "rediacc.wireguard=true"

rediacc.wireguard を使うと、サービスからWireGuardトンネルを確立できます。たとえば、特定のプロセスのトラフィックをリモートエンドポイント経由でルーティングする場合などに活用できます。すべてのサービスはホストネットワーキングで動作するため、ホストのルーティングに影響が出ないよう、トンネルはコンテナ内のネットワーク名前空間に閉じ込めてください。privileged: truepid: hostipc: host などの広範な特権オプションは、ラベルに関わらずバリデーションで拒否されます。

マルチサービスレイアウト

複数の独立したサービスグループを持つプロジェクトでは、サブディレクトリを使用します:

/mnt/rediacc/repos/my-app/
├── Rediaccfile              # ルート:共有セットアップ
├── docker-compose.yml
├── database/
│   ├── Rediaccfile          # データベースサービス
│   └── docker-compose.yml
├── backend/
│   ├── Rediaccfile          # APIサーバー
│   └── docker-compose.yml
└── monitoring/
    ├── Rediaccfile          # Prometheus、Grafanaなど
    └── docker-compose.yml

upの実行順序:ルート、次にbackenddatabasemonitoring(A-Z)。 downの実行順序:monitoringdatabasebackend、最後にルート(Z-A)。

サービスネットワーキング(.rediacc.json)

各リポジトリは127.x.x.xループバック範囲内の/26サブネット(64個のIP)を取得します。サービスは一意のループバックIPにバインドされるため、競合なく同じポートで実行できます。

.rediacc.jsonファイル

サービス名をスロット番号にマッピングします。各スロットは、リポジトリのサブネット内の一意のIPアドレスに対応します。

{
  "services": {
    "api": {"slot": 0},
    "postgres": {"slot": 1},
    "redis": {"slot": 2}
  }
}

Docker Composeからの自動生成

.rediacc.jsonを手動で作成する必要はありません。rdc repo upを実行すると、Rediaccは自動的に以下を行います:

  1. Rediaccfileを含むすべてのディレクトリでcomposeファイル(docker-compose.ymldocker-compose.yamlcompose.yml、またはcompose.yaml)をスキャン
  2. services:セクションからサービス名を抽出
  3. 新しいサービスに次の利用可能なスロットを割り当て
  4. 結果を{repository}/.rediacc.jsonに保存

IP計算

サービスのIPは、リポジトリのネットワークIDとサービスのスロットから計算されます。ネットワークIDは127.x.y.zループバックアドレスの第2、第3、第4オクテットに分割されます。サービスはオフセット2から開始します:

OffsetAddressPurpose
.0127.0.11.0Network address (reserved)
.1127.0.11.1Gateway (reserved)
.2 - .62127.0.11.2 - 127.0.11.62Services (slot + 2)
.63127.0.11.63Broadcast (reserved)

:ネットワークID 28160x0B00)の場合、ベースアドレスは127.0.11.0

サービススロットIPアドレス
api0127.0.11.2
postgres1127.0.11.3
redis2127.0.11.4

各リポジトリは最大61個のサービス(スロット0から60)をサポートします。

Docker ComposeでのサービスIPの使用

各リポジトリは隔離されたDockerデーモンを実行するため、renet composeはすべてのサービスに対して自動的にnetwork_mode: hostを設定します。カーネルはbind()呼び出しをサービスに割り当てられたループバックIPに透過的に書き換えるため、サービスは競合なく0.0.0.0localhostにバインドできます。他のサービスへの接続にはサービス名を使用してください。renetはすべてのサービス名を常に正しいIPに解決するホスト名として注入します(フォークでも同様):

services:
  postgres:
    image: postgres:16
    environment:
      PGDATA: /var/lib/postgresql/data
      POSTGRES_PASSWORD: secret
    # 明示的なlisten_addressesは不要 - カーネルがbindを正しいループバックIPに書き換えます

  api:
    image: my-api:latest
    environment:
      DATABASE_URL: postgresql://postgres:secret@postgres:5432/mydb  # サービス名を使用
      LISTEN_ADDR: 0.0.0.0:8080                                      # カーネルがサービスIPに書き換え

接続へのサービス名の使用: 他のサービスへ接続する際はサービス名(例:postgresredis)を使用してください - renetは/etc/hosts経由で各サービス名をそのループバックIPに自動的にマッピングします。データベースや設定ファイルに保存された接続文字列に${POSTGRES_IP}を埋め込むと生のIPが固定され、フォークの隔離を壊すバリデーションエラーになります。${SERVICE_IP}変数は明示的な使用のために引き続き利用可能ですが、バインドはカーネルが自動的に処理します。

注意: network_mode: hostを手動で追加しないでください。renet composeが自動的に注入します。再起動ポリシー(例:restart: always)は安全に使用できます。renetはCRIU互換性のために自動的に削除し、ルーターウォッチドッグがコンテナの回復を処理します。

コンテナの回復と再起動ポリシー

renetとDockerは、コンテナの再起動処理について意図的に見解が異なります。この分離を理解することは、コンテナが戻った(戻らなかった)理由をデバッグする際に重要です。

再起動ポリシーの変換。 composeファイルにrestart: always(またはunless-stoppedon-failure)を書くと、renetは実際のcomposeデプロイメントを合成する際にそれを削除し、restart: noに置き換えます。元の値はリポジトリの.rediacc.jsonservices.<name>.restart_policyに保存されます。これにより、DockerデーモンレベルのAuto-RestartがCRIUチェックポイント/リストアを妨げるのを防ぎます(デーモン主導の再起動は古いチェックポイント前の状態から再開します)。

ウォッチドッグの適用。 ルーターウォッチドッグは各マシンで定期的に実行されます。各ティックで:

  1. 各リポジトリの.rediacc.jsonを読み込み、回復可能なrestart_policyを持つサービスを見つけます。
  2. そのリポジトリのデーモンのすべてのコンテナをリストし、停止しているものを特定し、保存されたポリシーに従って再起動します。30秒のグレース期間により、docker stopを実行したオペレーターとの競合を防ぎます。
  3. 同じループは/var/run/rediacc/cold-backup-<guid>.running.jsonも処理します(コールドバックアップのセマンティクスを参照)。リストされたコンテナは保存されたポリシーに関わらず再起動されます。サイドカーは「renetがこれらを意図的に停止し、オペレーターへの再起動を約束している」ことを意味するからです。

on-failureが壊れて見える理由。 Dockerのon-failureポリシーは、コンテナが非ゼロコードで終了した場合にのみ再起動します。docker stopやデーモンのシャットダウンによる正常な停止(exit 0)は「失敗」ではなく、Dockerのネイティブロジックでもウォッチドッグのポリシーパスでも再起動をトリガーしません。コールドバックアップサイドカーがセーフティネットです:意図的に停止したコンテナはポリシーに関わらず再起動されます。

ランタイム状態の解釈方法:

  • docker inspect <container> -> RestartPolicy.Name:renet管理コンテナでは常にnoになります。セマンティックポリシーの判断には使用しないでください。
  • リポジトリマウントルートの.rediacc.json -> services.<name>.restart_policy:真の意図。
  • docker ps --format '{{.Status}}':ランタイム状態。

ドリフトの修正方法。 コンテナの.rediacc.jsonに保存されたポリシーが誤っている場合(例:composeを編集したがコンテナを再作成しなかった場合)、rdc repo up --name <repo> -m <machine>を再実行してください。コンテナは更新されたポリシーを記録した状態で再作成されます。

実験的: コールドバックアップサイドカーベースの回復とrdc machine query--sync-certsフラグはrenet 0.9+で導入されました。古いバージョンはウォッチドッグ回復のために保存されたrestart_policyのみに依存するため、コールドバックアップ後にon-failureコンテナが孤立する可能性があります。

Docker のブリッジネットワーキングはリポジトリごとのデーモンでは無効化されています。 リポジトリごとの各デーモン(FlavorRediacc)は "bridge": "none""iptables": false で構成されています。リポジトリシェル内で単純に docker run <image> を実行してもコンテナは起動しますが、ループバックインターフェースしか持たず、DNS も外向きの接続性もありません。これは仕様です。なぜなら、リポジトリ間のループバック分離は eBPF の cgroup フックによって強制されており、ブリッジ化されたコンテナはそれを迂回してしまうからです。本番サービスは renet compose を使用してください(ホストネットワーキングを自動で注入してくれます)。アドホックなデバッグでは、明示的に --network host を指定してください: docker run --rm --network host -it ubuntu bash

ユーザーごとの Hub デーモン(FlavorHub、開発環境で使用)は例外です。これらは bridge="docker0"iptables=truelive-restore=true を設定することで、ユーザーが実行するコンテナが通常のブリッジネットワーキングと外向きの接続性を利用できるようにします。

注意: Forkリポジトリは親のサブドメイン下に自動ルートを取得します:{service}-fork-{tag}.{repo}.{machine}.{baseDomain}。カスタムドメインはforkでは省略されます。

サービスの開始

リポジトリをマウントし、すべてのサービスを開始します:

rdc repo up --name my-app -m server-1
オプション説明
--detachコンテナが起動した時点で制御を返す。ヘルスチェックはバックグラウンドで継続される
--skip-router-restart操作後にルートサーバーの再起動をスキップ

実行シーケンスは以下の通りです:

  1. LUKS暗号化リポジトリをマウント(未マウントの場合は自動マウント)
  2. 隔離Dockerデーモンを起動
  3. composeファイルから.rediacc.jsonを自動生成
  4. すべてのRediaccfileでup()を実行(A-Z順)

デプロイ後、出力には各サービスの実際のURLを示すPROXY ROUTESセクションが表示されます。カスタムTraefikラベルを持つサービス(例:traefik.http.routers.myapp.rule=Host(...))は、カスタムドメインをプライマリURLとして表示します:

HTTP services (accessible via proxy after ~3s):
  gitlab-server:
    HTTPS: https://gitlab.example.com  (custom)
    Auto:  https://gitlab-server.gitlab.server-1.example.com
    IP:    127.0.11.130

カスタムTraefikラベルを持たないサービスは、自動生成されたルートのみを表示します。ブラウザアクセス、API呼び出し、サービス間設定にはこれらのURL(CLIで表示される汎用パターンではなく)を使用してください。

デタッチ起動

--detach を指定すると、ヘルスチェックの完了を待たず、コンテナが起動した時点でコマンドが返ります。起動の残りはバックグラウンドで進行します。プロキシは各サービスがバインドするまでアップストリーム接続を自動的に再試行するため、ルートは自然に回復します。進捗は rdc machine query --containers --name <machine> で確認できます。次のステップでサービスが揃っている必要のないスクリプトや使い捨てフォークに最適です。

準備完了プローブ

up() の実行後、renet は各 HTTP サービスが TCP 接続を受け入れるまでプローブを続けます。これにより、ブラウザからの最初のリクエストがプロキシの 502 に当たるのを防ぎます。Docker ヘルスチェックを定義しているコンテナはそのシグナルが優先されます。healthy なコンテナはプローブをスキップし、start_period 中のコンテナは警告ではなく情報ログを出します。プローブは 15 秒でタイムアウトします(マシン上の環境変数 REDIACC_READINESS_TIMEOUT に秒数を設定することで変更できます)。デタッチ起動ではプローブ自体がスキップされます。

サービスの停止

rdc repo down --name my-app -m server-1
オプション説明
--unmount停止後に暗号化リポジトリをアンマウント。効果が現れない場合は、rdc repo unmount を別途使用してください。
--skip-router-restart操作後にルートサーバーの再起動をスキップ

実行シーケンスは以下の通りです:

  1. すべてのRediaccfileでdown()を実行(Z-A逆順、ベストエフォート)
  2. 隔離Dockerデーモンを停止(--unmountの場合)
  3. LUKS暗号化ボリュームをアンマウントおよびクローズ(--unmountの場合)

一括操作

マシン上のすべてのリポジトリを一度に開始または停止します:

rdc repo up -m server-1
オプション説明
--include-forksフォークされたリポジトリを含める
--mount-onlyマウントのみ行い、コンテナは起動しない
--dry-run実行される操作を表示
--parallel操作を並列実行
--concurrency <n>最大同時操作数(デフォルト:3)
--skip-router-restart操作後にルートサーバーの再起動をスキップ

起動時の自動開始

デフォルトでは、サーバー再起動後にリポジトリを手動でマウントして開始する必要があります。自動開始を設定すると、サーバー起動時にリポジトリを自動的にマウントし、Dockerを起動し、Rediaccfileのup()を実行するように構成できます。

仕組み

リポジトリの自動開始を有効にすると:

  1. 256バイトのランダムなLUKSキーファイルが生成され、リポジトリのLUKSスロット1に追加されます(スロット0はユーザーパスフレーズのまま)
  2. キーファイルは{datastore}/.credentials/keys/{guid}.key0600パーミッション(root専用)で保存されます
  3. systemdサービス(rediacc-autostart)が起動時にすべての有効なリポジトリをマウントしてサービスを開始します

システムのシャットダウン時、サービスはすべてのサービスを正常に停止し(Rediaccfileのdown())、Dockerデーモンを停止し、LUKSボリュームをクローズします。

セキュリティに関する注意: 自動開始を有効にすると、サーバーのディスクにLUKSキーファイルが保存されます。サーバーへのrootアクセスを持つ者は、パスフレーズなしでリポジトリをマウントできます。脅威モデルに基づいて評価してください。

有効化

rdc repo autostart enable --name my-app -m server-1

リポジトリのパスフレーズの入力を求められます。

すべてを有効化

rdc repo autostart enable -m server-1

無効化

rdc repo autostart disable --name my-app -m server-1

これによりキーファイルが削除され、LUKSスロット1が無効化されます。

デプロイ時のキーファイル更新

自動開始が有効な場合、rdc repo upはLUKSスロット1のキーファイルを検証します。 ディスク上のキーファイルがまだLUKSスロットと一致する場合、変更は行われません。

repo push / repo pullでリポジトリをマシン間で転送した後、 新しいマシン上のキーファイルは一致しません。この場合、repo upは自動的に キーファイルを再生成してLUKSスロット1を更新します。以下のログメッセージが表示されます:

Refreshing keyfile credential for <guid>
Killing LUKS slot 1: /mnt/rediacc/repositories/<guid>
Adding keyfile to LUKS slot 1: /mnt/rediacc/repositories/<guid>

これは安全です。スロット0(パスフレーズ)は変更されません。自動開始が 有効でない場合、チェックはサイレントにスキップされます。失敗は致命的でなく、デプロイをブロックしません。

ステータスの一覧表示

rdc repo autostart list -m server-1

起動後に停止したリポジトリを定期リコンサイラーが回復する仕組みの詳細については、自動開始と回復を参照してください。

完全な例

この例では、PostgreSQL、Redis、APIサーバーを含むWebアプリケーションをデプロイします。

1. セットアップ

curl -fsSL https://www.rediacc.com/install.sh | bash
rdc config init --name production --ssh-key ~/.ssh/id_ed25519
rdc config machine add --name prod-1 --ip 203.0.113.50 --user deploy
rdc config machine setup --name prod-1
rdc repo create --name webapp -m prod-1 --size 10G

2. マウントと準備

rdc repo mount --name webapp -m prod-1

3. アプリケーションファイルの作成

リポジトリ内に以下のファイルを作成します:

docker-compose.yml:

services:
  postgres:
    image: postgres:16
    volumes:
      - ./data/postgres:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: webapp
      POSTGRES_USER: app
      POSTGRES_PASSWORD: changeme

  redis:
    image: redis:7-alpine

  api:
    image: myregistry/api:latest
    environment:
      DATABASE_URL: postgresql://app:changeme@postgres:5432/webapp
      REDIS_URL: redis://redis:6379
      LISTEN_ADDR: 0.0.0.0:8080

Rediaccfile:

#!/bin/bash

up() {
    mkdir -p data/postgres
    renet compose -- up -d

    echo "Waiting for PostgreSQL..."
    for i in $(seq 1 30); do
        if renet compose -- exec postgres pg_isready -q 2>/dev/null; then
            echo "PostgreSQL is ready."
            return 0
        fi
        sleep 1
    done
    echo "Warning: PostgreSQL did not become ready within 30 seconds."
}

down() {
    renet compose -- down
}

4. 開始

rdc repo up --name webapp -m prod-1

5. 自動開始の有効化

rdc repo autostart enable --name webapp -m prod-1

composeでリポジトリごとのシークレットを使用する

上記のPOSTGRES_PASSWORD: changemeプレースホルダーはチュートリアル用ですが、実アプリケーションは実クレデンシャルが必要で、composeファイル(またはリポジトリ内の.envファイル)にコミットするということは、フォークもそれを継承することを意味します。デプロイ時のクレデンシャルについては、rdc repo secretを使用してください。値は暗号化リポジトリイメージの外側にあるため、フォークは空のシークレットマップで開始します。

composeで機能する2つの配信モードがあります:

envモード。任意のenvironment:値内で${REDIACC_SECRET_<KEY>}を使用して補間します。renetラッパーはデプロイ時にコンテナの環境に値を渡します。

fileモード。値はホスト側のtmpfsファイル(/var/run/rediacc/secrets/<networkID>/<KEY>)に配置され、Dockerのcomposeの標準secrets:ブロック経由でコンテナにマウントします。コンテナは/run/secrets/<key>を読みます。何か機密情報がある場合はこのモードを優先してください。値はdocker inspect/proc/<pid>/environに表示されません。

services:
  api:
    image: myregistry/api:latest
    environment:
      DATABASE_URL: ${REDIACC_SECRET_DATABASE_URL}
    secrets:
      - stripe_live_key

secrets:
  stripe_live_key:
    file: /var/run/rediacc/secrets/${REDIACC_NETWORK_ID}/STRIPE_LIVE_KEY

rdc repo secret set --name <repo> --key DATABASE_URL --value <val> --mode env --current ""でファイルモード相当の値をシードします。詳細についてはリポジトリ » シークレットを参照し、コマンドリファレンスについてはチートシートのリポジトリごとのシークレットを参照してください。

クロスリポパスはバリデーション時に拒否されます。 composeのsecrets: file:(またはconfigs: file:、またはenv_file:)が別のリポジトリの/var/run/rediacc/secrets/<other-networkID>/ディレクトリを指していると、renetラッパーによってdocker compose実行前に厳密に拒否されます。--unsafeはオーバーライドしません。深層防御:Rediaccfileシェルの周囲のLandlockサンドボックスはリードを現在のネットワークのシークレットディレクトリにスコープするため、YAMLバリデーターをバイパスしても、Rediaccfileのbashからcat /var/run/rediacc/secrets/<other>/Xを実行するとEACCESで失敗します。オプトインする必要はありません。これはすべてのrepo upでデフォルトで有効です。