n8nをGCPでセルフホスト

# はじめに
n8nというワークフローシステムがあり、SaaSでも使えるんですが、自分のPCに環境を作ってそこで動かすこともできるので、その内容です。自分の記録のためと、誰かの参考になれば。

たぶんほとんど無料か微課金です。またワークフローシステムからいろいろなシステムへアクセスするため、セキュリティ的に突破されるとよくないのでSSLで作りました。（それが普通なのかもしれないけど、手間がかなり増える）

https://n8n.io/

## 環境の超概要
- GCP
    - GCE
        - 仮想端末
        - ここにn8nサーバーを立てる
    - Cloud DNS
        - ドメイン登録
- お名前.com
    - ドメイン登録

# 手順
## 1. お名前.comで無料DNSを取得
- １つ目は無料とのこと。詳細は割愛
- Freenomというサイトでも、１年無料でDNSを得られるらしい
- ここではこれ以降の説明のために、仮に`myserver.com`を取得したことにしておく


## 2. GCEの設定
- e2-micro
- OS: Ubuntu 24.04 LTS
- ディスク: 10GB
- httpとhttpsのポートを開ける
- 外部IPアドレスを得る
    - 再起動すると変わる（エフェメラル）だけど、とりあえずそれで運用してみて、困ったら静的に変える
- ローカルの`ssh-keygen`で作った公開鍵を、GCE＞メタデータ＞SSH認証鍵＞認証鍵へ追加しておく


## 3. Cloud DNSの設定
- DNSを登録し、ネームサーバー1～4を得る
- レコードセットを追加
    - `n8n.myserver.com`に対して、GCEの外部アドレスを設定
    - GCEを再起動するなどしてIPアドレスが変わったらここを修正する必要がある


## 4. お名前.comの設定
- ネームサーバー＞ネームサーバーの変更で、Googleのネームサーバー1～4を設定
- 【確認】
    - ローカルからSSH接続で、秘密鍵を使って`n8n.myserver.com`へ接続できるはず

## 5. ふたたびGCEの設定
- Docker環境を構築
    - [Ubuntu | Docker Docs](https://docs.docker.com/engine/install/ubuntu/)
    - 一般的なことなので割愛

### 5.1. Docker composeの定義ファイル
- Docker composeの定義ファイルをローカルで作って、githubにアップ(push)して、GCEで取得(pull)
    - 一般的なことなので手順は割愛
- ファイルは下記
    - Traefik自体にACME機能があり、下記の設定（traefikのcommand）によって、`${DATA_FOLDER}/letsencrypt:/letsencrypt`以下に証明書が置かれる
```yaml:docker-compose.yml
version: "3"

services:
  traefik:
    image: "traefik"
    restart: always
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.web.http.redirections.entryPoint.permanent=true"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.mytlschallenge.acme.caserver"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ${DATA_FOLDER}/letsencrypt:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro

  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=web,websecure
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true
      - traefik.http.routers.n8n.middlewares=n8n@docker
    environment:
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
    volumes:
      - ${DATA_FOLDER}/.n8n:/home/node/.n8n
```

### 5.2. `.env`ファイル
- `.env`ファイルを、(githubを介さずに）GCEへ格納
```ini:.env
DATA_FOLDER=/root/n8n/
DOMAIN_NAME=myserver.com
SUBDOMAIN=n8n
SSL_EMAIL=mymail@mail.com

# ログの出力先をファイルに吐き出す
N8N_LOG_OUTPUT=file
# ワークフローの実行タイムアウト
EXECUTIONS_TIMEOUT=600
# ワークフローの実行履歴の保存期間
EXECUTIONS_DATA_MAX_AGE=240
# タイムゾーン
GENERIC_TIMEZONE=Asia/Tokyo
```

### 5.3. 起動
- 起動
```sh
docker compose up -d
```
- `https://n8n.myserver.com`へアクセスし、n8nが動作していることを確認


# 参考リンク（大変お世話になりました:bow_tone1:）
- [【GCP】GCEで独自ドメイン設定からSSL対応まで | みんたく](https://mintaku-blog.net/gce-ssl/#google_vignette)
- [GCE の無料枠のサーバを立るときに、初見でハマりそうなところ #GoogleCloud - Qiita](https://qiita.com/ndxbn/items/7ef0a96e409a5b5837bd)
- [n8n（IFTTT,Zappierの代替）をセルフホストして自動化を快適にする #zapier - Qiita](https://qiita.com/malvageee/items/eda4eb3b71a31bc78a4f)


# おわりに
自分用の意図が大きいので、箇条書きばかりですみません。もう一度これを見ながら設定することがあったら、肉付けしていくかもしれません。

ではよきワークフローシステムライフを。