無料でIFTTTの代替、n8nをGCE f1-microで動かす

2021/7/23追記 無料対象のインスタンスタイプがf1-microからe2-microに変わるようです。スペックが2倍くらいになります。 とは言ってもそれでもリソースは限られているので、この記事の方針は有効かなと思います。

IFTTTは昔よく使っていたんですが今は無料ではほとんど使えなくなり、もともと遅延も結構気になっていたので しばらくはプログラム書いてCloud Runでwebhookイベントを受けて動かすみたいなことをやっていました。

代替手段を探していた人も多いんじゃないかと思いますが、無料となるとなかなか良いものが見つかりません。

一方自前で動かすIFTTT的なツールとしてHuginnやn8nといったものがあります。これが結構自由度も高く使い勝手 が良さそうだったので、n8nを使ってみることにしました。

しかしローカルで動かすのはネットワーク的にも管理的にも面倒なので、 無料枠で維持できるGCEのf1-microで動かそうと決めました。 無料なだけあってかなりスペックは低いですが、スワップを使うなど調整を入れてなんとかちゃんと使える 状態にはできたと思います。

個人的なちょっとした用途などには十分使えるのではないでしょうか。

(ちなみに、最初はとりあえず普通にインストールして試して動きこそしましたが、程なくしてVMが死にました)

VMインスタンス作成 Link to heading

次のようなインスタンスであれば無料で使えるらしいので、これをGCPコンソールから作成。

  • インスタンスを作るリージョン
    • us-central1
    • us-west1
    • us-east1
  • インスタンスタイプ
    • f1-micro
  • 1個まで
  • ブートディスク
    • 30GBまで(standard HDD)
  • 静的外部IPアドレス
    • ちゃんと割り当てる(未使用で放置すると課金対象)

Dockerを使ってアプリを動かしたいのですが、f1-microはメモリが0.6GBしかないのでスワップを使わないときつい。 Container Optimized OSを使いたいところですが、これはスワップをさせないような作りになっているらしく ブートディスクはUbuntu 20.04LTSを選択しました。 また、通信量に応じても従量課金はされますがこちらも無料枠1GB(例外あり)まである上、 アプリの性質上通信データ量は小さく仮にアタックが来たとしても高が知れていると思います。

スワップの設定 Link to heading

4GBのスワップを作成して割り当てる

$ sudo dd if=/dev/zero of=/swapfile bs=1M count=4096
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
$ sudo swapon /swapfile

確認

$ free -m

/etc/fstab に下記の1行を追加して、再起動時に自動マウントするようにしておきます。

/swapfile none swap sw 0 0

Dockerのインストール Link to heading

DockerとDocker Composeをインストール

$ sudo apt-get update
$ sudo apt-get install docker
$ sudo apt-get install docker-compose

このままだと権限が無くてdockerコマンドが使えないのでグループに追加。

$ sudo usermod -aG docker $USER
$ newgrp docker
$ docker run hello-world

SSL Link to heading

アプリ間連携用のネットワーク作成

$ docker network create nginx-proxy-network

nginx-proxy + letsencrypt用のdocker-compose.yml

version: '2'

networks:
  default:
    external:
      name: nginx-proxy-network

services:
  nginx-proxy:
    container_name: nginx-proxy
    image: jwilder/nginx-proxy:latest
    privileged: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./certs:/etc/nginx/certs:ro
      - ./vhost:/etc/nginx/vhost.d
      - ./html:/usr/share/nginx/html
    restart: always

  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: letsencrypt
    privileged: true
    volumes:
      - ./certs:/etc/nginx/certs:rw
      - ./vhost:/etc/nginx/vhost.d
      - ./html:/usr/share/nginx/html
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      NGINX_PROXY_CONTAINER: nginx-proxy
    restart: always

起動

$ docker-compose up -d

n8n Link to heading

n8n用のdocker-compose.yml

version: '3.1'

services:

  n8n:
    image: n8nio/n8n
    restart: always
    environment:
      - EXECUTIONS_PROCESS=main
      - GENERIC_TIMEZONE
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER
      - N8N_BASIC_AUTH_PASSWORD
      - N8N_PROTOCOL=http
      - N8N_PORT=8080
      - N8N_HOST=${BASE_URL}
      - WEBHOOK_TUNNEL_URL=https://${BASE_URL}/
      - VIRTUAL_HOST=${BASE_URL}
      - VIRTUAL_PORT=8080
      - VIRTUAL_PROTO=http
      - VIRTUAL_NETWORK=nginx-proxy-network
      - LETSENCRYPT_HOST=${BASE_URL}
      - LETSENCRYPT_EMAIL=${EMAIL}
    volumes:
      - ~/.n8n:/home/node/.n8n
    command: /bin/sh -c "n8n start"
    expose:
      - "8080"
    networks:
      - proxy-tier

networks:
 proxy-tier:
   external:
     name: nginx-proxy-network

.envのサンプル

GENERIC_TIMEZONE=Asia/Tokyo

N8N_BASIC_AUTH_USER=yourusername
N8N_BASIC_AUTH_PASSWORD=yourpassword

BASE_URL=yourdomain

はじめはDBにPostgreSQLを使おうとしていたのですがスペック的にきつかったので、 結局一番ライトにn8nでデフォルトで使われているSQLiteを使うことにしました。 docker-composeにする必要はなかったかもしれない。

f1-microはCPUが1vCPU(最大で)しかありませんが、EXECUTIONS_PROCESS=mainとするとシングルプロセスで実行してくれるので こちらの方が効率よくやりくりしてくれるはず。

起動

$ docker-compose up -d

使ってみる Link to heading

ワークフローの一例。今のところちゃんと使えていそうですが、しばらく様子をみてみます。