Install Portainer to Manage Docker via UI — No More Memorizing Commands, No More Mistakes

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

Typing Docker Commands Every Day — Until It Gets Exhausting

If you’re running a few dozen containers on a VPS, you’re probably familiar with the routine: SSH into the server, run docker ps -a, stare at a wall of containers, then dig through logs one by one. Then docker inspect to check networks and volumes… Every little operation requires opening a terminal.

I’ve been there. At first with just 5–6 containers, keeping commands in your head is manageable. But once you scale up to 20–30 containers — Nginx, PHP-FPM, MySQL, Redis, n8n, Gitea — the CLI starts becoming a burden. Especially when you’re debugging at 2 AM, fingers mistyping container names while your eyes can barely focus.

Why Docker CLI Falls Short in Real-World Environments

The problem isn’t that Docker CLI is weak. Quite the opposite — CLI is very powerful. But it demands that you remember exact container names, volume names, and command syntax. Some real-world pain points:

  • Hard to get an overview: docker stats shows real-time data but doesn’t keep history or display graphs.
  • Hard to share access: If a teammate needs to view logs, you have to create an SSH key for them — unnecessary risk.
  • Easy to make mistakes: Accidentally running docker rm on the wrong running container happens more often than you’d think.
  • No network topology view: It’s hard to tell which containers are connected to which networks using only CLI.

That’s when I started looking for an alternative — something that sits on top of Docker Engine so I don’t have to open a terminal for every little operation.

Options for Managing Docker via a GUI

Lazydocker — A Lightweight Terminal UI

Don’t want a web UI? Lazydocker is the lightest option. It runs directly in the terminal, requires no open ports, no reverse proxy. The downside: you still need to SSH into the server, and remote access isn’t straightforward.

Rancher — Heavy, Built for Kubernetes

Rancher is powerful but primarily designed for Kubernetes clusters. If you’re only running standalone Docker, installing Rancher is overkill — it’s RAM-hungry, complex to configure, and takes hours to get up and running.

Portainer CE — The Sweet Spot Between Simple and Feature-Complete

Portainer Community Edition is what I’ve been using consistently for two years and have yet to find a reason to switch. Install it with Docker, access it from a web browser, and get full management of containers, images, volumes, and networks. The standout feature is managing Docker Compose stacks directly from the UI — deploy without ever SSHing into the server.

Installing Portainer — The Right Way to Avoid Headaches Later

Prerequisites

  • Docker Engine installed (version 20.10 or later)
  • Docker Compose v2 (integrated plugin, not standalone v1)
  • VPS/server with port 9443 (HTTPS) or 9000 (HTTP) open

Setting Up the Directory and Compose File

I always install Portainer using Docker Compose — easier to update, backup, and migrate than running docker run directly. One thing to note: use docker compose (v2, no hyphen), not the old docker-compose. It’s faster, better integrated with modern Docker Engine, and docker-compose v1 officially reached end-of-life in July 2023.

mkdir -p /opt/portainer && cd /opt/portainer

Create a compose.yml file with the following content:

services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: unless-stopped
    ports:
      - "9443:9443"
      - "8000:8000"   # tunnel agent (optional)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data

volumes:
  portainer_data:

Starting Portainer

docker compose up -d

Check if the container is running:

docker compose ps

After about 10–15 seconds, open https://<your-server-IP>:9443 in your browser. The first time, you’ll see a form to create an admin account — fill it in and log in.

Note: Portainer uses a self-signed certificate — your browser will warn you it’s untrusted. You can click “Advanced → Proceed” to bypass it, or set up a reverse proxy with Let’s Encrypt later (recommended for production).

Initial Security Setup — Don’t Skip This Step

After creating your admin account, take care of these steps before getting started:

  1. Set a strong password — at least 12 characters with numbers and special characters.
  2. Disable unnecessary access: Settings → Authentication → disable “Allow non-admin users to access the local environment” if you’re the only user.
  3. Restrict access by IP using a firewall: Only allow your IP to access port 9443.
# Allow only a specific IP to access Portainer
ufw allow from 203.0.113.10 to any port 9443
ufw deny 9443
ufw reload

Practical Tips After Installation

Managing Docker Compose Stacks from the UI

This is the feature I use most. Go to Stacks → Add stack, paste the compose.yml content of the service you want to deploy — Portainer will manage it as a single unit. When you need to update to a newer image, just click “Pull and redeploy” and you’re done. No SSH, no memorizing commands.

Viewing Real-Time Logs Without Memorizing Container Names

Click on a container → Logs tab → enable “Auto-refresh logs”. Far more convenient than typing docker logs -f --tail 100 some-very-long-container-name every time you need to debug.

Exec Into a Container from the Browser

Container → Console tab → Connect. A terminal opens directly in your browser — no extra SSH window needed. Useful when you need to quickly inspect a config file inside a container without opening another session.

Easier Volume Backups

Go to Volumes and you can clearly see which volume is used by which container. A quick volume backup script:

# Back up portainer_data volume to a tar file
docker run --rm \
  -v portainer_data:/source \
  -v /backup:/dest \
  alpine tar czf /dest/portainer_data_$(date +%Y%m%d).tar.gz -C /source .

Updating Portainer Without Losing Data

Since you installed via Compose and data is stored in a named volume, updates are completely safe:

cd /opt/portainer
docker compose pull
docker compose up -d

Configuring a Reverse Proxy with Nginx for Production

Already have Nginx on the server? You should put Portainer behind a reverse proxy to use real HTTPS instead of a self-signed certificate:

server {
    listen 443 ssl;
    server_name portainer.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/portainer.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/portainer.yourdomain.com/privkey.pem;

    location / {
        proxy_pass https://localhost:9443;
        proxy_ssl_verify off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Then remove the ports section from compose.yml — port 9443 will no longer be exposed externally, and only Nginx internally can connect to it.

When You Shouldn’t Use Portainer

Portainer isn’t the answer to everything. A few cases worth thinking carefully about:

  • Automated CI/CD environments: Deployment pipelines don’t need a UI — using CLI or the Docker API directly is simpler and has fewer dependencies.
  • Servers with strict security requirements: Mounting /var/run/docker.sock into the Portainer container means Portainer has root-level access to the host. Strict production environments should use Portainer Agent instead of direct socket mounting.
  • Kubernetes clusters: Portainer supports K8s, but Lens or k9s are better suited for pure Kubernetes environments.

For a personal VPS or a small team running standalone Docker, Portainer is the best tool worth installing. Invest an afternoon setting it up and you’ll never have to type long commands every day again — that’s a pretty good deal in my book.

Share: