Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
FREEDOM251

Freedom251 › Blog › Docker Compose

How to Self-Host Evolution API on a VPS with Docker, PostgreSQL, and Redis

By Freedom251 Team · · 12 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To self-host Evolution API, provision a Linux VPS, install Docker Engine with the Compose plugin, prepare PostgreSQL and Redis, create a .env file, and start the official Compose deployment with docker compose up -d. The standalone example exposes the API on port 8080 and stores instance data in a Docker volume. For a public installation, put HTTPS in front of that port with a reverse proxy such as Traefik. Pin a verified image tag instead of assuming latest, and check the current official repository for exact variable names before every upgrade.

What you are building

Evolution API is a self-hosted HTTP API service. Your VPS runs the API container, a PostgreSQL database stores application data, and Redis supplies caching or other fast temporary data when enabled. Clients send requests to your domain or VPS address and authenticate with the API key configured in the container.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A small, single-server deployment is the simplest starting point:

  • Docker Compose: starts and connects the containers on one host.
  • PostgreSQL: the documented database choice in the official material and the architecture described by DeepWiki.
  • Redis: optional in the architecture, but recommended by the same overview and used by common v2 configurations.
  • Persistent storage: a PostgreSQL volume and the Evolution instances volume.
  • HTTP entry point: port 8080 for a direct test, or a reverse proxy on ports 80 and 443 for production.

The official standalone example is deliberately minimal. It assumes Docker is already installed, reads settings from .env, maps port 8080, mounts a volume for instances, and is started with docker compose up -d. The official repository also contains a Compose file on its main branch; treat that file and its current .env.example as the authority when they differ from community examples.

#1 Best Overall
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (8GB RAM)
  • Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM)
  • Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
  • CanaKit Turbine Black Case for the Raspberry Pi 5
  • CanaKit Low Noise Bearing System Fan
  • Mega Heat Sink - Black Anodized

Choose the deployment shape before installing

Standalone Compose on one VPS

This is the practical choice for a first installation or a modest workload. You manage one machine, one Compose project, and one firewall. It is easy to inspect with docker compose ps and docker compose logs, but high availability and automatic failover are not included.

Docker Swarm with Traefik

The official documentation describes a Swarm deployment that uses Traefik for routing and HTTPS. Swarm is more involved than standalone Compose, but it provides a documented way to attach a public domain, terminate TLS, and route traffic without exposing the application port directly. Use it when you already operate Swarm or need the routing model; do not adopt it solely to run a single test instance.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Decision Standalone Compose Swarm with Traefik
Setup effort Lowest; one VPS and one Compose project Higher; Swarm initialization, overlay networking, and Traefik configuration
Public HTTPS Requires a separate reverse-proxy configuration HTTPS routing is the documented pattern
Scaling Manual container and host scaling Service-oriented deployment and scheduling
Best fit Development, pilots, and single-host production Teams already running Swarm or needing centralized routing

VPS requirements and sizing reality

No official CPU, memory, or storage requirement was published in the material available for this guide. Hosting-provider pages advertise plans such as 1 vCPU, 4 GB RAM, and 50 GB NVMe, but those are marketing listings rather than Evolution API requirements. Treat that specification only as a test starting point, not a capacity guarantee.

Choose capacity from your workload: number of simultaneous instances, message volume, media retention, PostgreSQL growth, and whether Redis is handling queues as well as cache. Monitor memory and disk after launch. A VPS that is comfortable for a few low-volume instances can become constrained by media files or database growth long before the API process itself is CPU-bound.

  • A 64-bit Linux distribution supported by your Docker installation method.
  • Administrative access through SSH and permission to configure the firewall.
  • A DNS name pointing to the VPS if you will use HTTPS.
  • Enough disk space for PostgreSQL, logs, Docker images, and Evolution instance data, plus room for backups.

1. Prepare the Linux VPS and Docker

Use your distribution’s current Docker Engine installation instructions and install the Compose plugin. The official Evolution standalone guide assumes Docker is already present; it does not replace Docker’s installation documentation.

  1. Connect over SSH and update the operating system using its normal package-management procedure.
  2. Install Docker Engine and the Docker Compose plugin from Docker’s official instructions for your distribution.
  3. Verify both components:
docker --version
docker compose version

The second command must work without the legacy hyphenated docker-compose binary. If Docker requires elevated privileges on your system, either run Compose with sudo consistently or add your administrative user to the Docker group and start a new login session. The Docker daemon effectively grants root-level control, so restrict SSH access and do not expose its socket to the network.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a dedicated project directory, for example:

sudo mkdir -p /opt/evolution-api
sudo chown "$USER":"$USER" /opt/evolution-api
cd /opt/evolution-api

2. Decide where PostgreSQL and Redis will run

The official instructions say to configure PostgreSQL and Redis before installing Evolution API. They may run as containers on the same VPS, on separate hosts, or as managed services. The connection strings must use addresses reachable from the Evolution container, not localhost: inside a container, localhost means that same container.

Rank #2
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (4GB RAM)
  • Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (4GB RAM)
  • Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
  • CanaKit Turbine Black Case for the Raspberry Pi 5
  • CanaKit Low Noise Bearing System Fan
  • CanaKit Mega Heat Sink - Black Anodized

Same-host containers

Running all three services in one Compose project keeps networking simple. The service names postgres and redis become DNS names on the Compose network. Persist PostgreSQL data; Redis persistence depends on how you use it and whether losing cached data is acceptable.

External database services

If PostgreSQL or Redis is managed elsewhere, create firewall rules that allow connections only from the VPS, obtain the provider’s TLS and authentication requirements, and replace the internal service names in the connection URIs. Do not publish database ports broadly to the internet just to make the container connect.

3. Create the environment file

Community v2-style configurations commonly use DATABASE_CONNECTION_URI, CACHE_REDIS_URI, and AUTHENTICATION_API_KEY. Variable names have changed between releases and community examples, so compare every name with the current official .env.example and the Compose file for the tag you intend to run.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create /opt/evolution-api/.env with restrictive permissions:

umask 077
nano .env

A same-host example is:

POSTGRES_DB=evolution
POSTGRES_USER=evolution
POSTGRES_PASSWORD=Use-a-long-random-password-here

DATABASE_CONNECTION_URI=postgresql://evolution:Use-a-long-random-password-here@postgres:5432/evolution
CACHE_REDIS_URI=redis://redis:6379
AUTHENTICATION_API_KEY=6f4b8c1d9e2a7f3c5b6d8e1a4c9f2b7d

The password and API key above are example values. Generate unique secrets for your installation, never reuse them elsewhere, and do not commit .env to source control. A convenient key-generation command is:

openssl rand -hex 32

Copy its output into AUTHENTICATION_API_KEY. If your PostgreSQL password contains characters such as @, :, /, or #, URL-encode them before placing the password in DATABASE_CONNECTION_URI; otherwise the URI parser can read the wrong username, password, or host.

4. Write a Compose file

The official standalone example supplies the Evolution service, port mapping, environment file, and instances volume. The following single-host pattern adds PostgreSQL and Redis so that all dependencies share one private Compose network. Verify the image reference, variable names, and mount paths against the current official repository before using it in production; the documented example pins version v2.1.1, while community guides use other tags.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
CanaKit Raspberry Pi 5 Essentials Starter Kit (4GB RAM)
  • CanaKit Raspberry Pi 5 Essentials Starter Kit
services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redis_data:/data

  evolution-api:
    image: atendai/evolution-api:v2.1.1
    restart: unless-stopped
    env_file:
      - .env
    ports:
      - "8080:8080"
    volumes:
      - evolution_instances:/evolution/instances
    depends_on:
      - postgres
      - redis

volumes:
  postgres_data:
  redis_data:
  evolution_instances:

postgres:16-alpine and redis:7-alpine are example image choices, not official Evolution API hardware or version requirements. Keep the PostgreSQL major version stable during normal operation. For Redis, match the major version expected by any existing data volume; changing it casually can make the old on-disk format unreadable.

If you use external services, remove the corresponding Compose service and volume, then change the hostnames in the URI to the real endpoints. If the official Compose file contains additional required variables for your release, add them rather than relying on defaults.

5. Start the stack and inspect its state

  1. From the project directory, validate the rendered Compose configuration:
docker compose config

This catches malformed YAML and missing variable interpolation before containers start. Do not paste the rendered output into a public issue if it contains secrets.

  1. Pull the selected images and start in detached mode:
docker compose pull
docker compose up -d
  1. Check container state and logs:
docker compose ps
docker compose logs -f evolution-api

On first boot, PostgreSQL migrations can take a little time. One community guide advises waiting about 30 seconds before opening the manager; treat that as an operational observation, not a guaranteed boot time. Follow the logs and test only after the API reports that it has finished starting.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Because depends_on controls start order rather than database readiness, a container can begin before PostgreSQL accepts connections. A restart after the database is ready is safe:

docker compose restart evolution-api

Do not run docker compose down -v casually. The -v option removes named volumes and can destroy PostgreSQL data and instances.

6. Test the API without exposing it permanently

For an initial test, keep port 8080 restricted by the VPS firewall or bind it only to the loopback interface if a reverse proxy runs on the same host. From the VPS itself, test the service with the API key:

Rank #4
CanaKit Raspberry Pi 5 16GB Starter Kit PRO - Turbine Black (128GB Edition) (16GB RAM)
  • Includes Raspberry Pi 5 16GB with 2.4Ghz 64-bit quad-core CPU (16GB RAM)
  • Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
  • CanaKit Turbine Black Case for the Raspberry Pi 5
  • CanaKit Low Noise Bearing System Fan
  • Mega Heat Sink - Black Anodized
curl -i 
  -H "apikey: 6f4b8c1d9e2a7f3c5b6d8e1a4c9f2b7d" 
  http://127.0.0.1:8080/

The exact endpoint and response depend on the Evolution API version. A connection refusal means the process is not listening or the port mapping is wrong; an authentication response means the service is reachable and the key was processed. Use the endpoint list shipped with your version rather than assuming an older route still exists.

For remote troubleshooting without opening 8080 to the internet, use an SSH tunnel from your workstation:

ssh -L 8080:127.0.0.1:8080 user@your-vps

Then browse or call http://127.0.0.1:8080 locally. This keeps the API off the public interface while you validate the deployment.

7. Put HTTPS and access controls in front

Firewall

Allow SSH only from addresses you administer, allow TCP 80 and 443 for the reverse proxy, and block public access to PostgreSQL, Redis, and (after proxying) port 8080. The exact firewall commands differ by distribution, so apply the rules using the firewall tool supported by your VPS image. Confirm an existing SSH session remains open before tightening the rules.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Reverse proxy and certificate

For a public domain, terminate TLS at a reverse proxy and forward requests to the private Evolution service. The official HTTPS documentation uses Traefik with Docker Swarm. Follow that documented Swarm configuration when you choose that architecture, including its labels, network, certificate resolver, and secret handling. In a standalone Compose installation, use an equivalent reverse-proxy setup only if you understand how it obtains and renews certificates.

Do not send API keys over plain HTTP on an untrusted network. Redirect HTTP to HTTPS, preserve the Host header required by your proxy rules, and set a request-size limit appropriate for media uploads. Keep the application port private once the proxy is working.

API key handling

Treat AUTHENTICATION_API_KEY as a server credential. Store it in the VPS environment file or a secret manager, restrict file permissions, rotate it after accidental disclosure, and avoid putting it in shell history, screenshots, or client-side JavaScript. Create separate keys or accounts according to the authentication features supported by your installed release.

Best Value
CanaKit Raspberry Pi 5 Essentials Starter Kit (8GB RAM)
  • Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM)
  • Includes 32GB EVO+ Micro SD Card pre-loaded with 64-bit Pi OS, USB MicroSD Card Reader
  • CanaKit Turbine Black Case for the Raspberry Pi 5
  • CanaKit 45W PD Power Supply for the Raspberry Pi 5
  • Display Cable - 6 foot (Supports up to 4K 60p)
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

8. Make the data recoverable

Container recreation is normal; data loss is not. Keep PostgreSQL on a named volume and back it up outside the VPS. A plain SQL dump can be created from the running container:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
docker compose exec -T postgres 
  pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > evolution-$(date +%F).sql

Run the command from a shell that has the variables loaded, or substitute the database and user values explicitly. Encrypt the dump, copy it to separate storage, and periodically test a restore on a disposable PostgreSQL instance. Also back up the Evolution instances volume if it contains data you cannot recreate.

Redis data is different. In the common cache-oriented setup, it is disposable and can be rebuilt, but do not delete its volume if your configuration uses Redis for durable queues or other state. Document which role Redis has before changing images or removing data.

9. Upgrade without guessing

  1. Read the release notes and compare the new tag’s official .env.example with your current file.
  2. Back up PostgreSQL and, if needed, the instances volume.
  3. Change the image tag explicitly; do not silently switch to latest.
  4. Pull and recreate the service:
docker compose pull evolution-api
docker compose up -d evolution-api
docker compose logs -f evolution-api

Keep the previous image tag recorded until the new container completes migrations and passes an authenticated request. If a release changes database variables, Redis settings, or volume paths, update those deliberately rather than copying a community file wholesale.

Common failures and how to diagnose them

P1001: cannot connect to database

A GitHub issue reports that the latest image can fail with a P1001 database connection error even when dependency containers appear healthy. No definitive fix is established by that report. Start with the highest-probability checks: use the Compose service name (postgres), verify the database name, username, password, and port in DATABASE_CONNECTION_URI, and confirm that the variable name matches the release’s official example. Prefer a verified pinned tag while diagnosing instead of changing several variables at once.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Redis reports an incompatible or unreadable data format

An existing Redis volume can contain data written by a different Redis major version. Match the major version to the one that created the volume. If Redis is only a disposable cache in your setup, stop the stack, remove only the Redis volume, and start again; deleting it otherwise can remove queue or application state.

The manager is unavailable immediately after start

Watch docker compose logs evolution-api for migrations and connection retries. Wait for initialization to finish, then retry. If the service repeatedly restarts, inspect the first error rather than repeatedly recreating all containers; a wrong URI or missing variable will survive every restart.

Port 8080 is already in use

Find the process or container holding the port, then either stop the conflicting service or change the host side of the mapping, such as 8081:8080. The container still listens on 8080; only the VPS-facing port changes. Update the reverse proxy target accordingly.

It works on the VPS but not from the internet

Check the VPS firewall, cloud firewall, DNS record, and whether Docker is bound to the expected interface. If HTTPS is enabled, check the reverse proxy logs and certificate resolver before changing Evolution API settings. A private 8080 binding is correct when the proxy is the only public entry point.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Operational checklist

  • Docker Engine and the Compose plugin return versions successfully.
  • PostgreSQL is persistent, reachable by its Compose or external hostname, and included in backups.
  • Redis’s major version matches any existing volume and its durability role is documented.
  • DATABASE_CONNECTION_URI, CACHE_REDIS_URI, and AUTHENTICATION_API_KEY match the installed release’s official variable names.
  • The Evolution image tag is explicit and verified, not an untested latest pull.
  • The API starts with docker compose up -d, migrations finish, and an authenticated request succeeds.
  • Public traffic uses HTTPS; PostgreSQL, Redis, and the application port are not broadly exposed.
  • Secrets are restricted, backups are off-host, and a restore has been rehearsed.
  • Upgrade notes, the current image tag, and the rollback tag are recorded.

Bottom line

A dependable Evolution API VPS is mostly a disciplined container deployment: use PostgreSQL as the documented database, add Redis when your release expects it, keep connection names and environment variables aligned with the official files, and pin the image you have verified. Start with standalone Compose for simplicity, then place Traefik and HTTPS in front when the API must be public. Capacity figures advertised by hosting providers are only starting points, so let observed memory, disk, database growth, and instance traffic determine when the VPS needs to be enlarged.

Quick Recap

Bestseller No. 1
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (8GB RAM)
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (8GB RAM)
Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM); CanaKit Turbine Black Case for the Raspberry Pi 5
$259.95
Bestseller No. 2
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (4GB RAM)
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (4GB RAM)
Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (4GB RAM); CanaKit Turbine Black Case for the Raspberry Pi 5
$209.99
Bestseller No. 3
CanaKit Raspberry Pi 5 Essentials Starter Kit (4GB RAM)
CanaKit Raspberry Pi 5 Essentials Starter Kit (4GB RAM)
CanaKit Raspberry Pi 5 Essentials Starter Kit
$189.99
Bestseller No. 4
CanaKit Raspberry Pi 5 16GB Starter Kit PRO - Turbine Black (128GB Edition) (16GB RAM)
CanaKit Raspberry Pi 5 16GB Starter Kit PRO - Turbine Black (128GB Edition) (16GB RAM)
Includes Raspberry Pi 5 16GB with 2.4Ghz 64-bit quad-core CPU (16GB RAM); CanaKit Turbine Black Case for the Raspberry Pi 5
Bestseller No. 5
CanaKit Raspberry Pi 5 Essentials Starter Kit (8GB RAM)
CanaKit Raspberry Pi 5 Essentials Starter Kit (8GB RAM)
Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM); Includes 32GB EVO+ Micro SD Card pre-loaded with 64-bit Pi OS, USB MicroSD Card Reader
$229.99

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Docker ComposeEvolution APIPostgreSQLRedisself-hostingVPS

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.