Skip to main content
Create your own
Lesson illustration

Connecting n8n to an External Database

Hello and welcome back!

In the last lesson, we solidified our self-hosted n8n setup by configuring Docker volumes for persistent storage. You learned that this is critical for safeguarding your workflows, credentials, and the all-important encryption key. Our docker-compose.yml file now includes both an n8n service and a postgres service, with volumes ensuring their data survives container restarts.

Today, we'll focus on the connection between these two services. The learning outcome for this lesson is to connect a self-hosted n8n instance to an external database. While our current setup uses a PostgreSQL container that is "external" to the n8n container itself, we'll first dissect the exact mechanism that makes this connection possible. Then, we'll generalize this knowledge so you can confidently connect n8n to any external database, like a managed service from a cloud provider—a common practice in production environments.

1. From SQLite to PostgreSQL: The Configuration Switch

By default, a new self-hosted n8n instance uses an embedded SQLite database. This is simple and works out of the box, but for more robust, scalable deployments, PostgreSQL is the recommended choice. To make this switch, we need to provide n8n with a set of instructions—a database connection string—using environment variables.

As a software developer, you're likely familiar with configuring applications through environment variables, and n8n follows this standard practice.

The official n8n documentation lists all the variables available for this purpose. Let's take a look.

Supported databases and settings

The official n8n documentation, under 'Supported databases and settings', provides the definitive list of environment variables for configuring a PostgreSQL connection. This is our source of truth.

Please read the introduction and the section titled 'PostgresDB'. Familiarize yourself with the key variables like DB_TYPE, DB_POSTGRESDB_HOST, DB_POSTGRESDB_USER, DB_POSTGRESDB_PASSWORD, and DB_POSTGRESDB_DATABASE.

The most important variable is DB_TYPE=postgresdb. This tells n8n to ignore SQLite and look for a PostgreSQL database using the other DB_POSTGRESDB_* variables you provide.

2. Dissecting Our Docker Compose Connection

Our current docker-compose.yml stack is a perfect case study for how this works. Let's review the setup you've already built, which is well-represented in the Self-Host n8n with Docker on a VPS guide.

Self-Host n8n with Docker on a VPS

This guide provides an excellent practical example of a .env file and a docker-compose.yml file working together to connect n8n to a Postgres container.

Review the contents of the .env file (Step 5.1) and the docker-compose.yml file (Step 7). Pay close attention to how variables like ${DB_POSTGRESDB_DATABASE} are used in both the postgres and n8n service definitions.

Let's break down the key interactions you just reviewed:

  1. The .env file: This file stores the actual connection details (host, user, password, database name). This is a best practice that keeps secrets out of your version-controlled docker-compose.yml file.

  2. The postgres service: It uses these variables (POSTGRES_USER: ${DB_POSTGRESDB_USER}, etc.) to initialize the database and create the specified user with the correct password on its first run.

  3. The n8n service: It loads the entire .env file (env_file: - .env) and uses the DB_* variables to form its connection string.

The magic that ties it all together is Docker's networking. When you set DB_POSTGRESDB_HOST=postgres in your .env file, you're telling the n8n container to connect to a host named postgres. Within the private network created by Docker Compose, each service is automatically accessible to others using its service name as a hostname.

The following diagram illustrates this architecture, showing n8n connecting to an external PostgreSQL instance, both running as Docker containers.

n8n Docker Container Architecture with External Services
This architectural diagram shows an n8n Docker container configured with environment variables and using volumes for persistence, while connecting to a separate PostgreSQL container that acts as its database.

To see this principle in action, let's watch a short video clip. The presenter is setting up chat memory for an AI agent within n8n, which requires a database connection. Notice what they enter for the Host.

Build 100% Self-Hosted AI Agents in 2026 (Surprisingly Easy)

In this clip from Yashica Jain's 'Build 100% Self-Hosted AI Agents' video, watch how the n8n application is configured to connect to the PostgreSQL database running in the same Docker Compose stack.

Watch from 00:28:54 to 00:30:08. The key moment is when 'postgres' is entered as the Host for the credentials. This visually confirms that the Docker service name is used as the hostname for inter-container communication.

This demonstrates perfectly how the service name postgres becomes the resolvable network address for the database from within the n8n container.

3. Connecting to a Truly External Database

Running PostgreSQL in a container is great for development, but for a production setup, you'll often use a managed database service like Amazon RDS, Google Cloud SQL, or DigitalOcean Managed Databases. These services handle backups, scaling, and maintenance for you.

So, how do you connect your self-hosted n8n to one of these? The process is surprisingly straightforward and involves two main steps:

Step 1: Update your .env file

You simply replace the local Docker-centric values with the connection details provided by your cloud provider.

  • DB_POSTGRESDB_HOST: Change from postgres to the long endpoint URL provided by your managed database service (e.g., db-n8n-prod-do-user-12345-0.b.db.ondigitalocean.com).
  • DB_POSTGRESDB_USER, DB_POSTGRESDB_PASSWORD, DB_POSTGRESDB_DATABASE: Update these with the credentials for your managed database.
  • DB_POSTGRESDB_PORT: Use the port specified by your provider.
  • SSL/TLS: Most managed databases require an SSL connection. You may need to add DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZED=false or configure other DB_POSTGRESDB_SSL_* variables depending on your provider's requirements.

Step 2: Simplify your docker-compose.yml file

Since the database is no longer running in your Docker stack, you can remove its definition entirely.

  • Delete the entire postgres service block.
  • Remove the depends_on: - postgres line from the n8n service definition.
  • Delete the n8n_db_data volume from the top-level volumes declaration.

Your n8n service is now completely decoupled from a local database container and points to your robust, managed database in the cloud.

Test your understanding!

You've just provisioned a new managed PostgreSQL database on Amazon RDS. You are given the following:

  • Endpoint URL: n8n-instance-1.caxxxxxxxxx.us-east-1.rds.amazonaws.com
  • Port: 5432
  • DB Name: n8n_prod_db
  • Master username: n8n_admin
  • Master password: aVerySecurePassword123!

What changes would you make to your .env and docker-compose.yml files to connect your existing n8n Docker container to this new database?

Show answer
  1. In your .env file:

    • Set DB_POSTGRESDB_HOST=n8n-instance-1.caxxxxxxxxx.us-east-1.rds.amazonaws.com
    • Set DB_POSTGRESDB_PORT=5432
    • Set DB_POSTGRESDB_DATABASE=n8n_prod_db
    • Set DB_POSTGRESDB_USER=n8n_admin
    • Set DB_POSTGRESDB_PASSWORD=aVerySecurePassword123!
  2. In your docker-compose.yml file:

    • Remove the entire postgres: service definition.
    • In the n8n: service, remove the depends_on: - postgres line.
    • At the bottom, under volumes:, remove the n8n_db_data: volume definition.

After saving the files, you would run docker compose up -d to restart n8n with the new configuration.

Finally, when setting up an external database from scratch, you must ensure the database user n8n will connect with has the correct permissions. The n8n documentation provides the recommended SQL commands to create the user and grant it the necessary privileges.

Supported databases and settings

This section of the n8n docs shows the SQL commands needed to prepare a database for n8n.

Review the commands under the 'Required permissions' heading. You would typically run these commands against your new database using a tool like psql before starting n8n.

Conclusion

You have now mastered the configuration required to connect n8n to a PostgreSQL database, whether it's running in a local Docker container or as a managed service in the cloud. This flexibility is key to deploying n8n in a variety of environments, from development to full-scale production.

Key Takeaways:

  • n8n is configured to use PostgreSQL by setting DB_TYPE=postgresdb and providing connection details via DB_POSTGRESDB_* environment variables.
  • Within a Docker Compose network, a service's name (e.g., postgres) acts as its hostname for inter-container communication.
  • Connecting to a truly external database involves updating the DB_* variables in your .env file with the provider's details and removing the local database service from your docker-compose.yml.
  • Using a managed external database is a professional best practice for production deployments, as it offloads management tasks like backups, scaling, and security.

Preview of the Next Lesson:

Our self-hosted n8n instance is now architecturally sound. It has persistent storage and a robust database connection. The next logical step is to control who can access it. In the upcoming lesson, we will enable user management and configure basic access permissions, transforming your single-user instance into a platform ready for team collaboration.

Can't find a good explanation? Sign up and we'll make it for you

Sign up