From 99fc6ba04cb30621ffd7b949a6df7e89f236bde0 Mon Sep 17 00:00:00 2001 From: Michael Hettwer Date: Sat, 14 Mar 2026 18:25:44 +0100 Subject: [PATCH] v0.0.1 --- .gitignore | 5 + defaults/main.yml | 73 +++++++++++++++ meta/main.yml | 11 +++ tasks/cleanup.yml | 43 +++++++++ tasks/config.yml | 106 +++++++++++++++++++++ tasks/docker.yml | 5 + tasks/facts.yml | 44 +++++++++ tasks/install-docker.yml | 54 +++++++++++ tasks/install-package.yml | 61 ++++++++++++ tasks/install-repo.yml | 154 +++++++++++++++++++++++++++++++ tasks/main.yml | 12 +++ tasks/readme.yml | 16 ++++ templates/docker-compose.yml.j2 | 13 +++ templates/n8n-docker.env.j2 | 19 ++++ templates/n8n-docker.service.j2 | 15 +++ templates/n8n-package.service.j2 | 15 +++ templates/n8n-repo.service.j2 | 15 +++ templates/n8n.env.j2 | 19 ++++ templates/n8n.md.j2 | 23 +++++ 19 files changed, 703 insertions(+) create mode 100644 .gitignore create mode 100644 defaults/main.yml create mode 100644 meta/main.yml create mode 100644 tasks/cleanup.yml create mode 100644 tasks/config.yml create mode 100644 tasks/docker.yml create mode 100644 tasks/facts.yml create mode 100644 tasks/install-docker.yml create mode 100644 tasks/install-package.yml create mode 100644 tasks/install-repo.yml create mode 100644 tasks/main.yml create mode 100644 tasks/readme.yml create mode 100644 templates/docker-compose.yml.j2 create mode 100644 templates/n8n-docker.env.j2 create mode 100644 templates/n8n-docker.service.j2 create mode 100644 templates/n8n-package.service.j2 create mode 100644 templates/n8n-repo.service.j2 create mode 100644 templates/n8n.env.j2 create mode 100644 templates/n8n.md.j2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..617ec1c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Generated by MacOS +.DS_Store + +# Generated by Windows +Thumbs.db \ No newline at end of file diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..4fe847d --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,73 @@ +--- +# defaults file for lsa.n8n + +n8n: true + +n8n_default_user: "n8n" +n8n_default_group: "n8n" +n8n_default_path: "/srv/n8n" + +n8n_default_host: "localhost" +n8n_default_protocol: "http" +n8n_default_port: 5678 +n8n_default_timezone: "UTC" + +n8n_default_image: "n8nio/n8n:latest" + +n8n_default_docker_uid: "1000" +n8n_default_docker_gid: "1000" + +n8n_default_repo: "https://github.com/n8n-io/n8n.git" +n8n_default_repo_version: "master" +n8n_default_build_command: "pnpm build" +n8n_default_start_command: "pnpm start" + +n8n_default_package_name: "n8n" +n8n_default_package_version: "latest" +n8n_default_package_bin: "/usr/bin/n8n" + +n8n_default_db: + host: "127.0.0.1" + port: 5432 + name: "n8n" + user: "n8n" + password: "change-me" + type: "postgres" + +n8n_sites: [] +# n8n_sites: +# - name: "n8n" +# deploy_type: "package" # docker, repo, package +# path: "/srv/n8n" +# systemd: true +# state: "present" +# db: +# host: "127.0.0.1" +# port: 5432 +# name: "n8n" +# user: "n8n" +# password: "secret" +# type: "postgres" +# app_options: +# host: "n8n.example.com" +# port: 5678 +# protocol: "https" +# webhook_url: "https://n8n.example.com/" +# timezone: "UTC" +# repo_path: "https://github.com/n8n-io/n8n.git" +# repo_version: "master" +# build_command: "pnpm build" +# start_command: "pnpm start" +# package_name: "n8n" +# package_version: "latest" +# package_bin: "/usr/bin/n8n" +# clean_path: false +# docker_options: +# image: "n8nio/n8n:latest" +# listen_port: 5678 +# uid: "1000" +# gid: "1000" + +n8n_readme: true +n8n_readme_mode: "0640" +n8n_readme_path: "/etc/ansible/readme/" diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..8600850 --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,11 @@ +galaxy_info: + author: Michael Hettwer + description: Ansible role to deploy and manage n8n with Docker Compose. + company: Linux-Server-Admin.com s.r.o. + license: Apache-2.0 + min_ansible_version: 2.1 + galaxy_tags: + - n8n + - automation + +dependencies: [] diff --git a/tasks/cleanup.yml b/tasks/cleanup.yml new file mode 100644 index 0000000..defae5a --- /dev/null +++ b/tasks/cleanup.yml @@ -0,0 +1,43 @@ +--- +- name: Check n8n directory + ansible.builtin.stat: + path: "{{ n8n_home }}" + register: n8n_home_stat + +- name: Stop n8n docker compose + ansible.builtin.command: docker compose down + args: + chdir: "{{ n8n_home }}" + when: + - n8n_site.deploy_type == "docker" + - n8n_home_stat.stat.exists + failed_when: false + +- name: Stop and disable n8n systemd unit + ansible.builtin.systemd: + name: "{{ n8n_unit_name }}.service" + state: stopped + enabled: false + when: n8n_systemd + failed_when: false + +- name: Remove n8n systemd unit + ansible.builtin.file: + path: "/etc/systemd/system/{{ n8n_unit_name }}.service" + state: absent + when: n8n_systemd + +- name: Reload systemd after cleanup + ansible.builtin.systemd: + daemon_reload: true + when: n8n_systemd + +- name: Remove n8n facts file + ansible.builtin.file: + path: "{{ n8n_fact_path }}" + state: absent + +- name: Remove n8n directory + ansible.builtin.file: + path: "{{ n8n_home }}" + state: absent diff --git a/tasks/config.yml b/tasks/config.yml new file mode 100644 index 0000000..6a8a4fc --- /dev/null +++ b/tasks/config.yml @@ -0,0 +1,106 @@ +--- +- name: Validate n8n site deploy_type + assert: + that: + - n8n_site.name is defined + - n8n_site.deploy_type is defined + - n8n_site.deploy_type in ["docker", "repo", "package"] + fail_msg: "n8n_sites entry must define deploy_type as 'docker', 'repo', or 'package'." + +- name: Set n8n site defaults + set_fact: + n8n_name: "{{ n8n_site.name }}" + n8n_home: "{{ n8n_site.path | default('/srv/' + n8n_site.name) }}" + n8n_user: "{{ n8n_site.user | default(n8n_default_user) }}" + n8n_group: "{{ n8n_site.group | default(n8n_default_group) }}" + n8n_systemd: "{{ n8n_site.systemd | default(true) }}" + n8n_state: "{{ n8n_site.state | default('present') }}" + n8n_app_options: "{{ n8n_site.app_options | default({}) }}" + n8n_docker_options: "{{ n8n_site.docker_options | default({}) }}" + n8n_unit_name: "n8n-{{ n8n_site.name | regex_replace('[^a-zA-Z0-9]+', '-') }}" + n8n_fact_path: "/etc/ansible/facts.d/n8n-{{ n8n_site.name | regex_replace('[^a-zA-Z0-9]+', '-') }}.fact" + no_log: true + +- name: Set n8n runtime options + set_fact: + n8n_host: "{{ n8n_app_options.host | default(n8n_default_host) }}" + n8n_protocol: "{{ n8n_app_options.protocol | default(n8n_default_protocol) }}" + n8n_timezone: "{{ n8n_app_options.timezone | default(n8n_default_timezone) }}" + n8n_listen_port: >- + {{ + (n8n_docker_options.listen_port | default(n8n_default_port)) + if n8n_site.deploy_type == "docker" + else (n8n_app_options.port | default(n8n_default_port)) + }} + n8n_webhook_url: >- + {{ + n8n_app_options.webhook_url + | default( + (n8n_app_options.protocol | default(n8n_default_protocol)) + ~ '://' + ~ (n8n_app_options.host | default(n8n_default_host)) + ~ ':' + ~ ( + (n8n_docker_options.listen_port | default(n8n_default_port)) + if n8n_site.deploy_type == "docker" + else (n8n_app_options.port | default(n8n_default_port)) + ) + ~ '/' + ) + }} + no_log: true + +- name: Set n8n DB options + set_fact: + n8n_db_host: "{{ (n8n_site.db | default({})).host | default(n8n_default_db.host) }}" + n8n_db_port: "{{ (n8n_site.db | default({})).port | default(n8n_default_db.port) }}" + n8n_db_name: "{{ (n8n_site.db | default({})).name | default(n8n_default_db.name) }}" + n8n_db_user: "{{ (n8n_site.db | default({})).user | default(n8n_default_db.user) }}" + n8n_db_password: "{{ (n8n_site.db | default({})).password | default(n8n_default_db.password) }}" + n8n_db_type: "{{ (n8n_site.db | default({})).type | default(n8n_default_db.type) }}" + no_log: true + +- name: Set n8n DB kind + set_fact: + n8n_db_kind: "{{ 'mysql' if n8n_db_type in ['mysql', 'mariadb'] else 'postgres' }}" + no_log: true + +- name: Set n8n deploy options + set_fact: + n8n_docker_image: "{{ n8n_docker_options.image | default(n8n_default_image) }}" + n8n_docker_uid: "{{ n8n_docker_options.uid | default(n8n_default_docker_uid) }}" + n8n_docker_gid: "{{ n8n_docker_options.gid | default(n8n_default_docker_gid) }}" + n8n_repo_path: "{{ n8n_app_options.repo_path | default(n8n_default_repo) }}" + n8n_repo_version: "{{ n8n_app_options.repo_version | default(n8n_default_repo_version) }}" + n8n_build_command: "{{ n8n_app_options.build_command | default(n8n_default_build_command) }}" + n8n_start_command: "{{ n8n_app_options.start_command | default(n8n_default_start_command) }}" + n8n_package_name: "{{ n8n_app_options.package_name | default(n8n_default_package_name) }}" + n8n_package_version: "{{ n8n_app_options.package_version | default(n8n_default_package_version) }}" + n8n_package_bin: "{{ n8n_app_options.package_bin | default(n8n_default_package_bin) }}" + no_log: true + +- name: Cleanup n8n site + include_tasks: cleanup.yml + when: n8n_state == "absent" + +- name: Install n8n with Docker + include_tasks: install-docker.yml + when: + - n8n_site.deploy_type == "docker" + - n8n_state != "absent" + +- name: Install n8n from repo + include_tasks: install-repo.yml + when: + - n8n_site.deploy_type == "repo" + - n8n_state != "absent" + +- name: Install n8n from package + include_tasks: install-package.yml + when: + - n8n_site.deploy_type == "package" + - n8n_state != "absent" + +- name: Write n8n facts + include_tasks: facts.yml + when: n8n_state != "absent" diff --git a/tasks/docker.yml b/tasks/docker.yml new file mode 100644 index 0000000..2af8b65 --- /dev/null +++ b/tasks/docker.yml @@ -0,0 +1,5 @@ +--- +# compatibility wrapper for docker install + +- name: Install n8n with Docker + include_tasks: install-docker.yml diff --git a/tasks/facts.yml b/tasks/facts.yml new file mode 100644 index 0000000..0981402 --- /dev/null +++ b/tasks/facts.yml @@ -0,0 +1,44 @@ +--- +- name: Ensure facts directory exists + ansible.builtin.file: + path: /etc/ansible/facts.d + state: directory + owner: root + group: root + mode: "0755" + +- name: Write n8n facts + ansible.builtin.copy: + dest: "{{ n8n_fact_path }}" + owner: root + group: root + mode: "0644" + content: | + {{ { + "name": n8n_name, + "deploy_type": n8n_site.deploy_type, + "path": n8n_home, + "user": n8n_user, + "group": n8n_group, + "systemd": n8n_systemd, + "host": n8n_host, + "protocol": n8n_protocol, + "listen_port": n8n_listen_port, + "webhook_url": n8n_webhook_url, + "image": ( + n8n_docker_image if n8n_site.deploy_type == "docker" else "" + ), + "repo": ( + n8n_repo_path if n8n_site.deploy_type == "repo" else "" + ), + "package": ( + n8n_package_name if n8n_site.deploy_type == "package" else "" + ), + "db": { + "host": n8n_db_host, + "port": n8n_db_port, + "name": n8n_db_name, + "user": n8n_db_user, + "type": n8n_db_kind + } + } | to_nice_json }} diff --git a/tasks/install-docker.yml b/tasks/install-docker.yml new file mode 100644 index 0000000..8a45689 --- /dev/null +++ b/tasks/install-docker.yml @@ -0,0 +1,54 @@ +--- +# docker tasks file for n8n + +- name: Ensure n8n directory exists + ansible.builtin.file: + path: "{{ n8n_home }}" + state: directory + +- name: Ensure n8n data directory exists + ansible.builtin.file: + path: "{{ n8n_home }}/data" + state: directory + owner: "{{ n8n_docker_uid }}" + group: "{{ n8n_docker_gid }}" + mode: "0750" + become: true + +- name: Generate n8n docker-compose template + ansible.builtin.template: + src: "{{ n8n_docker_options.compose_template | default('docker-compose.yml.j2') }}" + dest: "{{ n8n_home }}/docker-compose.yml" + +- name: Generate n8n env template + ansible.builtin.template: + src: "{{ n8n_docker_options.env_template | default('n8n-docker.env.j2') }}" + dest: "{{ n8n_home }}/.env" + +- name: Generate n8n systemd service + ansible.builtin.template: + src: "{{ n8n_docker_options.systemd_template | default('n8n-docker.service.j2') }}" + dest: "/etc/systemd/system/{{ n8n_unit_name }}.service" + become: true + when: n8n_systemd + +- name: Deploy n8n + community.docker.docker_compose_v2: + project_src: "{{ n8n_home }}" + files: + - docker-compose.yml + build: never + +- name: Reload systemd daemon + ansible.builtin.systemd: + daemon_reload: true + become: true + when: n8n_systemd + +- name: Enable and start {{ n8n_unit_name }} service + ansible.builtin.systemd: + name: "{{ n8n_unit_name }}" + enabled: true + state: started + become: true + when: n8n_systemd diff --git a/tasks/install-package.yml b/tasks/install-package.yml new file mode 100644 index 0000000..de097ce --- /dev/null +++ b/tasks/install-package.yml @@ -0,0 +1,61 @@ +--- +# package tasks file for n8n + +- name: Ensure n8n group exists + ansible.builtin.group: + name: "{{ n8n_group }}" + system: true + +- name: Ensure n8n user exists + ansible.builtin.user: + name: "{{ n8n_user }}" + group: "{{ n8n_group }}" + system: true + create_home: false + shell: /usr/sbin/nologin + +- name: Ensure n8n directory exists + ansible.builtin.file: + path: "{{ n8n_home }}" + state: directory + owner: "{{ n8n_user }}" + group: "{{ n8n_group }}" + mode: "0755" + +- name: Install n8n package + npm: + name: "{{ n8n_package_name }}" + version: "{{ n8n_package_version }}" + global: true + state: present + become: true + +- name: Create n8n env file + ansible.builtin.template: + src: "{{ n8n_app_options.env_template | default('n8n.env.j2') }}" + dest: "{{ n8n_home }}/.env" + owner: "{{ n8n_user }}" + group: "{{ n8n_group }}" + mode: "0640" + +- name: Write n8n package systemd unit + ansible.builtin.template: + src: "{{ n8n_app_options.systemd_template | default('n8n-package.service.j2') }}" + dest: "/etc/systemd/system/{{ n8n_unit_name }}.service" + mode: "0644" + become: true + when: n8n_systemd + +- name: Reload systemd for n8n package + ansible.builtin.systemd: + daemon_reload: true + become: true + when: n8n_systemd + +- name: Enable and start n8n package + ansible.builtin.systemd: + name: "{{ n8n_unit_name }}.service" + enabled: true + state: started + become: true + when: n8n_systemd diff --git a/tasks/install-repo.yml b/tasks/install-repo.yml new file mode 100644 index 0000000..3cf193a --- /dev/null +++ b/tasks/install-repo.yml @@ -0,0 +1,154 @@ +--- +# repo tasks file for n8n + +- name: Ensure n8n group exists + ansible.builtin.group: + name: "{{ n8n_group }}" + system: true + +- name: Ensure n8n user exists + ansible.builtin.user: + name: "{{ n8n_user }}" + group: "{{ n8n_group }}" + system: true + create_home: false + shell: /usr/sbin/nologin + +- name: Ensure n8n directory exists + ansible.builtin.file: + path: "{{ n8n_home }}" + state: directory + owner: "{{ n8n_user }}" + group: "{{ n8n_group }}" + mode: "0755" + +- name: Check n8n repo directory + ansible.builtin.stat: + path: "{{ n8n_home }}" + register: n8n_repo_home + +- name: Check n8n git metadata + ansible.builtin.stat: + path: "{{ n8n_home }}/.git" + register: n8n_repo_git + +- name: Check n8n directory contents + ansible.builtin.find: + paths: "{{ n8n_home }}" + hidden: true + recurse: false + register: n8n_repo_contents + when: n8n_repo_home.stat.exists + +- name: Remove n8n directory when not a git repo + ansible.builtin.file: + path: "{{ n8n_home }}" + state: absent + when: + - n8n_repo_git.stat.exists is not defined or not n8n_repo_git.stat.exists + - (n8n_app_options.clean_path | default(false)) + +- name: Abort when n8n directory is not a git repo + ansible.builtin.fail: + msg: "n8n path {{ n8n_home }} exists but is not a git repo. Set app_options.clean_path: true to wipe it." + when: + - n8n_repo_home.stat.exists + - n8n_repo_git.stat.exists is not defined or not n8n_repo_git.stat.exists + - (n8n_repo_contents.files | default([]) | length) > 0 + - not (n8n_app_options.clean_path | default(false)) + +- name: Ensure n8n repo ownership + ansible.builtin.file: + path: "{{ n8n_home }}" + state: directory + owner: "{{ n8n_user }}" + group: "{{ n8n_group }}" + recurse: true + when: n8n_repo_git.stat.exists + +- name: Mark n8n repo as safe for git + ansible.builtin.command: "git config --global --add safe.directory {{ n8n_home }}" + become_user: "{{ n8n_user }}" + when: n8n_repo_git.stat.exists + +- name: Ensure n8n repo origin exists + ansible.builtin.command: "git remote add origin {{ n8n_repo_path }}" + args: + chdir: "{{ n8n_home }}" + become_user: "{{ n8n_user }}" + changed_when: false + failed_when: false + when: n8n_repo_git.stat.exists + +- name: Ensure n8n repo origin matches + ansible.builtin.command: "git remote set-url origin {{ n8n_repo_path }}" + args: + chdir: "{{ n8n_home }}" + become_user: "{{ n8n_user }}" + when: n8n_repo_git.stat.exists + +- name: Install pnpm globally + npm: + name: pnpm + global: true + state: present + become: true + +- name: Clone n8n repo + ansible.builtin.git: + repo: "{{ n8n_repo_path }}" + dest: "{{ n8n_home }}" + version: "{{ n8n_repo_version }}" + update: true + force: true + become_user: "{{ n8n_user }}" + +- name: Ensure n8n repo ownership + ansible.builtin.file: + path: "{{ n8n_home }}" + state: directory + owner: "{{ n8n_user }}" + group: "{{ n8n_group }}" + recurse: true + +- name: Create n8n env file + ansible.builtin.template: + src: "{{ n8n_app_options.env_template | default('n8n.env.j2') }}" + dest: "{{ n8n_home }}/.env" + owner: "{{ n8n_user }}" + group: "{{ n8n_group }}" + mode: "0640" + +- name: Install n8n dependencies (pnpm install) + ansible.builtin.command: pnpm install --frozen-lockfile=false + args: + chdir: "{{ n8n_home }}" + become_user: "{{ n8n_user }}" + +- name: Build n8n + ansible.builtin.command: /bin/sh -lc "{{ n8n_build_command }}" + args: + chdir: "{{ n8n_home }}" + become_user: "{{ n8n_user }}" + +- name: Write n8n repo systemd unit + ansible.builtin.template: + src: "{{ n8n_app_options.systemd_template | default('n8n-repo.service.j2') }}" + dest: "/etc/systemd/system/{{ n8n_unit_name }}.service" + mode: "0644" + become: true + when: n8n_systemd + +- name: Reload systemd for n8n repo + ansible.builtin.systemd: + daemon_reload: true + become: true + when: n8n_systemd + +- name: Enable and start n8n repo + ansible.builtin.systemd: + name: "{{ n8n_unit_name }}.service" + enabled: true + state: started + become: true + when: n8n_systemd diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..8945a5b --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,12 @@ +--- +# tasks file for lsa.n8n + +- name: Configure n8n sites + include_tasks: config.yml + loop: "{{ n8n_sites | default([]) }}" + loop_control: + loop_var: n8n_site + +- name: Setup n8n readme + include_tasks: readme.yml + when: n8n_readme diff --git a/tasks/readme.yml b/tasks/readme.yml new file mode 100644 index 0000000..409b1ef --- /dev/null +++ b/tasks/readme.yml @@ -0,0 +1,16 @@ +--- +# Readme Tasks + +- name: "Create Readme Directory" + ansible.builtin.file: + path: "{{ n8n_readme_path }}" + state: directory + mode: "{{ n8n_readme_mode }}" + become: true + +- name: "Update Readme" + ansible.builtin.template: + src: "n8n.md.j2" + dest: "{{ n8n_readme_path }}n8n.md" + mode: "{{ n8n_readme_mode }}" + become: true diff --git a/templates/docker-compose.yml.j2 b/templates/docker-compose.yml.j2 new file mode 100644 index 0000000..40b0d6b --- /dev/null +++ b/templates/docker-compose.yml.j2 @@ -0,0 +1,13 @@ +version: "3.8" + +services: + n8n: + image: "{{ n8n_docker_image }}" + restart: unless-stopped + user: "{{ n8n_docker_uid }}:{{ n8n_docker_gid }}" + env_file: + - .env + ports: + - "{{ n8n_listen_port }}:5678" + volumes: + - "{{ n8n_home }}/data:/home/node/.n8n" diff --git a/templates/n8n-docker.env.j2 b/templates/n8n-docker.env.j2 new file mode 100644 index 0000000..3da9ace --- /dev/null +++ b/templates/n8n-docker.env.j2 @@ -0,0 +1,19 @@ +N8N_HOST={{ n8n_host }} +N8N_PORT=5678 +N8N_PROTOCOL={{ n8n_protocol }} +WEBHOOK_URL={{ n8n_webhook_url }} +GENERIC_TIMEZONE={{ n8n_timezone }} +DB_TYPE={{ n8n_db_kind }} +{% if n8n_db_kind == 'postgres' -%} +DB_POSTGRESDB_HOST={{ n8n_db_host }} +DB_POSTGRESDB_PORT={{ n8n_db_port }} +DB_POSTGRESDB_DATABASE={{ n8n_db_name }} +DB_POSTGRESDB_USER={{ n8n_db_user }} +DB_POSTGRESDB_PASSWORD={{ n8n_db_password }} +{% else -%} +DB_MYSQLDB_HOST={{ n8n_db_host }} +DB_MYSQLDB_PORT={{ n8n_db_port }} +DB_MYSQLDB_DATABASE={{ n8n_db_name }} +DB_MYSQLDB_USER={{ n8n_db_user }} +DB_MYSQLDB_PASSWORD={{ n8n_db_password }} +{% endif -%} diff --git a/templates/n8n-docker.service.j2 b/templates/n8n-docker.service.j2 new file mode 100644 index 0000000..0c78c62 --- /dev/null +++ b/templates/n8n-docker.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description={{ n8n_name }} Docker Service +After=network.target docker.service +Requires=docker.service + +[Service] +WorkingDirectory={{ n8n_home }} +ExecStart=/usr/bin/docker compose up -d +ExecStop=/usr/bin/docker compose down +Restart=always +TimeoutStartSec=0 +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/templates/n8n-package.service.j2 b/templates/n8n-package.service.j2 new file mode 100644 index 0000000..5276a10 --- /dev/null +++ b/templates/n8n-package.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description={{ n8n_name }} Package Service +After=network.target + +[Service] +Type=simple +User={{ n8n_user }} +Group={{ n8n_group }} +WorkingDirectory={{ n8n_home }} +EnvironmentFile={{ n8n_home }}/.env +ExecStart={{ n8n_package_bin }} +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/templates/n8n-repo.service.j2 b/templates/n8n-repo.service.j2 new file mode 100644 index 0000000..7054feb --- /dev/null +++ b/templates/n8n-repo.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description={{ n8n_name }} Repo Service +After=network.target + +[Service] +Type=simple +User={{ n8n_user }} +Group={{ n8n_group }} +WorkingDirectory={{ n8n_home }} +EnvironmentFile={{ n8n_home }}/.env +ExecStart=/bin/sh -lc "{{ n8n_start_command }}" +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/templates/n8n.env.j2 b/templates/n8n.env.j2 new file mode 100644 index 0000000..c65d52d --- /dev/null +++ b/templates/n8n.env.j2 @@ -0,0 +1,19 @@ +N8N_HOST={{ n8n_host }} +N8N_PORT={{ n8n_listen_port }} +N8N_PROTOCOL={{ n8n_protocol }} +WEBHOOK_URL={{ n8n_webhook_url }} +GENERIC_TIMEZONE={{ n8n_timezone }} +DB_TYPE={{ n8n_db_kind }} +{% if n8n_db_kind == 'postgres' -%} +DB_POSTGRESDB_HOST={{ n8n_db_host }} +DB_POSTGRESDB_PORT={{ n8n_db_port }} +DB_POSTGRESDB_DATABASE={{ n8n_db_name }} +DB_POSTGRESDB_USER={{ n8n_db_user }} +DB_POSTGRESDB_PASSWORD={{ n8n_db_password }} +{% else -%} +DB_MYSQLDB_HOST={{ n8n_db_host }} +DB_MYSQLDB_PORT={{ n8n_db_port }} +DB_MYSQLDB_DATABASE={{ n8n_db_name }} +DB_MYSQLDB_USER={{ n8n_db_user }} +DB_MYSQLDB_PASSWORD={{ n8n_db_password }} +{% endif -%} diff --git a/templates/n8n.md.j2 b/templates/n8n.md.j2 new file mode 100644 index 0000000..bac33fa --- /dev/null +++ b/templates/n8n.md.j2 @@ -0,0 +1,23 @@ +# n8n Setup + +## Configured n8n Sites + +{% if n8n_sites | length > 0 %} +{% for site in n8n_sites %} +- **Name:** {{ site.name }} + - **Deploy Type:** {{ site.deploy_type }} + - **Path:** {{ site.path | default('/srv/' + site.name) }} + - **Host:** {{ (site.app_options | default({})).host | default(n8n_default_host) }} + - **Port:** {{ + ((site.docker_options | default({})).listen_port + if site.deploy_type == 'docker' else (site.app_options | default({})).port) + | default(n8n_default_port) + }} + - **Protocol:** {{ (site.app_options | default({})).protocol | default(n8n_default_protocol) }} + - **Image:** {{ (site.docker_options | default({})).image | default(n8n_default_image) if site.deploy_type == 'docker' else '' }} + - **Repo:** {{ (site.app_options | default({})).repo_path | default(n8n_default_repo) if site.deploy_type == 'repo' else '' }} + - **Package:** {{ (site.app_options | default({})).package_name | default(n8n_default_package_name) if site.deploy_type == 'package' else '' }} +{% endfor %} +{% else %} +No n8n sites configured. +{% endif %}