When you have a database running in a container, sooner or later you need to peek at its tables without opening a terminal. That is what web-based database managers are for, and two of the handiest in the self-hosted world are Adminer and pgweb. In this guide you bring up both with a single docker-compose.yml file, learn when each one is the better fit and, most importantly, how to secure them so they never end up exposed on the Internet. The same explanation is available in Spanish.

Key takeaways

  • Adminer is a database manager that fits in a single PHP file of about 480 KB and handles eight different engines: MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, Elasticsearch and MongoDB.
  • pgweb is an explorer written in Go, dedicated exclusively to PostgreSQL, shipped as a single binary and with a very useful read-only mode for production.
  • Each tool runs in one container: the official adminer image listens on port 8080 and sosedoff/pgweb on port 8081, with no port conflict.
  • Neither adds authentication of its own beyond the database login, so they must never be published open on the Internet: bind them to 127.0.0.1 or place them behind a proxy with SSO.
  • The setup in this guide includes a sample PostgreSQL database, so you can copy the docker-compose.yml, start it and have both panels working in under a minute.

What is a web-based database manager?

A web-based database manager is an application that connects to your data engine (PostgreSQL, MySQL, MariaDB…) and gives you, from the browser, what you used to do by hand with the command-line client: view tables, edit rows, run SQL queries, inspect indexes or export data. It is the self-hosted equivalent of desktop tools like DBeaver or pgAdmin, but without installing anything on your machine: you just open a URL.

In an infrastructure built with Docker this fits naturally. Your database already lives in a container, so adding another container with the manager and connecting it to the same internal network gives you instant access. The trade-off is security: these tools give full control over the data, so rule number one is never to leave them reachable from outside your network. We will come back to that at the end.

What makes Adminer special?

Adminer was born in 2007 from the hand of Jakub Vrána as a lightweight alternative to phpMyAdmin (its original name was in fact phpMinAdmin). Its great virtue is radical simplicity: the whole tool fits in a single PHP file of about 480 KB, against the roughly 13.7 MB and dozens of files of phpMyAdmin. That difference is not just cosmetic; a smaller code surface means less to audit and less to maintain.

The second thing that sets it apart is its reach. As its official site notes, "Adminer is available for MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, Elasticsearch and MongoDB", so with a single container you cover practically any database you use on your server. The current version of the official image is 5.4.2, and it relies on PHP’s built-in web server to listen on port 8080. It also accepts a few handy environment variables: ADMINER_DEFAULT_SERVER to set the default server it connects to, ADMINER_DESIGN to change the visual theme and ADMINER_PLUGINS to load extensions.

The Adminer and pgweb docker-compose.yml

Create a folder for the project and save this docker-compose.yml inside it. It includes a sample PostgreSQL database so both panels have something to connect to; if you already have your own database, delete the db service and point the tools at the network where it lives. Change cambia_esta_clave to your own password before starting:

services:
  db:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: midb
      POSTGRES_USER: usuario
      POSTGRES_PASSWORD: cambia_esta_clave
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U usuario -d midb"]
      interval: 30s
      timeout: 5s
      retries: 5

  adminer:
    image: adminer:5.4.2
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    environment:
      ADMINER_DEFAULT_SERVER: db
      ADMINER_DESIGN: dracula
    ports:
      - "127.0.0.1:8080:8080"

  pgweb:
    image: sosedoff/pgweb:0.17.0
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    environment:
      PGWEB_DATABASE_URL: postgres://usuario:cambia_esta_clave@db:5432/midb?sslmode=disable
    command: ["--readonly", "--bind=0.0.0.0", "--listen=8081"]
    ports:
      - "127.0.0.1:8081:8081"

volumes:
  db_data:

Notice two decisions in the file. The ports are published as 127.0.0.1:8080 and 127.0.0.1:8081, not as bare 8080: this way the panels only answer from the machine itself and are not exposed to the network even if the server has a public IP. And pgweb starts with --readonly so that from the browser you can only read data, never change it by accident.

With the file ready, start the stack in the background and check the container status:

docker compose up -d
docker compose ps
docker compose logs -f pgweb

When the three containers show as running, open http://localhost:8080 for Adminer and http://localhost:8081 for pgweb. In Adminer you pick the engine (PostgreSQL), type db as the server and use the username and password from the docker-compose.yml. pgweb, on the other hand, connects on its own with the PGWEB_DATABASE_URL string you already gave it, so you will see the tables straight away.

What does pgweb add over Adminer?

pgweb is a different project with a different philosophy. It was created by Dan Sosedoff in 2014 and is written in Go, so it ships as a single compiled binary with no dependencies, which is why its image is so light and starts instantly. Unlike Adminer, it does not try to cover many engines: it focuses entirely on PostgreSQL and, in return, offers a very polished browsing experience.

Its interface is designed to navigate the schema comfortably: a table list in a side panel, a paginated row view, column and index structure, a query editor with highlighting and export of results to CSV, JSON or XML. Version 0.17.0, released in November 2025, was built with Go 1.24 and added support for PostgreSQL 18. The most important practical detail when using it in Docker is the startup: by default pgweb binds to localhost inside the container, so you must pass it --bind=0.0.0.0 (as in the docker-compose.yml above) or it will not be reachable from the host’s browser.

Which one to choose? If you work only with PostgreSQL and want a fast, read-only explorer to keep an eye on production, pgweb is a delight. If you juggle several engines at once (for example, PostgreSQL for one app and MariaDB for another) and need to edit data, Adminer gives you a single window for all of them. Many setups end up with both: Adminer as the Swiss army knife and pgweb as the comfortable viewer for the main PostgreSQL.

How do you secure these panels?

This is the part most people overlook and the most dangerous. Neither Adminer nor pgweb adds an authentication layer of its own: whoever reaches the URL can try to log in with any database credential. Publishing them open on the Internet is an invitation to automated scanners. There are three measures worth combining.

The first, already applied in the docker-compose.yml, is binding the ports to 127.0.0.1 so the panels only answer locally; from your laptop you reach them with an SSH tunnel (ssh -L 8080:localhost:8080 user@server) and nobody else sees them. The second is not publishing ports at all and letting the tools talk to the database over Docker’s internal network, exposing them only behind a reverse proxy. The third, if you need permanent web access, is making that proxy require a login: the most solid option is a proxy with SSO such as Authentik, which asks for authentication before letting anyone through to Adminer. For pgweb, the --readonly mode is an extra safety net: even if someone gets in, they cannot alter data. And remember to install the Docker engine from a solid base by following the guide to install Docker on Ubuntu 24.04.

Frequently asked questions

Can I use Adminer with MySQL and MariaDB besides PostgreSQL?

Yes, and that is precisely its strong point. The official adminer image connects to MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, Elasticsearch and MongoDB from the same container. You just pick the system on the login screen and type the name of the database container’s service as the server. pgweb, by contrast, is PostgreSQL only.

Why should I not leave the latest tag in production?

Because :latest can drag you into a major version without warning during a simple restart and break something. By pinning adminer:5.4.2 and sosedoff/pgweb:0.17.0 you know exactly what code you are running and you decide when to update. It is the same rule you apply to the database: pinned versions and controlled updates.

Does pgweb let me modify data or only read it?

It depends on how you start it. With no arguments, pgweb lets you run any query, including writes. In the docker-compose.yml in this guide it is launched with the --readonly argument, which enables read-only transactions: ideal for inspecting a production database without any risk of changing something by mistake.

Conclusion

With a single docker-compose.yml you have two complementary ways to look at your databases from the browser: Adminer, the multi-engine Swiss army knife in one file, and pgweb, the lightweight read-only explorer for PostgreSQL. The key is bringing them up sensibly: ports bound to 127.0.0.1, Docker’s internal network and, if you need permanent access, a proxy with authentication in front. From there, managing your data no longer requires a terminal and becomes a matter of opening a tab.

Sources: [1] Official Adminer image on Docker Hub[1], [2] Official Adminer project site[2], [3] pgweb repository on GitHub (sosedoff/pgweb)[3].

Sources

  1. Official Adminer image on Docker Hub
  2. Official Adminer project site
  3. pgweb repository on GitHub (sosedoff/pgweb)

Route: Self-hosted databases and storage with Docker