Oh MyUtils

Docker Run to Compose - DockerコマンドをCompose YAMLに変換 オンライン

docker runコマンドをdocker-compose.yml形式に変換します。ポート、ボリューム、環境変数など30以上のDockerフラグを瞬時にパースします — 100%クライアントサイド、データはブラウザの外に出ません。

よくある質問

Docker Run to Composeコンバーターとは何ですか?

Docker Run to Composeコンバーターは、docker run CLIコマンドをdocker-compose.yml(Docker Compose)YAML設定ファイルに変換するツールです。docker run -d --name nginx -p 80:80 nginx:latestのようなコマンドでコンテナを実行すると、コンバーターはservices、ports、volumesなどのディレクティブを含む同等のCompose YAMLを生成します。Composeファイルはバージョン管理可能で再現性があり、マルチコンテナアプリケーションを管理できるため便利です。

このDocker Run to Composeコンバーターの使い方は?

入力エリアにdocker runコマンドを貼り付けてください(docker runプレフィックスの有無は問いません)。変換は入力中にリアルタイムで自動的に行われます。出力エリアで生成されたdocker-compose.yml YAMLを確認してください。必要に応じてオプションを調整できます:Composeバージョン(Latest、v3.x、v2.x)とインデント(2または4スペース)を選択してください。コピーボタンでYAMLをクリップボードにコピーするか、ダウンロードボタンでdocker-compose.ymlファイルとして保存できます。

データは安全ですか?サーバーに送信されますか?

データは100%安全で、ブラウザの外に出ることはありません。すべてのパースと変換はデバイス上で実行されるクライアントサイドJavaScriptで完全に処理されます。Dockerコマンド、環境変数、パスワード、APIキーなど、いかなるデータもサーバーに送信されたり、データベースに保存されたり、記録されたりしません。インターネットを切断して確認できます — 初回ページ読み込み後は完全にオフラインで動作します。

どのdocker runフラグがサポートされていますか?

このコンバーターは30以上の一般的なDocker runフラグをサポートしています:ポートマッピング(-p)、ボリューム(-v、--mount)、環境変数(-e、--env-file)、コンテナ名(--name)、再起動ポリシー(--restart)、ネットワーク(--network)、作業ディレクトリ(-w)、ユーザー(-u)、ホスト名(-h)、エントリポイント(--entrypoint)、ラベル(-l)、ケーパビリティ(--cap-add、--cap-drop)、特権モード(--privileged)、デバイス(--device)、ロギング、リソース制限(--memory、--cpus)、ヘルスチェックなど。Composeに直接対応しないフラグ(--rmなど)は警告が表示されます。

Docker Composeバージョン(v2、v3、latest)の違いは何ですか?

Docker Composeは複数の仕様バージョンを経て進化してきました。バージョン2.xはservices、networks、volumesをトップレベルキーとして導入し、リソース制約にmem_limitなどのキーを使用します。バージョン3.xはDocker Swarm互換性のために設計され、リソース制限をdeploy.resourcesの下に移動します。Latest(Common Specification)はversionフィールドを完全に省略し、最新の構文を使用するモダンな形式です。ほとんどの新しいプロジェクトではLatestを使用してください。

バックスラッシュ付きの複数行docker runコマンドを貼り付けられますか?

はい、コンバーターはシェルスクリプト、ドキュメント、READMEファイルからコピーする際に一般的なバックスラッシュ(\)による行継続を含む複数行コマンドを完全にサポートしています。ツールは変換前にこれらを自動的に単一コマンドに正規化します。複数行コマンドをそのまま貼り付けてください。

変換された出力が予想と異なるのはなぜですか?

一般的な理由:(1) フラグの順序 — Compose YAMLにはコマンドのフラグ順序と異なる可能性のある標準キー順序があります。(2) 暗黙のデフォルト — -d(デタッチ)などのフラグはComposeではデフォルトであり、明示的に表示されない場合があります。(3) バージョンの違い — リソース制限(--memory、--cpus)はv2とv3のCompose形式で異なって表現されます。(4) 未サポートフラグ — --rmなどのフラグはComposeに直接の対応がなく、警告として表示されます。

コード例

// Docker Run to Docker Compose converter
// Parses docker run command and generates docker-compose.yml YAML

function parseDockerRun(command) {
  const normalized = command.replace(/\\\s*\n/g, ' ').trim();
  const stripped = normalized.replace(/^docker\s+run\s+/, '');
  const tokens = tokenize(stripped);

  const options = {
    image: '', name: '', ports: [], volumes: [],
    envVars: [], network: '', restart: '',
    workdir: '', hostname: '', command: [],
    detach: false, privileged: false,
  };

  let i = 0;
  while (i < tokens.length) {
    const token = tokens[i];
    if (token === '-p' || token === '--publish') {
      const val = tokens[++i];
      const parts = val.split(':');
      options.ports.push({ host: parts[0], container: parts.slice(1).join(':') });
    } else if (token === '-v' || token === '--volume') {
      const val = tokens[++i];
      const parts = val.split(':');
      options.volumes.push({ host: parts[0], container: parts[1], mode: parts[2] || '' });
    } else if (token === '-e' || token === '--env') {
      const val = tokens[++i];
      const eq = val.indexOf('=');
      options.envVars.push({ key: val.substring(0, eq), value: val.substring(eq + 1) });
    } else if (token === '--name') { options.name = tokens[++i]; }
    else if (token === '--restart') { options.restart = tokens[++i]; }
    else if (token === '--network') { options.network = tokens[++i]; }
    else if (token === '-d') { options.detach = true; }
    else if (!token.startsWith('-')) {
      options.image = token;
      options.command = tokens.slice(i + 1);
      break;
    }
    i++;
  }
  return options;
}

function tokenize(input) {
  const tokens = [];
  let current = '', inSQ = false, inDQ = false;
  for (const char of input) {
    if (char === "'" && !inDQ) { inSQ = !inSQ; }
    else if (char === '"' && !inSQ) { inDQ = !inDQ; }
    else if (char === ' ' && !inSQ && !inDQ) {
      if (current) { tokens.push(current); current = ''; }
    } else { current += char; }
  }
  if (current) tokens.push(current);
  return tokens;
}

function generateComposeYaml(options, indent = 2) {
  const pad = ' '.repeat(indent);
  const p2 = pad.repeat(2), p3 = pad.repeat(3);
  const name = options.name || options.image.split('/').pop().split(':')[0] || 'app';
  let yaml = `services:\n${pad}${name}:\n${p2}image: ${options.image}\n`;
  if (options.name) yaml += `${p2}container_name: ${options.name}\n`;
  if (options.restart) yaml += `${p2}restart: ${options.restart}\n`;
  if (options.ports.length > 0) {
    yaml += `${p2}ports:\n`;
    options.ports.forEach(p => yaml += `${p3}- "${p.host}:${p.container}"\n`);
  }
  if (options.volumes.length > 0) {
    yaml += `${p2}volumes:\n`;
    options.volumes.forEach(v => {
      const mode = v.mode ? `:${v.mode}` : '';
      yaml += `${p3}- ${v.host}:${v.container}${mode}\n`;
    });
  }
  if (options.envVars.length > 0) {
    yaml += `${p2}environment:\n`;
    options.envVars.forEach(e => yaml += `${p3}- ${e.key}=${e.value}\n`);
  }
  if (options.network) {
    yaml += `${p2}networks:\n${p3}- ${options.network}\n`;
  }
  return yaml;
}

// Example usage
const cmd = 'docker run -d --name nginx -p 80:80 -v ./html:/usr/share/nginx/html nginx:latest';
const opts = parseDockerRun(cmd);
console.log(generateComposeYaml(opts));

関連ツール