Claudeを使ってMac上のDockerにNode.js+SQLite Webアプリを自動生成・デプロイする手順

概要:本記事は HTML/JavaScript(Node.js)+SQLite を用い、Mac(Apple Silicon対応)で Docker にコンテナ化してデプロイするまでの手順を、生成AI(Claude)を活用した自動開発ワークフローとともに解説します。記事内のコマンドや設定ファイルはそのままコピペして使えます。


目次


1. 前提と準備

  • OS:macOS(Intel / Apple Silicon 両対応)
  • インストール:Docker Desktop for Mac(Apple Siliconの場合はARM対応版を選択)
  • 開発言語:HTML, JavaScript(Node.js / Express)
  • DBMS:SQLite(ファイルベース)
  • AI:Claude(コード生成・レビュー・デバッグ支援に利用)

Docker Desktop の公式インストール手順や Node.js のコンテナ化サンプルは公式ドキュメントを参照してください(下部にURLを記載)。


2. プロジェクト雛形(ローカル)

まずローカルにプロジェクトディレクトリを作成します。

mkdir claude-node-sqlite
cd claude-node-sqlite


以下は最小構成のファイル一覧(後で内容を示します):

  • package.json
  • server.js
  • db.sqlite(アプリ起動時に自動生成可)
  • /public/index.html
  • Dockerfile
  • docker-compose.yml
  • nginx/nginx.conf

package.json(例)

{
  "name": "claude-node-sqlite",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
  },
  "dependencies": {
    "express": "^4.18.2",
    "sqlite3": "^5.1.6"
  }
}


server.js(Express + SQLite の簡易CRUD API)

const express = require('express');
const sqlite3 = require('sqlite3').verbose();
const path = require('path');

const app = express();
app.use(express.json());
app.use(express.static(path.join(__dirname, 'public')));

const DB_PATH = path.join(__dirname, 'db.sqlite');
const db = new sqlite3.Database(DB_PATH);

// 初期化
db.serialize(() => {
  db.run(`CREATE TABLE IF NOT EXISTS items (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
  )`);
});

// CRUD API
app.get('/api/items', (req, res) => {
  db.all('SELECT * FROM items ORDER BY id DESC', (err, rows) => {
    if (err) return res.status(500).json({ error: err.message });
    res.json(rows);
  });
});

app.post('/api/items', (req, res) => {
  const { name } = req.body;
  if (!name) return res.status(400).json({ error: 'name is required' });
  db.run('INSERT INTO items (name) VALUES (?)', [name], function(err) {
    if (err) return res.status(500).json({ error: err.message });
    res.json({ id: this.lastID, name });
  });
});

app.delete('/api/items/:id', (req, res) => {
  const id = req.params.id;
  db.run('DELETE FROM items WHERE id = ?', [id], function(err) {
    if (err) return res.status(500).json({ error: err.message });
    res.json({ deleted: this.changes });
  });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});


public/index.html(簡易フロント)

<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Claude 自動生成アプリ</title>
</head>
<body>
  <h1>Claude 自動生成の Node.js + SQLite サンプル</h1>
  <input id="name" placeholder="名前を入力">
  <button id="add">追加</button>
  <ul id="list"></ul>

  <script>
    async function fetchItems() {
      const res = await fetch('/api/items');
      const items = await res.json();
      const ul = document.getElementById('list');
      ul.innerHTML = '';
      items.forEach(i => {
        const li = document.createElement('li');
        li.textContent = `${i.id}: ${i.name}`;
        const btn = document.createElement('button');
        btn.textContent = '削除';
        btn.onclick = async () => {
          await fetch(`/api/items/${i.id}`, { method: 'DELETE' });
          fetchItems();
        };
        li.appendChild(btn);
        ul.appendChild(li);
      });
    }

    document.getElementById('add').onclick = async () => {
      const name = document.getElementById('name').value;
      await fetch('/api/items', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name })
      });
      document.getElementById('name').value = '';
      fetchItems();
    };

    fetchItems();
  </script>
</body>
</html>


3. Claudeを使った自動生成ワークフロー

Claude(生成AI)を使うと、以下のような工程を自動化できます。

  • Express + SQLite の CRUD コード生成(上記 server.js やフロント)
  • Dockerfile / docker-compose.yml の生成
  • コードレビューとセキュリティ指摘(例:入力バリデーション、SQLインジェクション対策)
  • ログやエラーメッセージを渡してデバッグ指示を得る

プロンプト例(Claudeに投げる)

「Node.js (Express) と SQLite を使った簡単な CRUD API とフロント(HTML/JS)を生成してください。Dockerfile と docker-compose.yml も作成してください。セキュリティ上の注意点と、Apple Silicon (arm64) での Docker 対応についてもコメントしてください。」

生成されたコードは必ずローカルで実行・レビューし、必要に応じて修正してください。AIの出力は補助であり、最終的な責任は開発者にあります。


4. Docker化(Dockerfile / docker-compose)

Dockerfile(例)

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]


Apple Silicon(arm64)環境では、公式イメージがarm64をサポートしているため通常は問題ありません。必要に応じて platform: linux/arm64 を docker-compose に指定できます。

docker-compose.yml(例)

version: "3.8"
services:
  app:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - ./:/app
    environment:
      - NODE_ENV=production

  nginx:
    image: nginx:stable-alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - app


5. Nginxでのリバースプロキシ設定

ローカルでポート80にアクセスできるよう、Nginxをリバースプロキシとして設定します。

nginx/nginx.conf(例)

events { }
http {
  server {
    listen 80;
    location / {
      proxy_pass http://app:3000;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
  }
}


この設定を docker-compose の nginx サービスでマウントします。公開環境では TLS(Let’s Encrypt 等)を必ず導入してください。


6. 起動と動作確認

  1. プロジェクトルートでビルド・起動:
docker compose up --build -d

  1. ブラウザで http://localhost にアクセスし、フロントが表示されることを確認。
  2. APIの動作確認(例):curl http://localhost/api/items

ログ確認:

docker compose logs -f app


問題が発生した場合は、ログをClaudeに渡して「このログを解析して原因と修正案を出して」といった形でデバッグ支援を受けると効率的です。


参考(引用元URL)


補足:セキュリティと運用上の注意

  • 本番環境では 環境変数による設定管理、TLS(HTTPS)、および適切なログ管理を必須としてください。
  • SQLiteは軽量で便利ですが、同時接続が多い本番用途では PostgreSQL や MySQL を検討してください。
  • AI(Claude)に生成させたコードは必ず人間がレビューし、脆弱性や誤ったロジックがないか確認してください。

コメントを残す