diff --git a/README.md b/README.md index c672021..7b40376 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,45 @@ If you would like your node to be available on n8n cloud you can also [submit yo You need the following installed on your development machine: -* [git](https://git-scm.com/downloads) -* Node.js and npm. Minimum version Node 20. You can find instructions on how to install both using nvm (Node Version Manager) for Linux, Mac, and WSL [here](https://github.com/nvm-sh/nvm). For Windows users, refer to Microsoft's guide to [Install NodeJS on Windows](https://docs.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-windows). -* Install n8n with: +* Docker and Docker Compose +* NodeJS and npm + +Once you have cloned the repository: + +* Execute: ``` - npm install n8n -g + npm i ``` -* Recommended: follow n8n's guide to [set up your development environment](https://docs.n8n.io/integrations/creating-nodes/build/node-development-environment/). + +To run the local n8n instance: + +* Execute: + ``` + docker compose up -d + ``` + Now, n8n will run on http://localhost:5678. + +When changes are made to the custom node code and you want to test it on the local instance: + +* There is a script file called deploy-node.sh. Once executed, it will build the custom node code and deploy the Docker container. This file requires a few changes depending on the name that Docker gives to the container and the volumes: + + * On line 24 of the script, you will see this line: + ``` + TARGET_DIR="/var/lib/docker/volumes/n8n-self-hosted_n8n_data/_data/custom/$PACKAGE_NAME" + ``` + + * Depending on the container volume name, "n8n-self-hosted_n8n_data" needs to be changed. To check the volume's name, execute: + + ``` + docker volume ls + ``` + + * On lines 56 and 59, "n8n-self-hosted-n8n-1" must be changed to match the name of the container for the n8n instance. + + * Once these changes are made, execute the script: + ``` + ./deploy-node.sh + ``` ## Using this starter diff --git a/deploy-node.sh b/deploy-node.sh new file mode 100755 index 0000000..0b1b0d0 --- /dev/null +++ b/deploy-node.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# This script builds your custom node, deploys it to your n8n custom nodes folder, +# kills any running n8n process, and then restarts n8n. +# +# It dynamically determines the target directory based on the "name" field in package.json. +# +# Usage: ./deploy-node.sh + +# Exit immediately if a command fails. +set -e + +############################## +# Step 0: Get Package Name +############################## +# Use Node.js to extract the package name from package.json. +PACKAGE_NAME=$(node -p "require('./package.json').name") + +if [ -z "$PACKAGE_NAME" ]; then + echo "Error: Could not determine package name from package.json." + exit 1 +fi + +# Set the target directory based on the package name. +TARGET_DIR="/var/lib/docker/volumes/n8n-self-hosted_n8n_data/_data/custom/$PACKAGE_NAME" + +echo "Detected package name: '$PACKAGE_NAME'" +echo "Target deployment directory: '$TARGET_DIR'" + +############################## +# Step 1: Build the Node +############################## +echo "Building the node..." +pnpm run build + +############################## +# Step 2: Deploy the Build Output +############################## +# Define the source (build output) directory. +SOURCE_DIR="./dist" + +echo "Deploying build output from '$SOURCE_DIR' to '$TARGET_DIR'..." + +# Remove any previous deployment and recreate the target directory. +sudo rm -rf "$TARGET_DIR" +sudo mkdir -p "$TARGET_DIR" + +# Copy all files from the build output to the target directory. +sudo cp -r "$SOURCE_DIR/"* "$TARGET_DIR/" + +echo "Deployment complete." + +############################## +# Step 3: Restart n8n +############################## +echo "Restarting n8n..." +docker container restart n8n-self-hosted-n8n-1 + +# Logging for debugging +docker logs -f n8n-self-hosted-n8n-1 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9829983 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,56 @@ +services: + traefik: + image: "traefik" + restart: always + command: + - "--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.websecure.address=:443" + - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true" + - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}" + - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json" + ports: + - "80:80" + - "443:443" + volumes: + - traefik_data:/letsencrypt + - /var/run/docker.sock:/var/run/docker.sock:ro + + n8n: + image: docker.n8n.io/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: + - n8n_data:/home/node/.n8n + - ./local-files:/files + +volumes: + n8n_data: + traefik_data: \ No newline at end of file