Terraform を使って
Nginx / Flask / PostgreSQL の 3 コンテナ構成を自動構築する手順をまとめます。
Windows / macOS / Linux すべてで動作し、
terraform apply だけで Web アプリ環境が立ち上がります。
自学自習のためにお試しで作成。まずは手元にあるWindows環境で試してみたものになります。
🎯 アーキテクチャ
ブラウザ
│
▼
Nginx (web)
│ reverse proxy
▼
Flask (app)
│ psycopg2
▼
PostgreSQL (pg)
📁 ディレクトリ構成
project-root/
├── main.tf
├── nginx/
│ └── default.conf
└── app/
├── Dockerfile
├── requirements.txt
└── app.py
📝 Nginx 設定(nginx/default.conf)
nginx
server {
listen 80;
location / {
proxy_pass http://app:5000;
}
}
🐍 Flask アプリ(app/app.py)
python
from flask import Flask
import psycopg2
app = Flask(__name__)
@app.route("/")
def index():
try:
conn = psycopg2.connect(
host="pg",
port=5432,
user="exampleuser",
password="examplepass",
dbname="exampledb"
)
cur = conn.cursor()
cur.execute("SELECT 'DB OK' AS status;")
result = cur.fetchone()
return f"Connected to DB: {result[0]}"
except Exception as e:
return f"DB Error: {e}"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
📦 Dockerfile(app/Dockerfile)
dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
📚 requirements.txt
コード
flask
psycopg2-binary
🧱 Terraform(main.tf)
Windows でも確実に動くように abspath() と depends_on を使用。
hcl
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.1"
}
}
}
provider "docker" {}
resource "docker_network" "app_net" {
name = "app_network"
}
resource "docker_image" "postgres" {
name = "postgres:15"
}
resource "docker_container" "postgres" {
name = "pg"
image = docker_image.postgres.image_id
env = [
"POSTGRES_PASSWORD=examplepass",
"POSTGRES_USER=exampleuser",
"POSTGRES_DB=exampledb"
]
networks_advanced {
name = docker_network.app_net.name
}
ports {
internal = 5432
external = 5432
}
}
resource "docker_image" "app" {
name = "myapp:latest"
build {
context = "${path.module}/app"
}
}
resource "docker_container" "app" {
name = "app"
image = docker_image.app.image_id
networks_advanced {
name = docker_network.app_net.name
}
depends_on = [
docker_container.postgres
]
}
resource "docker_image" "nginx" {
name = "nginx:latest"
}
resource "docker_container" "nginx" {
name = "web"
image = docker_image.nginx.image_id
networks_advanced {
name = docker_network.app_net.name
}
ports {
internal = 80
external = 8000
}
volumes {
host_path = abspath("${path.module}/nginx/default.conf")
container_path = "/etc/nginx/conf.d/default.conf"
}
depends_on = [
docker_container.app
]
}
▶ セットアップ
1. Terraform 初期化
コード
terraform init
2. 構築
コード
terraform apply
🌍 動作確認
ブラウザでアクセス:
コード
http://localhost:8000
表示:
コード
Connected to DB: DB OK
これが出れば成功。
🧹 クリーンアップ
コード
terraform destroy
📝 補足
-
Windows の場合、Nginx の設定ファイルは
abspath()を使わないと絶対パス扱いにならずエラーになります。 -
Nginx は Flask より先に起動すると DNS 解決に失敗するため、
depends_onを設定しています。