開発ツール・環境構築

【完全版】n8nをVPS上にDocker構築する方法(独自ドメイン・SSL対応)

n8nを「自分専用の編集エンジン」として使いたいと思ったとき、クラウド版では機能制限や運用面での制約が目立ちます。

この記事では、n8nをVPS上に構築し、独自ドメインとSSLを設定して、Webアプリとして安定運用できるようにするまでの工程をすべて記録しています。

VPS構築が初めての方でも再現できるよう、環境構築から設定ファイル、実行時の注意点まで丁寧にまとめました。

n8nを本格的な業務オートメーションの中核として活用したい方の参考になれば幸いです

なぜ自前でn8nを立てる必要があるのか?

n8nを本格的に活用しようと考えたとき、公式が提供しているクラウド版や無料プランでは、実行回数や機能の制限が多く、思うように仕組み化を進めることができません。

常時稼働や外部サービスとの連携を安定して行うには、自分でVPSを用意して、n8nを独自環境に構築する必要があります。
さらに、Webhookの受信や認証まわりで必須となるSSL対応や独自ドメインの運用も、VPS環境であれば自由に設計できます。

この記事では、なぜクラウドではなくVPS構築が前提になるのか、その背景と理由を最初に整理したうえで、構築の全手順を記録していきます。

無料プランでは制限が大きすぎる理由

n8nの無料プランでは、実行数やワークフローの保存数、APIアクセスの制限などが厳しく設定されています。

試してみるには十分ですが、定期実行や複数の外部連携を本格的に組み込もうとすると、すぐに上限に達してしまいます。

また、保存期間が短いためにエラー調査やログ追跡も十分に行えません。

クラウドサービスでは“常時稼働”が難しい

n8nは一度仕組みを構築したら「動かしっぱなし」にしておきたいツールです。

しかし、クラウドで提供されている環境ではタイムアウトやスリープが発生しやすく、Webhookやスケジュール処理が安定しないことがあります。

また、外部サービスとの連携でIP制限をかけている場合、自分でサーバーを持っていないと制御が難しいのも現実です。

独自ドメインで運用することの本質的意味

自分でn8nをホストする大きな利点のひとつが、独自ドメインでの運用です。これにより、Webアプリとして明確な入口が作れ、社内ツールや個人用途としても扱いやすくなります。

さらに、LINEやGoogleなどのWebhookを受ける際に、SSL対応済みの独自ドメインでなければ登録できないケースもあります。将来的な拡張性や信頼性を考えたとき、独自ドメインは必須ともいえます。

準備したものと構築前の前提条件

n8nをVPS上に構築するにあたっては、事前にいくつかの準備が必要です。

読者によって使用するVPSやドメイン、OS構成に違いがあると、同じ手順を踏んでもエラーや認識のズレが生じやすくなります。

この記事では、実際に構築した際の前提条件を明示することで、再現性を高められるようにしています。

この記事で構築する全体ステップ

本記事では、n8nをWebアプリとして常時公開運用するために、以下3つのステップに分けて構築していきます。段階ごとに必要な作業と注意点を整理し、すべての読者が確実に再現できるよう構成しています。

  1. VPSの初期設定
     - SSH鍵ログインの設定(パスワード認証無効化)
     - ポート変更、ファイアウォール(UFW)構成
     - サーバーの最低限のセキュリティ設定
  2. Docker環境の導入
     - Docker本体とdocker-compose(v2)のインストール
     - Dockerの動作確認と依存パッケージの導入
  3. n8nの構築と公開設定
     - docker-compose構成ファイルによるn8n起動
     - 独自ドメインでのリバースプロキシ設定(Nginx)
     - CertbotによるSSL証明書の取得と常時HTTPS化

VPSサーバーの初期設定について

n8nの構築に入る前に、VPSそのものを安全に運用するための初期設定を必ず済ませておいてください。

特に、SSHの公開鍵認証化、不要ポートの遮断、UFWやFail2banの導入は必須です。詳細は以下の記事を参照してください。VPSの準備がまだの方は、まず下記のマニュアルを確認しておくことをおすすめします。

▶︎【conoHa】VPSを安全に使うための初期設定マニュアル

このマニュアルでは、Ubuntu 22.04 LTS環境を前提に、最低限のセキュリティ設定を整える手順を紹介しています。

ConoHa VPSを例に説明していますが、内容は他のVPSサービス(さくらのVPS、さくらクラウド、さくらリモートサーバーなど)でも基本的に共通しています。

使用VPSとドメイン(例:ConoHa example.co.jp)

今回の構築では、国内VPSサービスのConoHaを利用しました。サーバーのスペックは1GBプランで十分動作します。

ドメインは独自に取得したもので、そのサブドメインを「n8n.任意のドメイン名」として使用しています。

独自ドメインとサブドメインの設定ができる環境であれば、どのドメインサービスでも問題ありません。構築時点で独自ドメインの管理権限を持っていることが前提となります。

VPSとドメインをセットで管理できる環境を整えておくと、DNS設定やSSL運用もスムーズに行えます。

前提となるOS構成とn8nのバージョン

サーバーOSはUbuntu 22.04 LTSを使用しています。

n8nのバージョンは構築当時で「1.48.0」を前提に進めていますが、バージョンによって内部の設定構造が変わる可能性があるため、実行前に公式ドキュメントで最新情報を確認することをおすすめします。

Docker & docker-compose のインストール手順

n8nをDocker上に構築するには、あらかじめDocker本体とdocker-compose(v2系)の導入が必要です。このセクションでは、Ubuntu 22.04 LTS 環境において最小構成でDocker環境を整える手順を示します。

古いDockerパッケージの削除(任意)

過去にインストールされた古いバージョンが存在する場合、先に削除しておきます。

sudo apt-get remove docker docker-engine docker.io containerd runc

必要な依存パッケージのインストール

HTTPS通信とリポジトリ連携に必要なパッケージを導入します。

sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release

Docker公式GPG鍵の追加

Dockerリポジトリの信頼性を保証するための鍵を追加します。

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

Dockerのリポジトリを登録

APTパッケージ管理にDockerの安定版リポジトリを追加します。

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Dockerとdocker-compose(v2)のインストール

Docker EngineとCLI、Compose v2を一括でインストールします。

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Dockerが正しくインストールされたか確認

以下のコマンドでバージョン確認ができればインストール成功です。

docker -v
docker compose version

下記のようにバージョン情報が表示されれば、DockerとComposeは正しく導入されています。

Docker version 28.1.1, build 4eba377
Docker Compose version v2.35.1

n8nをDockerで構築する手順

ここが本記事のメイン。VPSへの構築〜Dockerコンテナ起動までの全手順を整理して掲載します。 このプロジェクトでは、これまでと同様にホームディレクトリ下の~/projects配下に専用ディレクトリを作成し、n8n関連ファイルを構成しています。

n8n用ディレクトリとdocker-composeファイルの作成

まずはn8nを配置する作業用ディレクトリを作成し、その中でdocker-composeファイルを準備します。

mkdir -p ~/projects/ai_editor
cd ~/projects/ai_editor

次に、n8nを定義するdocker-compose.ymlファイルを作成します。ここではSQLiteベースでシンプルに構築します。

vi docker-compose.yml

以下の内容を貼り付けます:

version: "3.8"
services:
  n8n:
    image: n8nio/n8n
    container_name: n8n
    restart: always
    ports:
      - "5678:5678"
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=${N8N_USER}
      - N8N_BASIC_AUTH_PASSWORD=${N8N_PASS}
      - N8N_HOST=${N8N_HOST}
      - N8N_PORT=5678
    volumes:
      - ./n8n/.n8n:/home/node/.n8n

環境変数とマウント構成の設定

環境変数を.envファイルにまとめ、機密情報を切り離して管理します。

vi .env

内容の一例:

N8N_USER=admin
N8N_PASS=your_secure_password
N8N_HOST=n8n.example.com (※ご自身のドメインに読み替えてください)
N8N_PROTOCOL=https
N8N_PORT=443
N8N_SECURE_COOKIE=true

※本記事内では、実際のドメインを保護する目的で n8n.example.com を使用しています。
 読者の環境に合わせて、N8N_HOST にはご自身の独自ドメインを指定してください

永続化のためのディレクトリも事前に作成しておきます。

mkdir -p ./n8n/.n8n

初回起動・動作確認(ローカルアクセスでの接続確認)

すべての構成が完了したら、以下のコマンドでn8nを起動します。

docker compose up -d

コマンドを実行すると下記のように、dockerのインストールが開始されます。

bepro@vm-09d41400-18:~/projects/ai_editor$ docker compose up -d
WARN[0000] /home/bepro/projects/ai_editor/docker-compose.yml: the attribute version is obsolete, it will be ignored, please remove it to avoid potential confusion
[+] Running 9/12
⠋ n8n [⣿⣿⣿⣿⣿⣿⣶⣿⣿⣿⣿] 178.9MB / 203.5MB Pulling 19.1s
✔ f18232174bc9 Pull complete 1.0s
⠙ 8cc209e5911c Extracting [=================================================> ] 42.21MB/42.95MB 15.2s
✔ d7a069a788e0 Download complete 0.7s
✔ 42ec265e2954 Download complete 1.3s
✔ c8212b925ea8 Download complete 11.9s
✔ 4f4fb700ef54 Download complete 2.0s
⠙ 8407fa236366 Downloading [=========================================> ] 103.2MB/125.7MB 15.2s
✔ a85740143146 Download complete 12.8s
✔ 3d840b6f91fa Download complete 14.4s
✔ 90ea31d66485 Download complete 13.6s
✔ a9ad41dbf2d3 Download complete

起動後、ログを確認して問題が発生していないかチェックします。

docker compose logs -f

ブラウザで以下のURLにアクセスし、n8nの管理画面が表示されれば構築は完了です。

http://[VPSのIPアドレス]:5678

n8nの初回アクセス時、上記のような画面が表示されることがありますが、これは正常です。SSL化することで解消されます

この画面はエラーではなく、接続そのものは成功しています。 ただし、n8n側がセキュアな接続(HTTPS)を前提としているため、HTTPでのアクセスを拒否している状態です。

この挙動は、n8nのセキュリティ機能 N8N_SECURE_COOKIE=true が有効なために発生します。 HTTPS未設定の段階では、セッション用Cookieを安全に扱えないと判断され、アクセスがブロックされます。

この問題は、次のステップで行う「独自ドメイン+SSL設定(Nginx+Let's Encrypt)」によって解消されます。 この画面が表示された時点で、n8n自体の起動には成功しているので安心してください。

ブラウザへの表示ができないかった場合

ファイアウォールの確認とポートの開放の設定を行なってください。

ブラウザでアクセスできない場合、VPS側のファイアウォール(UFW)がポート5678をブロックしている可能性があります。以下の手順で確認と許可を行ってください。 現在のUFWの状態を確認:

sudo ufw status

もし 5678 ポートが開放されていない場合は、以下のコマンドで許可してください。

sudo ufw allow 5678

変更後、ファイアウォールを再読み込みするには以下を実行します:

sudo ufw reloadSSL設定は正常に完了しています。

独自ドメインとSSLの設定(Nginx+Certbot)

n8nをWebアプリとして常時HTTPSで運用するために、NginxとLet's EncryptによるSSL対応を行います。このセクションでは、リバースプロキシの設定から証明書の取得、HTTPS化の確認までを段階的に説明します。

DNS設定でVPSに向ける(Aレコード設定)

ドメイン管理サービスのDNS設定画面から、サブドメインのAレコードをVPSのグローバルIPアドレスに向けます。これにより、外部からドメインでアクセスした通信がVPSへ転送されます。

n8n.example.com → 163.44.xxx.xxx(VPSのIPアドレス)
(※ご自身のドメインに読み替えてください)

Nginxのリバースプロキシ設定内容

n8nは通常ポート5678で待ち受けますが、外部アクセスにはHTTPS経由の443番ポートを使います。そのため、Nginxでリバースプロキシを構成して、外部からのアクセスをn8nに中継します。

まずは証明書を取得するためのHTTP構成(ポート80)と、取得後のHTTPS構成(ポート443)を一つのファイルにまとめて定義します。

sudo vi /etc/nginx/sites-available/n8n

以下の内容を、Nginxの設定ファイル /etc/nginx/sites-available/n8n に保存してください。

設定ファイルの作成:

まずは、Let’s Encryptの証明書を取得するための「HTTPのみ構成(80番ポート)」を設定します。

server {
    listen 80;
    server_name n8n.example.com;
    
    # HTTPリクエストをHTTPSへリダイレクト
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name n8n.example.com;
    
  #  ssl_certificate /etc/letsencrypt/live/n8n.example.com/fullchain.pem;
  #  ssl_certificate_key /etc/letsencrypt/live/n8n.example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://localhost:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

※SSL構文は一時的にコメントアウトしておく
CertbotでSSL証明書を発行する前に、nginxの設定ファイルに含まれる以下の2行は一時的にコメントアウトしておいてください。証明書がまだ存在しない状態でこれらが有効化されていると、nginxの構文チェック(nginx -t)が失敗し、Certbotの動作も通らなくなります。

# ssl_certificate /etc/letsencrypt/live/your-domain/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/your-domain/privkey.pem;

証明書の取得が完了してから、コメントアウトを解除して再度 nginx を再起動することで、HTTPS通信が有効になります。

設定ファイルの有効化

設定後、有効化するには以下のコマンドを実行します:

sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/

構文テストとNginx再起動:

Nginxの構文をチェックしてから再起動します:

sudo nginx -t
sudo systemctl restart nginx

CertbotでLet's Encrypt証明書の自動更新化

次に、SSL証明書の発行を行います。まだ証明書が存在しない状態でNginx構成に443番ポートを含めると `nginx -t` が失敗するため、証明書の取得が先に必要です。 以下を実行して、証明書を発行します:

sudo certbot --nginx -d n8n.example.com (※ご自身のドメインに読み替えてください)

成功すれば、以下のディレクトリに証明書が生成されます:

/etc/letsencrypt/live/n8n.example.com/ (※ご自身のドメインに読み替えてください)

このあと再度Nginxを構文チェック・再起動してください:

sudo nginx -t
sudo systemctl restart nginx

自動更新が有効になっているか確認するには以下を実行します:

sudo certbot renew --dry-run

すでにSSL証明書が存在する場合の対応

もし、すでに対象ドメインに対してLet's Encryptの証明書を取得済みだった場合、以下のようなメッセージが表示されることがあります。

Certificate not yet due for renewal
You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
(ref: /etc/letsencrypt/renewal/ドメイン.conf)

この場合は、新しい証明書を発行せず、既存の証明書をNginxに再適用するだけで十分です。下記の選択肢が提示されます:

1: Attempt to reinstall this existing certificate
2: Renew & replace the certificate

→ このときは 「1」を選択してください。 Certbot が既存証明書を Nginx 設定へ再適用し、自動で HTTPS 構成(443番ポート)を追記してくれます。 最後に、Nginx の構文チェックと再起動を忘れずに実行してください:

ブラウザから https://n8n.example.com にアクセスできる状態の確認

ブラウザで以下のURLにアクセスして、n8nのログイン画面が表示されることを確認してください。

https://n8n.example.com (※ご自身のドメインに読み替えてください)

鍵マークが表示され、証明書情報がLet's EncryptになっていればSSL対応は完了です。

n8n初回アクセス時のセットアップ画面について

n8nの構築が完了してHTTPS経由でアクセスできるようになると、初回のみ「オーナーアカウントの作成」画面が表示されます。これは管理者としてログインするための初期設定画面であり、以後このステップはスキップされログイン画面に遷移するようになります。

入力する情報

以下の項目をすべて入力する必要があります。

項目説明
Email任意のメールアドレス(通知設定に使用)
First Name任意。UI表示のみで機能には影響しません
Last Name任意。UI表示のみで機能には影響しません
Password8文字以上で、英大文字・数字をそれぞれ1文字以上含める必要があります

構築完了の目安

このセットアップを完了し「Next」を押すと、n8nの本来のログイン画面にリダイレクトされます。 この状態になれば、n8nのWebアプリ化と初期導入は正常に完了しています。 以後は再起動してもこの画面は表示されず、永続化設定に基づいてログイン画面が表示されます。

運用してわかった構築上の落とし穴

構築記録ならではの、リアルなトラブルとその対処法を示すセクション。

最初の起動で403になる理由

初回起動後、n8nにアクセスしようとすると403 Forbiddenが返されるケースがあります。これはNginx側でベーシック認証やプロキシ設定に不備がある場合に発生します。

特に n8n 側でベーシック認証を有効にしているにもかかわらず、環境変数が正しく設定されていないことが原因です。

N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=adminpass

n8nのポート設定が競合する問題

n8nはデフォルトでポート5678を使用しますが、他のプロセス(開発系ツールや既存のNode.jsアプリなど)が同じポートを使っていると、n8nが起動できません。

VPS上でポートの使用状況を確認し、競合を解消する必要があります。

sudo lsof -i :5678
sudo netstat -tuln

必要であればdocker-compose.yml内でホスト側ポートを変更します。

ports:
  - "8080:5678"

SSLが失効するタイミングと監視方法

Let’s Encryptの証明書は90日間の有効期限があるため、自動更新に失敗していると気づかないうちにSSLが切れてしまいます。

証明書の有効期限を定期的に確認し、cronや監視ツールでアラートを設定しておくと安心です。

sudo certbot renew --dry-run
openssl s_client -connect n8n.example.com:443 -servername n8n.example.com

docker-compose down/upで設定が失われないための注意点

n8nを再起動するためにdocker-compose down/upを実行する際、設定が保存されていないとリセットされてしまうことがあります。

これを防ぐためには、明示的にボリュームやデータディレクトリを永続化する必要があります。

volumes:
  - ./n8n/.n8n:/home/node/.n8n

また、下記のように`.n8n`ディレクトリがコンテナとマウントされていることを確認してください。

docker volume ls

docker inspect <container_name>

この構成を採用するメリットと注意点

読者が「この構築を選ぶべきか?」を判断するための参考材料。

サーバーを握ることでできること

自前でVPSを用意し、n8nをDockerで構築することで、あらゆる構成やカスタマイズが自由に可能になります。

例えば、Webhookの挙動制御、API連携のセキュリティ強化、外部DBとの連携、Git連動によるフローのバージョン管理など、市販サービスでは難しい柔軟な拡張ができます。

  • n8n本体のアップデートを自分のタイミングで管理
  • 任意のドメインやSSL証明書を導入可能
  • 認証方式やセキュリティポリシーを細かく制御

メンテ・コスト・自己責任の現実

自由度と引き換えに、すべての構成やトラブルは自力で対処する必要があります。OSアップデート、証明書の更新、n8nの破損対応など、放置しているとサービスが停止するリスクもあります。

sudo apt update && sudo apt upgrade
sudo certbot renew --dry-run

また、クラウドサービスと違って、自動で障害対応されるわけではないため、定期的なログチェックや障害監視の仕組みを自前で用意する必要があります。

よく読まれている記事

1

IT入門シリーズ 🟢 STEP 1: ITの基礎を知る(ITとは何か?) 📌 IT初心者が最初に学ぶべき基本知識。ITの概念、ネットワーク、OS、クラウドの仕組みを学ぶ ...

2

「私たちが日々利用しているスマートフォンやインターネット、そしてスーパーコンピュータやクラウドサービス――これらの多くがLinuxの力で動いていることをご存じですか?無料で使えるだけでなく、高い柔軟性 ...

3

この記事は、Linuxについて勉強している初心者の方向けに「Shellスクリプト」について解説します。最後まで読んで頂けましたら、Shellスクリプトはどのような役割を担っているのか?を理解出来るよう ...

-開発ツール・環境構築