Skip to main content
Docker & Infrastructure

How to Install Portainer on Docker: Ubuntu Setup + Compose

· · 8 min read

I spent two years running Docker containers from the command line before I got tired of memorizing container IDs and digging through logs. Then I set up Portainer, which is just a web UI that talks to Docker, and stopped thinking about this problem. If you’re managing more than a handful of containers, installing Portainer on Docker will save you time and make debugging less tedious. This guide walks through the install, first-run setup, and the parts that usually trip people up.

🎯 Not sure if this will run on your hardware?Use our free Local LLM Hardware Checker — pick your GPU and RAM, see which models will run with real tokens/sec estimates.
Check my hardware →

The Problem With Managing Docker the Hard Way

When you’re running a few containers—maybe Jellyfin, an Ollama instance, and a reverse proxy—the CLI is fine. You know the names. You know what to look for when something breaks. But once you add a second node, or start running a dozen services, or just want to check container stats without SSH-ing into the box, the command line becomes friction. You’re grepping logs. You’re running docker ps fifty times a day. You’re forgetting which image version is running where.

Portainer solves this by giving you a single dashboard. You can see all your containers, their resource usage, their logs, and their config in one place. You can restart a container from the browser. You can pull a new image, update an environment variable, and deploy without touching SSH. For a homelab where you’re often working on multiple machines at once, that matters.

The other thing Portainer does well is make Docker Compose less scary. If you’re new to containers, Compose files can feel like magic incantations. Portainer’s stack interface (which is just Compose under the hood) shows you what you’re deploying before you hit go. That’s worth the setup time alone.

Prerequisites and Hardware

You need Docker already running. If it’s not, install it first with curl https://get.docker.com | sh on Ubuntu, then add your user to the docker group with sudo usermod -aG docker $USER. You’ll need to log out and back in for that to take effect.

For hardware: Portainer itself is lightweight. It’ll run fine on a 2-core machine with 1GB of RAM. But if you’re managing more than three or four containers, 2GB is more comfortable. If you’re also running the containers on the same machine—which is the typical homelab setup—budget CPU and memory for both Portainer and your actual workloads. The UI is responsive but not zero-cost.

You’ll need a host with a static IP or DHCP reservation. Portainer doesn’t move around, and you’ll want to bookmark it. Port 9000 is the default web UI. Port 8000 is optional and handles the edge agent communication if you add remote nodes later. If both are already in use, you can change them, but don’t unless you have to.

Installation: Portainer Container and Docker Compose

There are two reasonable ways to run Portainer. The first is a standalone container. The second is Docker Compose. I’ll show both, but use Compose if you ever rebuild this machine—it’s easier to recover from.

Standalone container:

docker run -d n  --name portainer n  --restart always n  -p 9000:9000 n  -p 8000:8000 n  -v /var/run/docker.sock:/var/run/docker.sock n  -v portainer_data:/data n  portainer/portainer-ce:latest

That’s it. The --restart always means Portainer survives a reboot. The volume mount at /var/run/docker.sock is how Portainer talks to Docker—that’s the API socket. The named volume portainer_data stores its database.

Docker Compose approach:

version: '3.9'

services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: always
    ports:
      - "9000:9000"
      - "8000:8000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    environment:
      - TZ=UTC

volumes:
  portainer_data:

Save that to a file called docker-compose.yml, then run docker-compose up -d. Both approaches work identically once running.

Wait about 10 seconds for Portainer to boot. It’s usually fast, but if you’re on an older drive or a Raspberry Pi, it can take 15-20 seconds. You’ll know it’s ready when you can hit http://localhost:9000 and see the setup screen instead of a connection refused error.

First-Run Configuration

Open a browser and go to http://YOUR_IP:9000. You’ll see a setup screen asking for an admin password. Make it strong. This is the key to your Docker infrastructure. You’re not overthinking it—use a password manager and generate something 16+ characters.

Next, it asks which environment you want to manage. By default it detects the local Docker socket and offers “Docker” and “Docker Standalone”. Leave it on Docker Standalone. This is the local machine’s Docker daemon. If you add a second node later, you’ll come back here, but for now, just select it and continue.

After that, you’re in the dashboard. It’s empty because you don’t have any containers yet, or Portainer hasn’t recognized your existing ones. Go to the Containers menu on the left. If you have running containers, they should appear within a few seconds. If they don’t, and you know Docker is running stuff, there’s usually a permissions issue—see the gotchas section below.

Before you do anything else, set a strong password for the edge agent. This is optional but worth doing if you ever plan to add remote nodes. Go to Settings in the left menu, then Edge Compute, and set the key. It’s at the bottom of the page and easy to miss.

Common Gotchas and Fixes

Portainer can’t see Docker containers. This almost always means the docker.sock mount isn’t working. Check that Portainer is running: docker ps | grep portainer. If it is, exec into it and try ls -la /var/run/docker.sock. If that file doesn’t exist inside the container, Docker isn’t mounted. Stop the container, check that /var/run/docker.sock exists on the host (ls -la /var/run/docker.sock), then recreate Portainer. If you’re on a system where Docker runs as a socket at a different location (some Linux distros), you may need to adjust the mount path.

Can’t access Portainer from another machine. The default setup binds to 127.0.0.1:9000 on some systems. If you can hit it from localhost but not from another machine, the port is probably not listening on your network interface. Check with sudo netstat -tlnp | grep 9000. If it shows 127.0.0.1:9000, you need to modify the port binding. Edit your docker-compose.yml and change the port line to - "0.0.0.0:9000:9000", then run docker-compose up -d again. If you’re using the standalone container command, add -p 0.0.0.0:9000:9000 instead of just -p 9000:9000.

Dashboard is slow or unresponsive. This usually means Portainer is under resource pressure. Check its logs: docker logs portainer. If you see memory warnings, you’re probably running a lot of containers or have a small machine. Portainer’s UI should still work, but stats updates might lag. This is rarely a blocker—it’s just useful to know. If it’s truly unusable, increase the container’s memory limit by adding -m 512m to the docker run command or this to the compose file: mem_limit: 512m.

Password reset. If you forget the admin password, you can’t self-service reset it easily. You have to nuke the Portainer data volume and start over: docker stop portainer && docker rm portainer && docker volume rm portainer_data, then recreate it. Write down your password or use a password manager’s backup feature. I learned this the hard way and now keep it in Bitwarden.

What to Do Next

Once Portainer is running and you can see your containers, you have a few natural next steps. The first is to deploy something new using a stack (Compose file). Go to Stacks, paste in a docker-compose.yml for something like Jellyfin or a database, and let Portainer handle the deploy. This teaches you how the UI maps to Compose syntax.

The second is to set up SSL. By default Portainer runs over HTTP, which is fine in a home network but sloppy if you’re exposing it to the internet. You can add a reverse proxy in front of it, or configure Portainer itself to use HTTPS. The reverse proxy approach (nginx, Caddy, or Traefik) is more flexible and I’d do that if you’re managing multiple services. Check Portainer’s docs for the HTTPS setup if you want to go direct.

Third, if you’re running multiple machines, add remote nodes. This is where Portainer really pays off. You can manage Docker on your main server, a Raspberry Pi running edge services, and a backup box from the same dashboard. That feature alone justifies learning the tool.

One thing I should mention: Portainer is good, but it’s not a replacement for understanding Docker. If something breaks, you’re going to end up in the terminal eventually. The UI makes the common tasks frictionless, but when you’re debugging a network issue or a volume permission problem, you still need to know what’s happening at the command line. Think of Portainer as the pleasant layer on top, not as the whole thing.

FAQ

Can Portainer run on a Raspberry Pi?

Yes. Portainer is lightweight enough for a Pi 4 or newer. A Pi Zero or Pi 3 will work but may feel sluggish, especially if you’re managing a lot of containers on the same machine. Use the ARM-compatible image—it should auto-detect, but if not, specify portainer/portainer-ce:latest-arm.

How much RAM does Portainer need?

About 100-150MB idle, depending on how many containers you’re monitoring. If you’re viewing live stats for 20+ containers, expect 300MB. It won’t ask for more unless you tell it to. A 512MB limit is safe for most homelabs.

Do I need Portainer for a small homelab?

Not strictly. If you have two or three containers and you’re comfortable with Docker CLI, you don’t need it. But past that point—or if you want to lower the barrier to restarting services or viewing logs—it pays for itself in time saved.

Is Portainer secure enough for remote access?

The free Community Edition has basic auth only. For remote access, you should put it behind a reverse proxy with SSL and ideally authentication (Authelia, Nginx auth, etc.). Don’t expose the raw Portainer port to the internet. The commercial Business Edition has LDAP and RBAC, but for a homelab, the proxy approach is fine.

What’s the difference between Portainer Community Edition and Business Edition?

Community is free and handles local and remote Docker management fine. Business adds RBAC, team management, image scanning, and support. For a solo homelab, Community is all you need. You hit the edge case where Business matters only if you’re managing Docker across a team.

Explore Portainer in our AI Homelab Toolkit.

Share this article