Bare-metal servers with AMD Ryzen™ 9 9950X processor are now available in our NL location. Click here to order.

How to Self-Host Metabase on Ubuntu 26.04

  • published_on 2026 Август 28

 

Many organizations store valuable data in databases, but giving teams an easy way to explore, visualize, and share that data often requires a dedicated business intelligence (BI) platform.

Metabase is an open-source business intelligence (BI) platform that enables teams to analyze data, build interactive dashboards, and share insights without relying on proprietary software. It connects to a wide range of databases and data sources, making it suitable for everything from business reporting to application monitoring and analytics.

In this guide, you'll learn how to self-host Metabase on Ubuntu 26.04 LTS with Docker and PostgreSQL. You'll set up persistent storage, configure Nginx as a reverse proxy, and secure the deployment with HTTPS using Let's Encrypt.

Prerequisites

Before you begin, ensure you have the following:

  • An Ubuntu 26.04 LTS server

  • A root or sudo-enabled user account

  • Docker Engine and Docker Compose V2 (docker compose) installed. If Docker is not already installed, follow our How to Install and Set Up Docker on Ubuntu 26.04 guide before continuing.

  • A domain name pointing to the VPS

For a smoother production-style deployment, a VPS with at least 2 vCPUs and 4 GB RAM is recommended.

Choose Ubuntu 26.04 VPS hosting in Lithuania, the Netherlands, the USA, or the UK. Fast NVMe storage delivers excellent performance, low latency, and reliable speed for your projects. Perfect for websites, applications, testing environments, and business infrastructure.
Get Ubuntu 26.04 VPS

Step 1: Update the System

Before installing Metabase and its dependencies, update the package index:

sudo apt update

Next, upgrade the installed packages on the server:

sudo apt upgrade -y

These commands ensure that the system is up to date before you continue.

Step 2: Verify the Docker Installation

Before deploying Metabase, verify that Docker Engine and Docker Compose V2 are installed and that the Docker service is running.

Check the installed Docker version.

docker --version

If Docker is installed, you should see output similar to:

img-1787912963-6a91630353479.webp

Next, verify that Docker Compose V2 is available:

docker compose version

If the Docker Compose plugin is installed, the command displays the installed version.

Step 3: Create the Metabase Project Directory

Create a dedicated directory for the Metabase deployment.

mkdir -p ~/metabase

Change into the directory.

cd ~/metabase

This directory will contain the Docker Compose configuration and the environment file for the deployment.

Step 4: Create the Environment File

Create a .env file in the project directory to store the PostgreSQL connection settings for the Metabase deployment:

nano .env

Add the following values, replacing the example password with a strong password:

MB_DB_TYPE=postgresMB_DB_DBNAME=metabaseMB_DB_PORT=5432MB_DB_USER=metabaseMB_DB_PASS=your_strong_passwordMB_DB_HOST=postgres

The MB_DB_HOST value postgres corresponds to the PostgreSQL service name defined in the Docker Compose configuration.

After saving the file, restrict its permissions so that only the current user can read and modify it:

chmod 600 .env

The .env file contains database credentials and should not be committed to a public Git repository.

 

Step 5: Create the Docker Compose Configuration

Metabase recommends PostgreSQL as its application database. This database stores Metabase users, dashboards, questions, collections, settings, and other application metadata.

It is important to distinguish this PostgreSQL database from the databases you will later connect to Metabase for analytics. The PostgreSQL database configured here stores Metabase's own configuration and content, while your analytics databases contain the data you want to analyze.

From the Metabase project directory, create and open the Docker Compose file:

nano compose.yaml

Add the following configuration:

services:  postgres:    image: postgres:16    container_name: metabase-postgres    restart: unless-stopped    environment:      POSTGRES_DB: ${MB_DB_DBNAME}      POSTGRES_USER: ${MB_DB_USER}      POSTGRES_PASSWORD: ${MB_DB_PASS}    volumes:      - pgdata:/var/lib/postgresql/data    networks:      - metabase-internal    healthcheck:      test: ["CMD-SHELL", "pg_isready -U ${MB_DB_USER} -d ${MB_DB_DBNAME}"]      interval: 10s      timeout: 5s      retries: 5  metabase:    image: metabase/metabase:v0.63.2    container_name: metabase    restart: unless-stopped    depends_on:      postgres:        condition: service_healthy    environment:      MB_DB_TYPE: postgres      MB_DB_DBNAME: ${MB_DB_DBNAME}      MB_DB_PORT: 5432      MB_DB_USER: ${MB_DB_USER}      MB_DB_PASS: ${MB_DB_PASS}      MB_DB_HOST: postgres    ports:      - "127.0.0.1:3000:3000"    networks:      - metabase-internal    healthcheck:      test: ["CMD-SHELL", "curl --fail -I http://localhost:3000/api/health || exit 1"]      interval: 15s      timeout: 5s      retries: 5volumes:  pgdata:networks:  metabase-internal:    driver: bridge

Save and close the file.

The PostgreSQL service uses the credentials defined in the .env file and stores its data in the persistent pgdata volume. No host port is assigned to PostgreSQL, so the database remains accessible only through the Docker network.

The metabase-internal network allows Metabase to communicate with PostgreSQL using the postgres service name. Metabase's port 3000 is bound only to the server's localhost interface, allowing the later-configured Nginx reverse proxy to access Metabase without exposing port 3000 directly to the Internet.

The health checks ensure that PostgreSQL is ready before Metabase starts and help verify that both services are responding correctly.

With the Docker Compose configuration complete, you can now start the Metabase services.

Step 6: Start Metabase

Start the Metabase and PostgreSQL services in the background:

docker compose up -d

Verify that the containers are running:

docker compose ps

You should see output similar to the following: 

img-1787912963-6a916303be8f4.webp

The output may vary, but PostgreSQL should show Up (healthy) and Metabase should show Up. 

Once the services are running, you can proceed to the initial Metabase setup.

Step 7: Complete the Initial Metabase Setup

Open a second terminal on your local computer and create an SSH tunnel to the VPS:

ssh -L 3000:127.0.0.1:3000 USERNAME@SERVER_IP

This forwards traffic from your local machine to Metabase on the server, which is listening only on localhost.

Keep the SSH session open while completing the setup wizard. The SSH tunnel is only required for this initial setup; after HTTPS is configured, you will access Metabase through your domain instead.

Then open the following address in your local browser: 

http://localhost:3000

img-1787912964-6a916304375b5.webp

When the Metabase setup wizard appears, follow the on-screen prompts to:

  • Create the administrator account.

  • Choose your preferred language and organization settings.

  • Optionally connect a data source or continue using the included Sample Database. You can add additional data sources later from the Metabase administration settings.

  • Choose whether to share anonymous usage data with Metabase.

After completing the setup wizard, verify that the Metabase dashboard loads successfully.

Step 8: Configure Nginx as a Reverse Proxy

Nginx will receive requests for your Metabase domain and forward them to Metabase through the localhost port configured earlier.

First, install Nginx:

sudo apt install nginx -y

Next, create a dedicated Nginx server block for Metabase:

sudo nano /etc/nginx/sites-available/metabase

Add the following configuration, replacing metabase.example.com with the domain you configured for your Metabase installation:

server {   listen 80;   server_name metabase.example.com;   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 $scheme;   }}

The proxy_pass directive forwards requests to Metabase on port 3000. The proxy headers pass the original host, client IP address, and protocol information to Metabase.

Save and close the file.

Enable the Metabase server block:

sudo ln -s /etc/nginx/sites-available/metabase /etc/nginx/sites-enabled/metabase

If UFW is enabled, allow HTTP traffic through port 80:

sudo ufw allow 80/tcp

Test the Nginx configuration:

sudo nginx -t

You should see output similar to:

img-1787912964-6a916304ac06d.webp

If the test is successful, reload Nginx:

sudo systemctl reload nginx

You can now access Metabase through your domain over HTTP:

http://metabase.example.com

The Metabase login page should open in your browser.

At this stage, Nginx is forwarding requests to Metabase while port 3000 remains accessible only through the server's localhost interface. The next step is to secure the connection with HTTPS.

Step 9: Enable HTTPS

Install Certbot and the Nginx plugin:

sudo apt install certbot python3-certbot-nginx -y

After the installation is complete, obtain a Let's Encrypt certificate for your Metabase domain. Replace metabase.example.com with the domain configured for your Metabase installation: 

sudo certbot --nginx -d metabase.example.com

Follow the prompts to provide an email address, agree to the Let's Encrypt Terms of Service, and choose whether to share your email address with the Electronic Frontier Foundation (EFF).

When prompted, select the option to redirect all HTTP traffic to HTTPS. Certbot will automatically update the Nginx configuration and install the SSL certificate.

If UFW is enabled, allow HTTPS traffic through port 443:

sudo ufw allow 443/tcp

This allows external HTTPS connections to reach Nginx.

Finally, open your Metabase domain using HTTPS. Replace metabase.example.com with your actual domain:

https://metabase.example.com

Confirm that:

  • The Metabase instance loads successfully over HTTPS.

  • The browser reports a secure connection.

  • Requests to http://metabase.example.com automatically redirect to https://metabase.example.com.

Step 10: Verify Data Persistence

Restart the Metabase and PostgreSQL containers to verify that Metabase retains its application data: 

docker compose restart

Wait for the containers to restart, then open your Metabase domain and sign in. 

Confirm that:

  • Your administrator account is still available.

  • Your Metabase settings have been preserved.

  • Any dashboards, collections, or questions you created remain available.

You can also verify that the containers are running:

docker compose ps

If your Metabase data remains intact after the restart, the PostgreSQL application database and persistent Docker volume are working as expected. 

Step 11: Back Up and Maintain Metabase

The PostgreSQL application database stores your Metabase users, dashboards, questions, collections, settings, and other application metadata. Back up this database regularly to protect your Metabase configuration and content.

Use PostgreSQL backup tools such as pg_dump rather than copying the live PostgreSQL data volume.

For example, create a database backup from the PostgreSQL container:

docker exec -t metabase-postgres pg_dump -U metabase -d metabase > metabase_backup.sql

Replace metabase with the PostgreSQL username and database name configured in your .env file if you used different values.

Store the backup securely and, when possible, keep a copy outside the VPS.

To automate recurring PostgreSQL backups, see our guide on How to Schedule and Automate Tasks on Ubuntu VPS Using Cron Jobs.

To view Metabase logs, run:

docker compose logs -f metabase

When upgrading Metabase, first update the Metabase image tag in compose.yaml to the version you want to deploy. Then pull the updated image and recreate the container:

docker compose pulldocker compose up -d

Before upgrading Metabase, create a backup of the PostgreSQL application database. This gives you a recovery point if the upgrade causes problems.

Conclusion

You have now self-hosted Metabase on Ubuntu 26.04 using Docker, PostgreSQL, and Nginx, with HTTPS enabled for secure access. The PostgreSQL application database and persistent storage help ensure your Metabase configuration and content survive container restarts.

With regular database backups and controlled updates, your Metabase deployment is ready for ongoing use and maintenance.

For more in-depth tutorials, visit the BaCloud blog, where you’ll find helpful guides.

« Назад