Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteiTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
The reliable production pattern is to run the official metabase/metabase Docker image on a Linux VPS, store Metabase’s application state in PostgreSQL instead of embedded H2, and expose it through an HTTPS reverse proxy. Bind the container’s port 3000 only to the local host or a private Docker network, keep database credentials in secrets, and back up the PostgreSQL application database before upgrades.
What a production Metabase deployment looks like
A quick Docker test can publish port 3000 directly and use the image’s embedded H2 database. That is useful for evaluating the interface, but it is not a durable production design: removing the container removes the H2 file and therefore Metabase’s application data. A production deployment separates the components:
Recommended Free Tools
- Metabase: the official
metabase/metabaseimage, running as a container. - Application database: PostgreSQL, either on the VPS or supplied as a managed database. It stores Metabase users, questions, dashboards, permissions, settings, and other application metadata.
- Reverse proxy: a web server or load balancer that owns the public hostname, terminates TLS, and forwards requests to Metabase.
- Persistent operations: firewall rules, secret storage, image-version control, PostgreSQL backups, restore testing, and a rollback plan.
Metabase’s connected data sources remain separate from the application database. Backing up PostgreSQL protects Metabase’s configuration and content; it does not replace backups for the databases that contain your business data.
Prerequisites and decisions before you start
VPS and operating system
Provision a current Linux VPS with a public IP address, a DNS name you control, Docker Engine, and Docker Compose. The required CPU, memory, disk, and network capacity depend on concurrent users, dashboard complexity, scheduled jobs, and the size and responsiveness of the connected data sources. The first-party material does not establish a universal VPS size or performance benchmark, so size the host from your workload and monitor it rather than relying on a generic minimum.
#1 Best Overall
DNS and public ports
Create a DNS record such as analytics.example.com pointing to the VPS. In the finished design, the normal public entry points are SSH for administration and HTTPS for users. Metabase’s application port, 3000, should not be reachable directly from the internet.
PostgreSQL location
You can run PostgreSQL on the VPS with its own persistent volume, or use a managed PostgreSQL service. A managed service reduces database maintenance on the VPS but still leaves you responsible for the Metabase configuration, credentials, network allow-list, TLS validation, backups, and restore tests. Whichever option you choose, create an empty database for Metabase; you do not need to create Metabase tables manually.
Version policy
The quick-start examples commonly use the latest image tag for convenience. Treat that as a demonstration choice, not as an immutable production release reference. Select a reviewed Metabase version or digest, record the current version, and change it deliberately during upgrades.
Install Docker and create a private project
Install Docker Engine and the Compose plugin using the instructions for your Linux distribution. Then create a directory that is readable only by administrators:
sudo mkdir -p /opt/metabase/secrets
sudo chown -R "$USER":"$USER" /opt/metabase
cd /opt/metabase
chmod 700 secrets
Compose will create a project network for the container. If your reverse proxy also runs in Docker, attach it to the same private network and route to the Metabase service name. If the proxy runs directly on the VPS, bind Metabase to 127.0.0.1 so only local processes can reach it.
Create the empty PostgreSQL application database
Use your PostgreSQL provider’s control panel or an administrator connection to create a database named metabaseappdb and a dedicated login named metabase_user. Grant that login the privileges required to create and modify objects in the Metabase database. Do not reuse a superuser or the credentials of a business-data connection.
Rank #2
- Wiley
- Language: english
- Book - storytelling with data: a data visualization guide for business professionals
If PostgreSQL is administered with psql, the database-creation portion can be performed interactively:
psql -h DB_HOST -U postgres -d postgres
CREATE DATABASE metabaseappdb;
CREATE USER metabase_user;
password metabase_user
GRANT ALL PRIVILEGES ON DATABASE metabaseappdb TO metabase_user;
q
The exact ownership and schema grants can vary with the PostgreSQL version and provider. Follow the provider’s privilege model if it requires the database user to own the database or grants additional schema permissions. The important Metabase requirement is an empty, reachable PostgreSQL database whose credentials have enough rights for Metabase to create its application tables during startup.
Store credentials as Docker secrets
Keep the database username and password out of a committed Compose file. Create two local secret files, restrict their permissions, and use a secret manager or your platform’s equivalent when the VPS is managed centrally:
cd /opt/metabase
printf '%s' 'metabase_user' > secrets/mb_db_user
printf '%s' 'use-a-long-unique-password' > secrets/mb_db_pass
chmod 600 secrets/mb_db_user secrets/mb_db_pass
Do not commit the secrets directory to source control, include it in backups that are accessible to untrusted users, or paste its contents into support tickets. The Docker image supports file-based secret variables including MB_DB_USER_FILE, MB_DB_PASS_FILE, and MB_DB_CONNECTION_URI_FILE.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Define the Metabase Compose service
Create /opt/metabase/compose.yml. Replace the database host and public hostname with your values. The example intentionally binds port 3000 to loopback instead of publishing it on every network interface:
services:
metabase:
image: metabase/metabase:latest
container_name: metabase
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
environment:
MB_DB_TYPE: postgres
MB_DB_DBNAME: metabaseappdb
MB_DB_PORT: "5432"
MB_DB_HOST: db.example.internal
MB_DB_USER_FILE: /run/secrets/mb_db_user
MB_DB_PASS_FILE: /run/secrets/mb_db_pass
MB_SITE_URL: https://analytics.example.com
MB_REDIRECT_ALL_REQUESTS_TO_HTTPS: "true"
secrets:
- mb_db_user
- mb_db_pass
healthcheck:
test: ["CMD", "curl", "--fail", "http://localhost:3000/api/health"]
interval: 30s
timeout: 5s
retries: 5
start_period: 60s
secrets:
mb_db_user:
file: ./secrets/mb_db_user
mb_db_pass:
file: ./secrets/mb_db_pass
The required database settings are MB_DB_TYPE=postgres, the database name, port, user, password, and host. Metabase connects with those settings and creates its own tables on the first successful startup. If your provider supplies a connection URI instead, use the supported connection-URI setting and its file-based secret variant rather than placing a password in plain text.
Rank #3
Before starting, validate the rendered Compose configuration and check that secret files are present:
docker compose config
test -s secrets/mb_db_user
test -s secrets/mb_db_pass
If the output of docker compose config reveals a password or other secret, stop and revise the file before proceeding.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Start Metabase and complete first-run setup
- Start the service in the background:
docker compose up -d. - Follow startup output with
docker logs -f metabase. The first run can take longer while Metabase initializes its application schema. - From the VPS itself, check the health endpoint:
curl --fail http://127.0.0.1:3000/api/health. A successful response confirms that the HTTP service is responding; it does not prove that every data source is reachable. - Open the public HTTPS hostname after the reverse proxy is configured and complete the browser-based setup wizard. Create the initial administrator, set the site details, and add data sources using separate least-privilege credentials.
If the container exits, inspect the complete log rather than repeatedly restarting it. Database DNS failures, rejected credentials, TLS validation errors, and insufficient PostgreSQL privileges are normally visible in the startup output.
Put Metabase behind an HTTPS reverse proxy
The reverse proxy should be the only public path to Metabase. It obtains and renews the certificate, accepts HTTPS, and forwards requests to http://127.0.0.1:3000 on the VPS. Configure the canonical URL in the Compose file as the exact HTTPS hostname and keep MB_REDIRECT_ALL_REQUESTS_TO_HTTPS=true when TLS terminates at the proxy.
A minimal Nginx-style virtual host has the following routing characteristics:
server {
listen 443 ssl;
server_name analytics.example.com;
# Configure your certificate and private key here.
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
The exact certificate directives and renewal commands depend on the reverse-proxy software and certificate authority you select. Test the proxy configuration, reload it without stopping the container, and verify that the browser shows a valid certificate, the hostname remains stable, and login redirects do not loop between HTTP and HTTPS.
Rank #4
If the proxy runs in another container, use a private Docker network and the Metabase service name instead of exposing port 3000 on the host. If a load balancer sits in front of the proxy, preserve the original host and HTTPS forwarding information so Metabase can construct correct links.
Lock down the VPS and network
- Allow SSH only from trusted administrative addresses where practical.
- Allow inbound HTTPS to the reverse proxy.
- Do not allow inbound TCP 3000 from the public internet. The loopback binding in the Compose example prevents that exposure on a single-host proxy.
- Allow PostgreSQL traffic only between Metabase and the database service. For a managed database, add the VPS address or private network to the provider’s allow-list.
- Apply operating-system security updates and remove unused services and firewall rules.
- Use a separate database login for each connected data source, with read-only access when dashboards do not need writes.
HTTPS protects browser traffic between users and the proxy. Use TLS certificate validation for the PostgreSQL application database and connected data sources whenever those services support it. The container image includes AWS and Azure CA certificates under /app/certs/. A different provider’s certificate may require a custom image or mounted certificate files, following that provider’s certificate instructions.
Back up PostgreSQL and test restoration
Metabase’s security guidance calls for a production application database and regular backups. Back up the PostgreSQL database that Metabase uses, not just the Docker volume or the VPS filesystem. A logical dump can be created with:
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutepg_dump
--host DB_HOST
--port 5432
--username metabase_user
--format custom
--file metabaseappdb.dump
metabaseappdb
Protect the dump as sensitive data because it contains Metabase configuration and potentially user or connection metadata. Store copies according to your retention policy and document who can restore them.
A backup is not operationally trustworthy until restoration has been tested. On a separate PostgreSQL instance, create an empty test database, restore the dump, point a temporary Metabase container at that database, and verify that administrators can sign in and dashboards open. Record the restore time and any manual steps. Repeat the test after major Metabase or PostgreSQL changes.
Upgrade safely and keep a rollback path
- Read the release notes for the Metabase version you plan to deploy and confirm that your PostgreSQL version and integrations remain supported.
- Take and verify a fresh PostgreSQL application-database backup.
- Change the Compose image from the current reviewed tag or digest to the new reviewed value. Avoid treating
latestas a permanent production pin. - Pull and recreate the service:
docker compose pull metabase && docker compose up -d metabase. - Watch
docker logs -f metabase, check/api/health, and test login, dashboards, subscriptions, and representative data-source queries. - If the deployment fails, restore the previous image reference. If a database migration has already run and the older application cannot use the migrated schema, restore the pre-upgrade PostgreSQL backup in the rollback environment rather than repeatedly switching images against an unknown schema state.
Keep the Compose file, image reference, proxy configuration, database endpoint, and restore procedure under controlled change management. A rollback plan that exists only in an operator’s memory is not a reliable rollback plan.
Best Value
Troubleshoot the common failure modes
The container starts and then exits
Run docker logs metabase. Check spelling and values for MB_DB_TYPE, MB_DB_DBNAME, MB_DB_HOST, and MB_DB_PORT. Confirm that the secret files are non-empty and readable by Docker. If PostgreSQL rejects the connection, verify the username, password, database allow-list, and network route.
Metabase cannot resolve or reach PostgreSQL
Confirm that the hostname resolves from the VPS or container network and that the database firewall permits the source address. A managed database may require a private-network route or an explicit IP allow-list. Test connectivity from an approved diagnostic container or PostgreSQL client without exposing the database publicly.
Authentication succeeds but the browser redirects repeatedly
Check that users reach the proxy through HTTPS, MB_SITE_URL contains the same HTTPS hostname, and the proxy sends X-Forwarded-Proto https. Remove conflicting HTTP-to-HTTPS redirects at other layers and reload the proxy.
The site works locally but not from the internet
Check DNS resolution, the VPS firewall, the proxy listener, certificate validity, and the cloud provider’s network firewall. Ensure the proxy can reach 127.0.0.1:3000 and that the Metabase container is healthy.
A connected data source fails while Metabase is healthy
The health endpoint checks Metabase’s HTTP service, not every data source. Review the data-source credentials, network allow-list, TLS certificate chain, hostname, port, and least-privilege permissions. Keep source-database troubleshooting separate from the PostgreSQL database that stores Metabase’s own application state.
Free tools Windows power users keep installed
One-click scans. No signup required.
The installation accidentally used H2
Inspect the environment and startup logs. Production configuration must set MB_DB_TYPE=postgres and the PostgreSQL connection values. Do not delete the old container until you have determined whether it contains any configuration worth preserving; H2 data disappears with the container unless its storage was deliberately persisted.
Docker on a VPS versus Metabase Cloud
| Decision axis | Docker on your VPS | Metabase Cloud |
|---|---|---|
| Operational effort | You operate Docker, PostgreSQL or its connection, the reverse proxy, firewall, certificates, monitoring, backups, and upgrades. | The service provider operates the platform layer, reducing server and proxy administration. |
| Control and data residency | You choose the host, network boundaries, database location, and retention controls, subject to your infrastructure and compliance requirements. | You accept the provider’s hosting architecture, regions, and service controls. |
| Recurring infrastructure cost | You pay for the VPS, storage, database resources, backups, traffic, and any operational tooling. No universal price is established. | Pricing and included capacity depend on the selected service plan and are not evaluated here. |
| Backup responsibility | You must back up the PostgreSQL application database and test restoration. | The provider manages platform operations, but you should still understand its backup, export, retention, and recovery terms. |
| TLS and networking | You configure DNS, certificates, proxy headers, firewall rules, and database connectivity. | The provider supplies the hosted ingress; you configure data-source access and any required network integration. |
| Upgrade and rollback ownership | You choose when to pull an image, review changes, test, and roll back. | The provider controls the service upgrade process; you control the compatibility of connected systems and your exported data. |
Self-hosting is a fit when infrastructure control, private networking, or data-residency requirements justify the operational work. A hosted service is simpler when you prefer not to run the server, database, proxy, and recovery process yourself.
Production-readiness checklist
- Metabase runs from the official Docker image with a reviewed, recorded image version.
MB_DB_TYPE=postgresand all PostgreSQL connection settings point to a dedicated application database.- PostgreSQL credentials are supplied through Docker Secrets or an equivalent secret manager, not committed Compose text.
- Metabase’s port 3000 is private and unreachable from the public internet.
- The reverse proxy serves the configured canonical hostname over HTTPS.
MB_SITE_URLmatches that HTTPS hostname and the HTTPS redirect setting matches where TLS terminates.- Database and data-source TLS certificate validation is enabled where supported.
- Operating-system updates, firewall rules, and database network allow-lists are maintained.
- PostgreSQL backups run regularly, are protected, and have passed a restoration test.
- Upgrade records include the image reference, backup, health check, functional tests, and rollback procedure.
Bottom line
For a durable VPS deployment, run Metabase in Docker with PostgreSQL as its application database, keep the container behind a private reverse-proxy connection, terminate TLS at the proxy, protect credentials with secrets, and make backup-and-restore testing part of normal operations.
Quick Recap
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.

