Self-hosting

Secure Umami analytics deployment with Docker and PostgreSQL

A technical guide details how to self-host Umami v3 using Docker, highlighting critical security steps like localhost binding and default credential changes.

Illustration of a secured server rack representing safe self-hosting practices
Illustration created for this article

A recent technical guide published on October 18, 2026, outlines the specific steps required to self-host Umami analytics version 3.4.0 using Docker and PostgreSQL. The article emphasizes secure configuration practices, particularly regarding network binding and initial authentication, to prevent unauthorized access during the setup process.

What happened

The guide provides a detailed walkthrough for deploying Umami, a privacy-focused alternative to Google Analytics, within a containerized environment. It specifies using the ghcr.io/umami-software/umami:3.4.0 image alongside a postgres:15.19-alpine database container. A central focus of the instructions is the modification of the default Docker Compose configuration to enhance security immediately upon deployment.

The author highlights a critical security risk in the upstream default configuration, which binds the application port to all network interfaces. Because Docker-published ports can bypass host-level firewalls like ufw, leaving the default settings intact could allow external actors to reach the application before the administrator has a chance to secure it. The guide recommends binding the port specifically to 127.0.0.1, ensuring that only local processes, such as a reverse proxy, can communicate with the Umami instance.

Another significant portion of the guide addresses the default credentials. Umami initializes with a standard username and password combination of admin and umami. The instructions stress that administrators must change this password immediately after the first login. If the port is exposed to the public internet before this change occurs, any user who discovers the service could log in as an administrator and compromise the instance.

Key details

  • Umami version 3.4.0 does not support MySQL; PostgreSQL is the required database engine.
  • The default administrative login credentials are username admin and password umami.
  • Binding the Docker port to 127.0.0.1:3000 prevents external network access to the raw application port.
  • Secrets such as POSTGRES_PASSWORD, APP_SECRET, and TWO_FACTOR_ENCRYPTION_KEY should be stored in a protected .env file.
  • Changing the PostgreSQL password in the environment variables after the initial database creation will cause authentication failures unless the database user password is also updated manually.
  • The application includes a bot detection filter that silently drops requests from headless browsers, which can confuse developers during testing.

Background

Self-hosting analytics software gives organizations control over their data, but it also shifts the responsibility for security entirely to the internal IT team. Unlike managed services where the provider handles patching and access control, self-hosted instances require careful configuration of network boundaries and authentication mechanisms. Docker simplifies the deployment of complex applications like Umami by packaging the application and its dependencies into containers, but it introduces specific networking behaviors that administrators must understand.

One common misconception is that host-level firewalls automatically protect Docker containers. In many default configurations, Docker manages its own iptables rules, which can override user-defined firewall settings like ufw. This means that if a container exposes a port to the host, it may be accessible from the wider network even if the host firewall appears to block that traffic. Understanding this interaction is crucial for securing any self-hosted web application.

Why it matters

For teams running their own software, the difference between a secure deployment and a vulnerable one often comes down to small configuration details. The recommendation to bind to localhost is a fundamental defense-in-depth strategy. It ensures that the application is not directly exposed to the internet, forcing all traffic through a reverse proxy like Caddy or Nginx. This setup allows the proxy to handle TLS termination and additional security headers, while the application itself remains isolated on the local loopback interface.

The issue with default credentials is another persistent challenge in self-hosted environments. Many open-source projects use simple default passwords to facilitate easy initial setup and testing. However, if these defaults are not changed immediately, they become a well-known entry point for attackers. Automating the secret generation process, as suggested in the guide using tools like openssl, reduces the risk of human error and ensures that each deployment starts with unique, strong credentials.

Additionally, the guide’s note about bot filtering highlights the importance of understanding application logic during troubleshooting. Developers often test new deployments using automated tools or headless browsers, which Umami identifies as bots and ignores. Without this knowledge, teams might spend significant time debugging why their tracking scripts appear to fail, when in fact the system is working as designed to preserve data quality.

What you can do

  • Generate strong, random secrets for POSTGRES_PASSWORD, APP_SECRET, and TWO_FACTOR_ENCRYPTION_KEY before starting the containers.
  • Modify the Docker Compose file to bind the Umami port to 127.0.0.1 instead of all interfaces.
  • Deploy a reverse proxy such as Caddy to handle HTTPS connections and forward traffic to the local Umami instance.
  • Log in immediately after the first start and change the default admin password to a strong, unique value.
  • Pin the Docker image tag to a specific version like 3.4.0 rather than using latest to ensure predictable upgrades.
  • Test tracking functionality using a standard browser with a normal user agent to avoid being filtered by the built-in bot detection.

More news

All news