What this lab does
Portainer answers a simple question: what is actually running on this Docker host, and how do I change it without a shell? In this lab you create the working directory ~/docker/portainer, write a complete compose.yaml, check it with docker compose config -q before anything starts, and bring the stack up with docker compose up -d. docker compose ps then confirms the container is up and listening on 0.0.0.0:9443, and only after that do you open https://<IP>:9443 to create the admin account with a password of 12 characters or more, on a form that expires five minutes after the container starts. The written walkthrough is our guide to installing Portainer with Docker Compose.
Reading the compose.yaml line by line
The file follows the current Compose Specification described in the official Docker Compose documentation: there is no version: key, because Compose v2 ignores it. The image is pinned to portainer/portainer-ce:2.40.0 instead of :latest, so rebuilding this stack in six months gives you the same software you tested today. security_opt: no-new-privileges:true narrows what the container may do, restart: unless-stopped brings it back after a host reboot, and the named portainer_data volume keeps users and settings outside the container so they survive an upgrade. Two ports are published: 9443 for the HTTPS UI and 8000 for the Edge Agent tunnel. The Docker socket goes in read-only (:ro), since Portainer drives everything through the API.
Where it fits in a self-hosted stack
Portainer is the control panel; it does not replace the pieces underneath it, it makes them visible. If you also need to publish those containers under real hostnames, our Traefik reverse proxy lab handles the routing, and Portainer gives you a browser view of the containers Traefik is routing to. The UI is published on the host’s own port 9443 here, so on an internet-facing server restrict who can reach that address. The official Portainer documentation covers what comes next: agents, remote environments and upgrades. The rest of our reproducible walkthroughs live in the hands-on labs.
FAQ
What is Portainer?
Portainer is a web interface for managing Docker environments: containers, images, volumes and networks. It runs as a container itself — here from the portainer/portainer-ce:2.40.0 image — and talks to the daemon through the /var/run/docker.sock socket mounted into it by the compose file. Its interface is served over HTTPS on port 9443 of the host.
What is port 8000 for?
Port 8000 is the Edge Agent tunnel. Portainer listens there for agents running on other machines, so a single interface can manage several remote Docker environments. This lab only manages the local daemon through the mounted socket, so if remote hosts are not on your roadmap you can drop that mapping and publish 9443 alone.
What happens if the admin setup form expires?
Portainer disables the initial admin form five minutes after the container starts, so an instance left running on a network cannot be claimed by whoever reaches it first. If you miss the window, restart the container from the stack directory with docker compose restart and reload https://IP:9443: the form comes back and you can create your administrator account.
Why validate with docker compose config before starting anything?
Because config parses compose.yaml and fails on a bad indent or an invalid key without creating a single container, volume or network. The -q flag silences the output on success, which is why the lab chains it to an echo that prints compose.yaml OK. Catching a typo there costs a second; catching it during up -d means cleaning up half-created resources.