はじめに
前にterraformを使ってローカルdocker(OrbStack)でnginxのコンテナを作成して、静的コンテンツを設定する、という作業をご紹介しました。

Gemini Code Assistと二人三脚で、TerraformによるローカルDocker環境を爆速構築してみた
タイトルの通り、VSCode + Gemini Code Assistを使って、ローカルのOrbStackにterraformでコンテナを作ってみました。環境の超概要はこちらmacOS Tahoe 26.4OrbStack 2.0.5Ter…
今回はもう少し進んで、ローカルで簡単なwebサービスを作ってみたいと思います。
さらにゆくゆくはAWSのECSとしてデプロイしたいと目論んでますので、お楽しみに。
ちなみに今回はClaudeと対話しながら構成を決めて実装を進めました。詰まったところも一緒にデバッグしてもらいながら進められたので、初めての構成でもスムーズに動かすことができました。
概要
技術スタック
| 項目 | 技術 |
|---|---|
| 言語 | Python 3.12 |
| フレームワーク | Flask |
| データベース | PostgreSQL 16 |
| ローカル環境 | Docker Compose / OrbStack |
リポジトリ
flask-to-ecs/ ├── docker-compose.yaml ├── app/ │ ├── Dockerfile │ ├── requirements.txt │ └── main.py ├── .github/ │ └── workflows/ # 今後追加予定 └── terraform/ # 今後追加予定
構成
docker-compose.yaml
ローカルでのコンテナとしては、webとdbの2つで構成。
- web
- 後述するDockerfileでpythonのイメージ
- ポートはホスト側(Mac)は5001、コンテナ側は5000(flaskのデフォルト)
- Mac側のポート5000は、AirPlayで使っているので避けてます(動作確認で少しハマりましたw)
- DB接続するための環境変数を定義
- ボリュームはリポジトリのappディレクトリを使う
- dbコンテナがservice_healthyになったら起動
- db
- postgresのイメージ
- 環境変数としてDB接続情報を定義
- 今はローカルなのでDB接続情報は平文で定義してますが、AWSに持っていく場合は環境変数などで管理していく予定です。んー、secrets使うおうかなぁw
- DBのデータはDockerボリュームで管理。これによりコンテナを停止してもデータは保持されます。
- ポートはデフォルト(5432)
- ヘルスチェックをしてます。
services:
web:
build: ./app
ports:
- "5001:5000"
environment:
- DATABASE_URL=postgresql://user:password@db:5432/mydb
volumes:
- ./app:/app
depends_on:
db:
condition: service_healthy
db:
image: postgres:16
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 5s
timeout: 5s
retries: 5
volumes:
postgres_data:
Dockerfileとrequirements.txt
webコンテナはDockerfileとrequirements.txtで構成。
- pythonイメージ
- requirements.txtで指定したライブラリをインストール
- flask:フレームワーク
- psycopg2-binary:postgresのライブラリ
- flask-sqlalchemy :flaskでdbを扱うライブラリ
FROM python:3.12-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt CMD ["flask", "--app", "main", "run", "--host=0.0.0.0", "--reload"]
flask psycopg2-binary flask-sqlalchemy
main.py
簡単なwebサービス風のアプリ。
DBは idとnameだけですが、postでデータを登録、querystringでnameの部分一致検索が出来るようにはなっています。
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
import os
app = Flask(__name__)
app.json.ensure_ascii = False
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ["DATABASE_URL"]
db = SQLAlchemy(app)
class Item(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
with app.app_context():
db.create_all()
@app.route("/")
def index():
return jsonify({"message": "Hello, Flask + PostgreSQL!"})
@app.route("/items", methods=["GET"])
def get_items():
name = request.args.get("name") # ?name=xxx を受け取る
if name:
items = Item.query.filter(Item.name.contains(name)).all()
else:
items = Item.query.all()
return jsonify([{"id": i.id, "name": i.name} for i in items])
@app.route("/items", methods=["POST"])
def create_item():
data = request.get_json()
if not data or "name" not in data:
return jsonify({"error": "name is required"}), 400
item = Item(name=data["name"])
db.session.add(item)
db.session.commit()
return jsonify({"id": item.id, "name": item.name}), 201
コンテナの起動
材料が出来ましたので、docker-compose.yamlがあるディレクトリで以下のコマンドを実行
docker compose up --build
動作確認
Hello メッセージ
ブラウザ、またはcurlでhttps://www.51weblab.jp:5001/へアクセス

curl https://www.51weblab.jp:5001/
{"message":"Hello, Flask + PostgreSQL!"}
データ登録
curl -X POST https://www.51weblab.jp:5001/items \
-H "Content-Type: application/json" \
-d '{"name": "テストアイテム"}'
データ表示
ブラウザかcurlで全件を表示

# 全件表示
curl https://www.51weblab.jp:5001/items
[{"id":1,"name":"テストアイテム"},{"id":2,"name":"テストアイテム2"},{"id":3,"name":"サンプル3"},{"id":4,"name":"サンプル4"}]
- データ検索は文字コードが手抜きなので、ブラウザで動作確認
「テスト」を含むレコードを抽出してます。

まとめ
非常に簡単なアプリではありますが、まずはローカルdockerで作ってみました。
もう少しブラッシュアップしながら(?)最終的にAWS ECSを使ったwebサービス構築までのステップを進めていこうと思います。
ではでは。
