n8nのインフラ環境構築してみた(n8n part1)
これを書いた感想(完走)
- たまには記事書かないとね🧐
- やっぱ記事書くと頭の中整理される📚
- 特にコンテナ(こんたいなー)周辺の知識が整理された📦
- でも公表するなら機密情報消さないとね㊙
- めんどくさがらずに消す🤬
- AIに消させたけど、抜け漏れあるよね
- めちゃめちゃアンチパターン笑(パブリックにEC2、Fargate)
- でもプライベートにおくとお金かかるし、、、(NAT gw)
- まぁまずは社内だからいいか
- コンソールでやると理解捗る👍
- terraformといい対比で勉強なる❤️
- でも、これ続編あるんだよね。。。。
経緯
-
発端は社内のなんでも掲示板
-
事業部長曰く
- ゆくゆくはお客さんへ提案する
- まずは動くものを作成して欲しい
- ドメインにアクセスしたらn8nのログイン画面が出ることまでやってくれればOK
-
渡されたもの(一部変更済み)
-
docker-compose.yml
services: n8n: image: docker.n8n.io/n8nio/n8n:latest container_name: n8n ports: - "5678:5678" # EC2のSGは"ALBのSGのみ許可" env_file: - .env volumes: - n8n_data:/home/node/.n8n # ← named volume に変更 - /opt/n8n/files:/files restart: unless-stopped volumes: n8n_data: name: n8n_data -
.env
# ====== 必須・基本 ====== N8N_ENCRYPTION_KEY=xxxxxxxxxxxx GENERIC_TIMEZONE=Asia/Tokyo # 外向きURL(ALB+ACMで公開する"ルートドメイン") N8N_HOST=n8n.com N8N_PROTOCOL=https WEBHOOK_URL=https://n8n.xxxx.com # ポート(既定は5678。明示したい場合だけ) N8N_PORT=5678 # 実行履歴の自動削除(お好みで調整) EXECUTIONS_DATA_PRUNE=true EXECUTIONS_DATA_MAX_AGE=336 # 14日=336時間 # テレメトリ/通知(任意) N8N_PUBLIC_API_DISABLED=true N8N_DIAGNOSTICS_ENABLED=false N8N_VERSION_NOTIFICATIONS_ENABLED=false # バイナリデータ保存(Communityは filesystem が扱いやすい) N8N_DEFAULT_BINARY_DATA_MODE=filesystem
-
-
サンドボックスで作成
- EC2
- ECS fargate
-
EC2作成後
-
https://n8n.dev.work/signin へのアクセスめっちゃ遅い問題
- 作成したALBのうち1つがプライベートサブネットにあった(凡ミス)
-
https://n8n.dev.work/signin へのアクセスめっちゃ遅い問題
-
ECS作成後
- もらったレビュー
- コストを算出すること
- VPCとALBは、EC2と同じものを使用すること
- Fargate Spotを使用すること
- EFSを使用すること
- 構成図作成すること
- ALBは便宜的に1つにしてもOK
- ECSはパブリックサブネットでも可
- n8nを今後本格的に使っていくと確定してから、NAT(EIP)つけてプライベートサブネットで稼働させる。でOK。
- 一旦動くものを提出する
- プライベートサブネットを使用するにはNATが必要($30/月)
- 現状EC2もパブリックサブネットで稼働させている(SGは社内からのみ)
- もらったレビュー
所見
- 運用コストは安いほうがいい。特に本格運用前は
- ありものを活用する
- 今回は安いアーキテクチャを選んだ
- ARM(x86に比べて2割引)、FargateSpot(停止する可能性あるも7割引)
- ALBのコスト算出しにくい(変動する)。ざっくり1台MAX$17/月は固定でかかる。ここに通信量による従量課金が追加
- 固定で金かかるものはリソース削除忘れが怖い
- ECS execはデフォルトで有効にするべき(コンテナ入れる)
- EFS
- 脇役のリソースのイメージがあったが、調べると
沼る奥が深いリソースだった - AWSおすすめの設定はコスト高(安全ではある)
- 設定項目多い
- リージョン or 単一AZ
- bursting(バースト) or enhanced(拡張)
- enhancedなら
- Provisioned(プロビジョン二ング済み) or Elastic(伸縮自在)
- パフォーマンスモード
- 汎用 or 最大 I/O
- アクセスポイント
- 脇役のリソースのイメージがあったが、調べると
- 設定項目はエビデンス残すこと
- せっかく自分が構築したインフラなので、n8nのアプリ使ってみたい
アクセスできる場所
- 東京事業所、北海道事業所、VPN
構成図
[n8n-infra.drawio]

リソース
EC2
月額:
固定:$39(EC2 t3mediam 24H 30D)
変動:ALB($17+通信の従量課金)
※ALBはEC2、ECS共通
- ACM [xxxxxxx-xxxxxxxxx]
- VPC [n8n-2-vpc]
- サブネット
- [n8n-subnet-public1-ap-northeast-1a]
- [n8n-subnet-public2-ap-northeast-1c]
- [n8n-subnet-private1-ap-northeast-1a]
- [n8n-subnet-private2-ap-northeast-1c]
- サブネット
- ALB [n8n-2-alb]
- SG [n8n-alb-sg]
- リスナー [HTTPS:443]
[※リスナールール]のホストヘッダーでEC2とECSを分けてる
- EC2 [n8n.dev.ec2]
- SG [n8n-ec2-sg]
ECS
月額:
-
固定:$10.5(Fargate Spot)+2.4(EFS 5GB)
-
変動:ALB($17+通信の従量課金)
※ALBはEC2、ECS共通
※FargateSpotなのでAWS側のリソース使用状況によってタスク停止する可能性があります。
- ACM [xxxxxxx-xxxxxxxxx]
- VPC [n8n-vpc]
- サブネット(EC2と同じサブネット)
- [n8n-subnet-public1-ap-northeast-1a]
- [n8n-subnet-public2-ap-northeast-1c]
- [n8n-subnet-private1-ap-northeast-1a]
- [n8n-subnet-private2-ap-northeast-1c]
- ALB [n8n-alb]
- SG [n8n-ecs-alb-sg]
- リスナー [HTTPS:443
※リスナールール のホストヘッダーでEC2とECSを分けてる
- ECS
- cluster [n8n-ecs-cluster]
- service [n8n-ecs-service]
- タスク定義 [n8n-ecs-task]
vCPU:1 Memory:2GiB- SG [n8n-ec2-sg]
- タスクロール [n8n-ecs-task-role]
- 実行ロール [n8n-ecs-task-execution-role]
- EFS
- [n8n-ecs-efs]
※5GBのストレージ使用で$2.4/月(コスト重視でバーストモード使用)- アクセスポイント [n8n-efs-access-point]
- SG [n8n-efs-sg]
- EFSディレクトリ /home/node/.n8n
- [n8n-ecs-efs]
上司さん指摘詳細
-
コメント
今のスペックで稼働したら、どれぐらい金かかるか試算してみたりした?
→ECSだけでざっくり $89/月(24時間稼働 task数:1 CPU:2 Memory:4) ここに+ALB
→同じ条件で、ARMだと$71/月+ALB
→作り直した条件(24時間稼働 task数:1 CPU:1 Memory:2 FargateSpot ARM)だと$ 10.5/月+ALB (10.5 = 35*0.3 spot料金)コンソールでどうやったらCloudFormationになるんだろうね。
→ECS cluster ECS serviceについて、これらリソースをコンソールでポチると裏でCloudFormationが動く (こんな記事がありました)
私の担当案件内だとElasticBeansTalkが同様今あるALBをつかって、後ろのECSに流すほうがいいかなって思うんだよね。
- →処置完了。[ECSservice]を既存ALBの後ろにおきました
タスクの大きさだけど、2CPUだとちょっと大きい気がしていて、とりあえず1
-
→処置完了。今はvCPU1(1024) memory2(2048)
{ "cpu": "1024", "executionRoleArn": "arn:aws:iam::1234567890:role/ecsTaskExecutionRole", "family": "n8n-ecs-task", "memory": "2048", "networkMode": "awsvpc", "placementConstraints": [], "registeredAt": "2025-09-26T07:13:19.317Z", "registeredBy": "arn:aws:sts::1234567890:assumed-role/AWSReservedSSO_AdministratorAccess_adcdefghijklmnop/", "requiresCompatibilities": [ "FARGATE" ], "revision": 6, "runtimePlatform": { "cpuArchitecture": "ARM64", "operatingSystemFamily": "LINUX" }, "status": "ACTIVE", "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:1234567890:task-definition/n8n-ecs-task:6", "taskRoleArn": "arn:aws:iam::1234567890:role/n8n-ecs-task-role", "volumes": [ { "efsVolumeConfiguration": { "authorizationConfig": { "iam": "DISABLED" }, "fileSystemId": "fs-0000000000002", "rootDirectory": "/", "transitEncryption": "ENABLED" }, "name": "n8n-data" } ], "tags": [] }
Fargateスポットで立ててほしいかな。やすいので。
→ARMで作って、Fargateスポット設定しました。全1台:Fargateスポット1台で設定。
→ECS execもオンに。
aws ecs execute-command \ --cluster n8n-ecs-cluster \ --task タスクID \ --container n8n \ --command "/bin/sh" \ --interactiveあとはあれか、データをどう保持するかだね。
→EFS設定完了。
コンテナ([11111abc111111111111]入ってdf -hコマンドで表示。”test.txt”を作成。新しいタスク([
2aaaaaaaaaaabbbbbbbccc2])を立てて、古いタスク([11111abc111111111111])時に作成した”test.txt”があるか確認。ある。タスクが変わってもEFSが永続していることを確認できた。
参考
Discussion