⚡ 3秒でわかる!この記事のポイント
- Codex CLIはDockerfile作成・最適化・マルチステージビルド設計を自然言語で自動化
- Docker Compose構成やCI/CDパイプラインのコンテナ化も一括で生成可能
- コンテナスキルを持つSESエンジニアの月単価は平均15〜20%高い
「Dockerfileの書き方がわからない」「マルチステージビルドでイメージサイズを最適化したいが、設定が複雑」「Docker Composeで開発環境を構築したいが、依存関係の管理に苦戦」——SES現場でコンテナ化に取り組むエンジニアなら、誰もが経験する課題です。
2026年現在、コンテナ技術はSES案件の約70%で求められるスキルになっています。特にDockerの実践的な知識は、バックエンド・インフラ案件だけでなく、フロントエンド案件でも開発環境構築に必要とされています。
本記事では、OpenAI Codex CLIを活用してDocker開発を効率化する方法を、Dockerfileの自動生成からプロダクション最適化まで体系的に解説します。
コンテナ開発でCodex CLIが活きる理由
Docker開発の主な課題は「正しいDockerfileの記述」「イメージサイズの最適化」「セキュリティ対策」の3つです。Codex CLIは、これらの課題をプロジェクトのコンテキストを理解した上で解決します。
従来のDocker開発の課題と解決策
| 課題 | 従来の対処法 | Codex CLIでの解決 |
|---|---|---|
| Dockerfile作成 | テンプレートをコピペして修正 | プロジェクト構成から自動生成 |
| イメージサイズ肥大 | 手動でレイヤー最適化 | マルチステージビルド自動設計 |
| セキュリティ対策 | ベストプラクティスを調べて適用 | 脆弱性チェック付きで自動設定 |
| Compose構成 | ドキュメントを見ながら手書き | サービス構成から自動生成 |
実践①:最適なDockerfileの自動生成
Node.jsアプリケーションのコンテナ化
codex "このNode.js/TypeScriptプロジェクトのDockerfileを作成して。
- マルチステージビルドで最小イメージに
- 本番用はdistrolessベースイメージを使う
- non-rootユーザーで実行
- ヘルスチェックを設定
- .dockerignoreも生成して"
Codex CLIが生成するDockerfile:
# ============================================
# Stage 1: 依存関係のインストール
# ============================================
FROM node:22-slim AS deps
WORKDIR /app
# パッケージマネージャのロックファイルをコピー
COPY package.json pnpm-lock.yaml ./
# pnpmをインストールして依存関係を取得
RUN corepack enable pnpm && \
pnpm install --frozen-lockfile --prod=false
# ============================================
# Stage 2: ビルド
# ============================================
FROM node:22-slim AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# TypeScriptのビルド
RUN corepack enable pnpm && \
pnpm run build
# 本番依存関係のみ再インストール
RUN corepack enable pnpm && \
pnpm install --frozen-lockfile --prod
# ============================================
# Stage 3: 本番イメージ
# ============================================
FROM gcr.io/distroless/nodejs22-debian12 AS runner
WORKDIR /app
# セキュリティ: non-rootユーザー
USER nonroot:nonroot
# ビルド成果物と本番依存関係のみコピー
COPY --from=builder --chown=nonroot:nonroot /app/dist ./dist
COPY --from=builder --chown=nonroot:nonroot /app/node_modules ./node_modules
COPY --from=builder --chown=nonroot:nonroot /app/package.json ./
# 環境変数
ENV NODE_ENV=production
ENV PORT=3000
EXPOSE 3000
# ヘルスチェック
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD ["/nodejs/bin/node", "-e", "fetch('http://localhost:3000/health').then(r => r.ok ? process.exit(0) : process.exit(1)).catch(() => process.exit(1))"]
CMD ["dist/main.js"]
.dockerignore の自動生成
codex "このプロジェクトに最適な.dockerignoreを生成して"
# バージョン管理
.git
.gitignore
# 開発環境
node_modules
.env
.env.local
.env.*.local
# ビルド成果物(コンテナ内でビルドする)
dist
build
coverage
# IDE・エディタ
.vscode
.idea
*.swp
*.swo
# ドキュメント・テスト
docs
__tests__
*.test.ts
*.spec.ts
jest.config.*
vitest.config.*
# Docker関連
Dockerfile*
docker-compose*
.dockerignore
# CI/CD
.github
.gitlab-ci.yml
# その他
README.md
CHANGELOG.md
LICENSE
実践②:Docker Compose開発環境の構築
フルスタックアプリケーションの構成
codex "以下の構成でDocker Compose環境を作って。
- Next.jsフロントエンド(ホットリロード対応)
- NestJSバックエンドAPI
- PostgreSQL 16(初期データ投入付き)
- Redis(セッション・キャッシュ用)
- Nginx(リバースプロキシ)
- 開発用のVolume設定
- ヘルスチェック設定"
# docker-compose.yml
services:
# ──────────────────────────────
# フロントエンド (Next.js)
# ──────────────────────────────
frontend:
build:
context: ./frontend
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- ./frontend/src:/app/src
- ./frontend/public:/app/public
environment:
- NEXT_PUBLIC_API_URL=http://localhost:8080/api
- WATCHPACK_POLLING=true
depends_on:
backend:
condition: service_healthy
networks:
- app-network
# ──────────────────────────────
# バックエンド (NestJS)
# ──────────────────────────────
backend:
build:
context: ./backend
dockerfile: Dockerfile.dev
ports:
- "4000:4000"
volumes:
- ./backend/src:/app/src
environment:
- DATABASE_URL=postgresql://app:secret@postgres:5432/myapp
- REDIS_URL=redis://redis:6379
- JWT_SECRET=dev-secret-key
- NODE_ENV=development
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:4000/health"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
networks:
- app-network
# ──────────────────────────────
# データベース (PostgreSQL)
# ──────────────────────────────
postgres:
image: postgres:16-alpine
ports:
- "5432:5432"
environment:
POSTGRES_DB: myapp
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
volumes:
- postgres-data:/var/lib/postgresql/data
- ./database/init:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d myapp"]
interval: 5s
timeout: 3s
retries: 10
networks:
- app-network
# ──────────────────────────────
# キャッシュ (Redis)
# ──────────────────────────────
redis:
image: redis:7-alpine
ports:
- "6379:6379"
command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
networks:
- app-network
# ──────────────────────────────
# リバースプロキシ (Nginx)
# ──────────────────────────────
nginx:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
frontend:
condition: service_started
backend:
condition: service_healthy
networks:
- app-network
volumes:
postgres-data:
redis-data:
networks:
app-network:
driver: bridge
実践③:イメージサイズ最適化
最適化の分析と改善
codex "このDockerfileのイメージサイズを分析して最適化して。
- 各レイヤーのサイズを見積もり
- 不要なファイルの削除
- ベースイメージの最適な選択
- ビルドキャッシュの最大活用"
最適化前後のサイズ比較:
| 手法 | サイズ | 削減率 |
|---|---|---|
| node:22(最適化前) | 1.2 GB | - |
| node:22-slim | 250 MB | -79% |
| マルチステージビルド | 180 MB | -85% |
| distroless | 130 MB | -89% |
| Alpine + 最適化 | 95 MB | -92% |
セキュリティスキャン
codex "このDockerイメージのセキュリティスキャンを設定して。
- Trivyでの脆弱性スキャン
- Dockerfileのベストプラクティスチェック(hadolint)
- CI/CDに組み込むGitHub Actionsワークフロー"
# .github/workflows/docker-security.yml
name: Docker Security Scan
on:
pull_request:
paths:
- 'Dockerfile*'
- 'docker-compose*.yml'
- '.dockerignore'
jobs:
hadolint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hadolint/[email protected]
with:
dockerfile: Dockerfile
trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t app:scan .
- name: Run Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: 'app:scan'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
- name: Upload results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
実践④:本番デプロイ設定
ECS Fargateへのデプロイ
codex "このDockerアプリをAWS ECS Fargateにデプロイするための
タスク定義とCDKコードを生成して。
- ALBによるロードバランシング
- Auto Scaling設定
- CloudWatchログ
- Secrets Managerからの環境変数取得"
// cdk/lib/ecs-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
import * as logs from 'aws-cdk-lib/aws-logs';
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
export class EcsStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// VPC
const vpc = new ec2.Vpc(this, 'AppVpc', {
maxAzs: 2,
natGateways: 1,
});
// ECS クラスター
const cluster = new ecs.Cluster(this, 'AppCluster', {
vpc,
containerInsights: true,
});
// Secrets Manager
const dbSecret = secretsmanager.Secret.fromSecretNameV2(
this, 'DbSecret', 'app/database-url'
);
// タスク定義
const taskDef = new ecs.FargateTaskDefinition(this, 'TaskDef', {
memoryLimitMiB: 512,
cpu: 256,
});
const container = taskDef.addContainer('app', {
image: ecs.ContainerImage.fromAsset('.'),
logging: ecs.LogDrivers.awsLogs({
streamPrefix: 'app',
logRetention: logs.RetentionDays.ONE_MONTH,
}),
environment: {
NODE_ENV: 'production',
},
secrets: {
DATABASE_URL: ecs.Secret.fromSecretsManager(dbSecret),
},
healthCheck: {
command: ['CMD-SHELL', 'curl -f http://localhost:3000/health || exit 1'],
interval: cdk.Duration.seconds(30),
timeout: cdk.Duration.seconds(5),
retries: 3,
},
});
container.addPortMappings({ containerPort: 3000 });
// Fargate サービス + ALB
const service = new ecs.FargateService(this, 'Service', {
cluster,
taskDefinition: taskDef,
desiredCount: 2,
assignPublicIp: false,
});
// Auto Scaling
const scaling = service.autoScaleTaskCount({
minCapacity: 2,
maxCapacity: 10,
});
scaling.scaleOnCpuUtilization('CpuScaling', {
targetUtilizationPercent: 70,
scaleInCooldown: cdk.Duration.seconds(60),
scaleOutCooldown: cdk.Duration.seconds(60),
});
// ALB
const alb = new elbv2.ApplicationLoadBalancer(this, 'ALB', {
vpc,
internetFacing: true,
});
const listener = alb.addListener('Listener', { port: 80 });
listener.addTargets('Target', {
port: 3000,
targets: [service],
healthCheck: {
path: '/health',
interval: cdk.Duration.seconds(30),
},
});
}
}
SES現場でのDockerスキルの市場価値

2026年のコンテナ案件動向
| スキルレベル | できること | 月単価目安 |
|---|---|---|
| 基礎 | Dockerfile作成、基本的なコマンド操作 | 60〜70万円 |
| 中級 | マルチステージビルド、Compose構築 | 70〜80万円 |
| 上級 | オーケストレーション(ECS/K8s)、CI/CD連携 | 80〜95万円 |
| エキスパート | プラットフォームエンジニアリング、セキュリティ | 95万円以上 |
まとめ:Codex CLI × Dockerで開発環境を革新
Codex CLIを活用したDocker開発のポイントをおさらいしましょう。
| 活用シーン | 効果 | 時間短縮 |
|---|---|---|
| Dockerfile自動生成 | プロジェクト構成から最適なDockerfileを生成 | 最大80%短縮 |
| マルチステージビルド | イメージサイズ最大92%削減 | 設計時間を大幅短縮 |
| Docker Compose構成 | フルスタック開発環境を一発構築 | 最大70%短縮 |
| セキュリティ対策 | 脆弱性スキャン・ベストプラクティス自動適用 | 最大60%短縮 |
| 本番デプロイ | ECS/Cloud Run等のデプロイ設定を自動生成 | 最大75%短縮 |
Docker × AI活用は、2026年のSES市場で最も需要の高いスキルセットの一つです。Codex CLIを活用することで、ベストプラクティスに沿ったコンテナ化を短時間で実現できます。
📚 OpenAI Codex CLI 完全攻略シリーズの他の記事もチェック!