Hello! Do you want to automate your repetitive tasks efficiently? If so, n8n could be the best tool for you. In this article, I’ll walk you through a detailed guide on how to quickly and easily build n8n, an open source automation tool, using Docker Compose. No complicated installation process, just a few lines of code to create your own automation server! 🚀 !
—.
📝 Table of Contents
- What is n8n? 🚀 2.
- Why use Docker Compose? 🐳 3.
- before you start (prerequisites) 🛠️
- n8n Docker Compose Setup: A Step-by-Step Guide 🪜
-
- create a project directory
-
- Create a
docker-compose.yml
file
- Create a
-
- Create an
.env
file (recommended)
- Create an
-
- Run n8n
-
- Connecting to n8n
-
- Stop n8n
-
- Dissect the
docker-compose.yml
file 🔬version
services
n8n
serviceimage
container_name
ports
volumes
environment
restart
- advanced settings and tips 💡
- Changing ports
- Managing Data Persistence
- Utilizing various environment variables
- Integrate PostgreSQL/MySQL databases
- Setting up HTTPS (Reverse Proxy)
- Production Environment Considerations ⚙️
- Security Hardening
- Monitoring and logging
- Backup strategy
- Importance of setting webhook URLs
- Performance optimization
- wrapping things up 🎉 .
—.
1. What is n8n? 🚀 🚀 .
n8n is an open source workflow automation tool with a “Fair Code” license. It is an alternative to commercial services like Zapier and Integromat (Make), with the big advantage that you can install it on your own server and have full control over your data.
Key Features:
- Visual workflow builder: Drag and drop to easily configure automation workflows.
- Variety of nodes: Provides 200+ built-in nodes to integrate with a wide range of services (Slack, Google Sheets, Notion, Stripe, etc.). General-purpose nodes like webhooks, HTTP requests, and more are also powerful.
- Create custom nodes: You can create your own nodes to extend functionality as needed.
- Data sovereignty:** All data is processed on your own servers, providing privacy and security.
- Flexibility: You can implement complex workflows, including conditional logic, loops, and parallelization.
Examples of N8N in action:
- Send notifications to Slack when a new Notion database entry is added 💬
- Save email attachments to Google Drive, and update Google Sheets with the file names 📧
- Call external APIs based on specific conditions, and send the results to other services 🌐.
- Automatically synchronize or backup your CRM data 💾.
—.
2. Why use Docker Compose? 🐳 * To automatically synchronize or backup your CRM data 💾 — — ### 3.
Docker Compose is a tool that allows you to define and run multiple Docker containers together. With a single docker-compose.yml
file, you can set up and manage all of your application’s services (e.g. web server, database, cache, etc.).
Synergies between n8n and Docker Compose:.
- Easy deployment: You can easily deploy n8n and its dependencies (if you add databases later) with a single command.
- Environmental isolation: N8N runs in an independent environment without conflicting with other software on your system.
- Reproducibility: You can deploy the same instance of n8n in any environment with just a
docker-compose.yml
file. - Configuration file management: Complex n8n environment variables can be neatly organized in a
docker-compose.yml
or.env
file.
—.
3. Before you begin (prerequisites) 🛠️
Before installing n8n with Docker Compose, you need to have the following things ready:
- Docker and Docker Compose installed: You must have Docker Desktop or Docker Engine and Docker Compose installed for your operating system (Windows, macOS, Linux). (Installing Docker Desktop will install Docker and Docker Compose together.)
- Basic terminal/CLI skills: You must be able to run basic commands from a command prompt (Windows) or terminal (macOS/Linux).
—.
4. n8n Setting Up Docker Compose: A Step-by-Step Guide 🪜
Now let’s follow along step-by-step to get n8n up and running with Docker Compose.
1. Create a project directory
First, create a new directory to store n8n related files.
mkdir n8n-project
cd n8n-project
2. Create a docker-compose.yml
file
Inside the n8n-project
directory, create a file named docker-compose.yml
and copy and paste the following contents
# docker-compose.yml
version: '3.8'
services:
n8n:
image: n8n/n8n:latest
container_name: n8n
ports:
- "5678:5678" # host port:container port. 5678 is the default port for n8n.
volumes:
# Specifies the path to permanently store n8n data.
# ~/.n8n means to use the .n8n folder in your home directory.
# (On Linux/macOS, %USERPROFILE%\.n8n or C:\Users\YourUser\.n8n on Windows)
- ~/.n8n:/home/node/.n8n
environment:
# email-related settings (optional).
# - N8N_EMAIL_MODE=smtp
# - N8N_SMTP_HOST=your.smtp.host
# n8n_smtp_port=587
# - N8N_SMTP_USER=your_smtp_user
# - N8N_SMTP_PASSWORD=your_smtp_password
# - N8N_SMTP_SSL=true
# Set up basic authentication for accessing the n8n UI (recommended)
# For security purposes, it is recommended to put the actual username and password in the .env file.
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER:-n8n_user} # use default if no .env file exists
- N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD:-n8n_password} # use default if no .env file exists
# n8n workflow webhook URL (required)
# Set the URL to use when calling the n8n webhook from the outside.
# You must specify a domain or IP and port that is externally reachable.
# This can be set to http://localhost:5678/ for local use only.
- webhook_url=${webhook_url:-http://localhost:5678/}
# n8n's encryption key (required, important!)
# Used to encrypt Credentials. This key should never be exposed and,
# and it is not recommended to change it after starting N8N.
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY:-your_super_secret_key_please_change_this_to_a_long_random_string}
# Synchronize container timezone with host (optional)
- TZ=Asia/Seoul # or set to your timezone, such as Europe/Berlin, America/New_York, etc.
# Set up your database (if you are using PostgreSQL or MySQL, this section will be detailed later)
# - DB_TYPE=postgres
# - DB_POSTGRES_HOST=db
# - DB_POSTGRES_DATABASE=n8n
# - DB_POSTGRES_USER=n8n
# - DB_POSTGRES_PASSWORD=n8n
restart: unless-stopped # Always restart the container unless it is stopped.
3. Create an .env
file (recommended) 🔒 .
For security reasons, it is recommended to keep sensitive information (passwords, API keys, etc.) separate in an .env
file rather than directly in the docker-compose.yml
file. Create a file named .env
inside the n8n-project
directory and write the following contents
# .env
# username and password to access the n8n web UI
N8N_BASIC_AUTH_USER=mysecureuser
N8N_BASIC_AUTH_PASSWORD=mysecurepassword123!
# n8n workflow webhook URL. Use a real, externally accessible domain or IP.
# Example: http://your.domain.com:5678/ or https://your.domain.com/
# If using HTTPS, the WEBHOOK_URL should start with https://.
WEBHOOK_URL=http://localhost:5678/
# Encryption key for n8n. Be sure to change it to a strong, long, random string!
# This key should never be exposed, and once set, do not change it.
N8N_ENCRYPTION_KEY=super_long_random_string_for_n8n_encryption_2023_abcd1234efgh5678ijkl9012mnop3456
> ⚠️ NOTE: N8N_ENCRYPTION_KEY
MUST be changed to a long, complex random string. This is very important for security reasons, as it is used to encrypt credentials (API keys, passwords, etc.) that are stored in n8n. Once set, it is not recommended to change it, as doing so may render previously stored credentials unusable.
For more information, see: #### 4. Run n8n
Once you have both the docker-compose.yml
and .env
files ready, run the following command in the n8n-project
directory to start the n8n container.
docker-compose up -d
```bash docker-compose up -d
* `up`: Create and start the services defined in the `docker-compose.yml` file.
* `-d`: (detached mode) Run the container in the background so that the terminal is still available.
If everything works, you should see a message similar to the following in the terminal:
[+] Running 1/1 ⠿ Container n8n Started
#### 5. Connect to n8n
Once the container has started successfully, open a web browser and connect to the following address
`http://localhost:5678`
Enter the username and password you set in the `.env` file in `N8N_BASIC_AUTH_USER` and `N8N_BASIC_AUTH_PASSWORD`, and you should see the n8n's workflow editor screen 🎉.
#### 6. Stopping n8n
If you want to stop the n8n container, run the following command in the `n8n-project` directory:
```bash
docker-compose down
This command stops and removes the container, but retains the data specified in volumes
. When you restart the container, the data and settings you worked with before will be preserved.
—]
5. Dissecting the docker-compose.yml
file 🔬
Let’s take a closer look at what each part of the docker-compose.yml
file we created means.
version: '3.8' # Docker Compose file format version
services: # Defines the services (containers) to run under this section.
n8n: # Name of the service. You can use this name to refer to the containers.
image: n8n/n8n:latest # The Docker image and tags to use. Here we use the latest official image of n8n.
container_name: n8n # Name to give to the container that will be created. This makes it easy to find with the `docker ps` command.
ports: # Define the port mapping between the host machine and the container.
- "5678:5678" # "host_port:container_port". Forwards requests coming in on port 5678 on the host to port 5678 on the n8n container.
volumes: # Set the volumes to permanently store the data inside the container on the host machine.
- ~/.n8n:/home/node/.n8n # "host_path:container_path". Mount the ~/.n8n directory on the host to the /home/node/.n8n directory on the container. n8n's settings, workflows, credentials, etc. will be stored here.
environment: # Define environment variables to pass inside the container.
# Environment variables are used to configure N8N's behavior.
- N8N_BASIC_AUTH_ACTIVE=true # Enable basic authentication for the n8n web UI.
- N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER:-n8n_user} # Authentication username. Get from the .env file or use the default.
- N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD:-n8n_password} # Authentication password. Import from the .env file or use the default.
- WEBHOOK_URL=${WEBHOOK_URL:-http://localhost:5678/} # URL to use when calling the n8n webhook from the outside. Must specify a valid external address.
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY:-your_super_secret_key_please_change_this_to_a_long_random_string} # Key used to encrypt n8n's credentials. This is very important and should be changed.
- TZ=Asia/Seoul # Sets the timezone of the container. This affects time-based tasks in the n8n workflow.
restart: unless-stopped # Container restart policy. Always attempt to restart the container unless it is explicitly stopped. This ensures that N8N starts automatically when the server reboots.
—.
6. Advanced Settings and Tips 💡
Change the port
If the default port 5678 conflicts with another service, or you want to use a different port, you can change the ports
section.
For example, if you want to use port 8000 on your host:
ports:
- "8000:5678" # Now connect to http://localhost:8000으로.
Managing Data Persistence
In the example above, we used the path ~/.n8n
, but you can change this if you want to store data in a specific path or if you want to use Docker’s Named Volumes.
Use a specific host path: **Use a specific host path
volumes:
- /opt/n8n_data:/home/node/.n8n # Linux/macOS specific. For Windows, change to C:\n8n_data:/home/node/.n8n, etc.
Using Docker Named Volumes: Docker Named Volumes are used by Docker to store data in a named volume. Named Volumes are volumes managed by Docker that are easy to backup and manage.
# docker-compose.yml
version: '3.8'
services:
n8n:
# ... (omitted) ...
volumes:
- n8n_data:/home/node/.n8n # 'n8n_data' is the name of the volume we define here.
# ... (omitted) ...
volumes: # Define the volumes named in this section.
n8n_data:
Utilizing different environment variables
N8N provides detailed settings through a variety of environment variables. Some useful variables include
N8N_EDITOR_BASE_URL
: The actual URL where the n8n UI runs (useful when using a proxy). This may be different fromWEBHOOK_URL
.N8N_USER_MANAGEMENT_ACTIVE=true
: Enable multi-user management feature. After activation, user registration is possible in the n8n UI.N8N_LOG_LEVEL=debug
: Sets the log level (info
,warn
,error
,debug
,verbose
). Useful for troubleshooting.N8N_DISABLE_REGISTRATION=true
: Disable new user registration in the n8n UI.GENERIC_TIMEZONE=Asia/Seoul
: Sets the default time zone when using time-related nodes inside workflows.
These environment variables can be added to the environment
section of docker-compose.yml
or to an .env
file as needed.
PostgreSQL/MySQL Database Integration
By default, n8n uses SQLite to store data, but in production it is much more reliable and scalable to use an external database like PostgreSQL or MySQL. This is an example of running n8n and a database together using Docker Compose.
# docker-compose.db.yml (example)
version: '3.8'
services:
n8n:
image: n8n/n8n:latest
container_name: n8n
ports:
- "5678:5678"
volumes:
- n8n_data:/home/node/.n8n # Use Named Volume
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- n8n_basic_auth_user=${n8n_basic_auth_user}
- n8n_basic_auth_password=${n8n_basic_auth_password}
- webhook_url=${webhook_url}
- n8n_encryption_key=${n8n_encryption_key}
- TZ=Asia/Seoul
# Add database settings
- DB_TYPE=postgres # or mysql
- DB_POSTGRES_HOST=db # Name of the database service
- db_postgres_database=${postgres_db}
- db_postgres_user=${postgres_user}
- db_postgres_password=${postgres_password}
depends_on: # set dependency so that the n8n service starts before the db service
- db
restart: unless-stopped
db: # define the PostgreSQL database service
image: postgres:13-alpine # PostgreSQL image to use
container_name: n8n_postgres_db
environment:
- POSTGRES_DB=${POSTGRES_DB}
- postgres_user=${postgres_user}
- postgres_password=${postgres_password}
volumes:
- /var/lib/postgresql/data postgres_data:/var/lib/postgresql/data # Database data persistence
restart: unless-stopped
volumes:
n8n_data: # n8n application data
postgres_data: # PostgreSQL database data
And add database-related variables to the .env
file:
# .env (add database)
# ... existing n8n variables ...
POSTGRES_DB=n8n_database
POSTGRES_USER=n8n_user
POSTGRES_PASSWORD=very_secure_db_password
Running docker-compose up -d
with these settings will start n8n and the PostgreSQL database together, and n8n will use PostgreSQL to store data.
HTTPS (Reverse Proxy) Settings
Enforcing HTTPS is essential if you want to use n8n in a production environment. It provides added security when calling webhooks or accessing the UI. You can either have a reverse proxy (e.g. Nginx, Caddy) as a separate service within Docker Compose, or you can use Nginx/Apache already installed on your server.
Concept:
User/External Webhook (HTTPS 443) -> Reverse Proxy (Nginx/Caddy) -> n8n Container (HTTP 5678)
.
Example (using Nginx Proxy Manager): Nginx Proxy Manager (Nginx) Nginx Proxy Manager (NPM) is a tool that provides a web-based UI to make reverse proxy setup easy.
# docker-compose.npm.yml (example of NPM integration with n8n)
version: '3.8'
services:
n8n:
image: n8n/n8n:latest
container_name: n8n
# NPM will connect directly to port 5678 on n8n, so no need to expose the port to the host
# ports:
# - "5678:5678"
volumes:
- # n8n_data:/home/node/.n8n
environment:
# ... (omitted) ...
# WEBHOOK_URL should now be changed to an external domain.
- WEBHOOK_URL=https://your.n8n.domain.com/ # Change to real domain!
- N8N_EDITOR_BASE_URL=https://your.n8n.domain.com/ # n8n UI also uses same domain
restart: unless-stopped
networks: # Define networks to allow NPM and n8n to communicate.
- web_proxy_network
# Nginx Proxy Manager (installed separately, or add it to this file to run alongside)
# This example assumes that NPM is already running by another docker-compose.
# If you want to run them together, you'll need to add the contents of NPM's docker-compose.yml here.
networks:
# the network to be shared by NPM and n8n. web_proxy_network: # the network to be shared by NPM and n8n.
external: true # If the network used by NPM is defined externally, use external: true
# or internal: true if you define it inside this file
In NPM, you can create a proxy host with your.n8n.domain.com
, set the Forward Hostname/IP to n8n
(the name of your container), and the Forward Port to 5678
. You can also easily get a free SSL certificate using Let’s Encrypt.
—.
7. Production Environment Considerations ⚙️
When utilizing n8n in production, the following considerations must be taken into account.
Hardening security
- Use
.env
files: Manage all sensitive information (passwords, API keys, etc.) through.env
files and add them to.gitignore
to prevent them from being included in version control systems like Git. N8N_ENCRYPTION_KEY
Setting: Set a strong and unique encryption key and make sure it is never exposed. This key is used to encrypt all credentials stored in N8N.-
N8N_BASIC_AUTH
or user management: Enable basic authentication and use a strong password to access the n8n UI. If you need multi-user functionality, setN8N_USER_MANAGEMENT_ACTIVE=true
to manage permissions per user. - HTTPS Required: All external communication (webhooks, UI access) should be HTTPS to prevent data eavesdropping and tampering.
- Container minimum privileges: It is recommended to grant only the minimum necessary privileges when running Docker containers.
Monitoring and logging
- Docker Logs: You can check the real-time logs of your n8n container with the command
docker-compose logs -f n8n
. - n8n self-logging: Use the
N8N_LOG_LEVEL
environment variable to control log verbosity, and consider integrating with external logging services (e.g. ELK Stack, Grafana Loki) as needed. - Resource monitoring: You should use tools like Docker stats or Prometheus/Grafana to monitor the CPU and memory usage of your n8n containers.
Backup strategy
- Backup volumes: All data (settings, workflows, credentials) in n8n is stored in the path specified in
volumes
. You should backup the data in this path regularly. If you are using PostgreSQL/MySQL, we recommend backing up a dump of your database. - Recovery Plan: You should have a plan in place to quickly recover your N8N instance using the backed up data.
Importance of setting the webhook URL
The WEBHOOK_URL
environment variable defines the base URL that n8n uses when receiving external webhook requests. It must be set to an externally accessible domain or IP and a valid URL that includes HTTPS. If set incorrectly, webhooks in your workflow will not work properly, or other services will not be able to send data to n8n.
Optimize performance
- Database separation: SQLite is useful at small scales, but for larger workflows or when many executions are expected, using an external database such as PostgreSQL or MySQL is much better for performance.
- Hardware resources: Make sure your server has enough CPU, memory, and set resource limits on your Docker containers as needed to ensure reliability.
- Redis caching: n8n can use Redis for caching to improve performance. Redis services can also be added to Docker Compose to work with it (e.g., by setting
N8N_REDIS_HOST
,N8N_REDIS_PORT
, etc.)
—]
8. To wrap up 🎉
We hope this guide has given you a complete understanding of how to install and set up n8n with Docker Compose. You are now able to run n8n, a powerful automation tool, securely and flexibly in your own environment.
n8n offers endless automation possibilities. Beyond the basic setup described in this article, explore the many advanced features and integrations to take your work to the next level of efficiency. If you have any questions, feel free to ask in the comments! Happy automation life! ✨