Docker Run から Compose へ

docker run コマンドを貼り付けるだけで、そのまま使える Compose のサービス定義を生成します。ポート、ボリューム、環境変数、ネットワーク、ヘルスチェック、再起動ポリシーをブラウザ内で変換します。

長い docker run コマンドを、リポジトリにコミットできる Compose ファイルに変換します。 普段入力するとおりに貼り付けてください。行継続を含んでいても構いません。Compose に対応するものがないオプションは、黙って捨てずに注記として一覧表示します。

その場限りのコマンドから再現可能なファイルへ

変換が単純な置き換えにならない理由

docker run コマンドと Compose のサービスは同じコンテナを記述しますが、答えている問いが違います。コマンドは「いま何をするか」を、ファイルは「このサービスが動いている間、何が成り立っているべきか」を述べます。ほとんどのオプションはそのまま対応付けられ、対応しないものはたいてい、コンテナ自体ではなく「実行するという行為」を表しています。

最も分かりやすいのが detach です。-d はデーモンに端末を占有しないよう伝えるもので、その呼び出しの性質であってサービスの性質ではありません。Compose では同じ意図をコマンドラインの docker compose up -d で表すため、このオプションはファイルから消えます。--rm も同様で、その回の実行後の後片付けを求めるものです。Compose では終了時に docker compose down を実行します。

対話系のオプションは中間に位置します。-i と -t には stdin_open と tty という対応キーがあり、シェルを接続したままにすることがサービスの本来の性質である場合もあるため、破棄せず変換します。ただし長時間稼働するサービスの多くには不要です。

変換が壊れるのはたいてい引用符

変換がうまくいかない最大の原因は、貼り付ける前にシェルの引用符が失われていることです。ヘルスチェックを例にすると、テストコマンド全体が 1 つの引数として渡される必要があるため、コマンドラインでは引用符で囲みます。引用符なしで貼り付けると各単語が別々の引数になり、イメージ名が誤った位置から読み取られ、結果は意味を成しません。

本ツールはシェルと同じ規則で入力を分割し、単一引用符・二重引用符・バックスラッシュエスケープ・バックスラッシュによる行継続を正しく扱うため、スクリプトからそのままコピーした構造を保てます。出力時には YAML の規則に従って再度引用符を付けます。これは見た目以上に重要で、8080:80 のようなポート指定は YAML では引用符が必要です。コロン区切りの値は引用符がないと曖昧で、22:00 のような値を六十進数として読むパーサーが歴史的に存在したためです。

ネットワーク、そしてファイルには分からないこと

忠実に変換してもなおあなたの判断が必要になる唯一の箇所がネットワークです。host、none、bridge に接続する場合はモードなので network_mode になります。それ以外の名前は既存のネットワークを指すため、サービスには networks の項目が付き、ファイル側でそのネットワークを external として宣言します。

この宣言はあなたの環境についての主張です。つまり、そのネットワークはこのファイルの外側で管理されている、という意味になります。Compose 自身に作成・管理させたい場合は external を外して通常どおり定義してください。元のコマンドは「実行した時点でネットワークが存在した」ことしか証明しないため、ツール側では判断できません。

バインドマウントにも同じ注意が必要です。/srv/site のようなパスは、そのコマンドを書いたマシンでしか成立しません。サービス定義がコミットされ共有されるファイルに移る以上、相対パスや名前付きボリュームのほうが適切なことが多いでしょう。

自社実装で、shell トークナイザと YAML ジェネレータを独自に記述しています。サードパーティのパーサーは同梱せず、入力したコマンドがブラウザ外に送信されることはありません。

よくある質問

出力から -d が消えたのはなぜですか。
detach はコンテナの起動方法を表すもので、コンテナ自体の性質ではありません。Compose では docker compose up -d で同じ意図を表すため、ファイルには含めません。
バックスラッシュで改行した複数行のコマンドを貼り付けられますか。
できます。行継続は解析前に連結されるため、スクリプトやドキュメントからそのままコピーして貼り付けられます。
ポートが引用符で囲まれるのはなぜですか。
YAML では引用符のないコロン区切りの値は曖昧で、22:00 のような値を数値として読むパーサーもあります。ポート指定を引用符で囲むのは公式に推奨される書き方です。
生成されたネットワークの external: true はどういう意味ですか。
そのネットワークが既に存在し、このファイルで作成も削除もしないことを Compose に伝えます。Compose に管理させたい場合はこの指定を外してください。
未対応のオプションは黙って無視されますか。
いいえ。対応付けできなかった項目はすべて変換注記に表示されるため、後から抜けに気付くのではなくその場で判断できます。
入力したコマンドはアップロードされますか。
されません。分割処理も YAML 生成も自前のコードでブラウザ内で実行され、コマンドがページの外に出ることはありません。