Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Portainer Ubuntu
GUIDEInstall Guides

How to Install Portainer CE on Ubuntu 24.04 — Self-Host a Docker Management UI

25 min read

How to Install Portainer CE on Ubuntu 24.04 — Self-Host a Docker Management UI

Running containers on a single VPS is easy until you have ten of them, three Compose stacks, two private registries, and a teammate asking which one is leaking memory. Portainer Community Edition turns that noise into a single, clean web interface. This tutorial walks through installing Portainer CE on Ubuntu 24.04 from a fresh server, through TLS, environments, stacks, templates, registries, RBAC, an optional Nginx reverse proxy, and backups.

Looking for a cheap, reliable home for Portainer? Our Starter VPS plan includes 2 vCPU, 4 GB RAM, and 50 GB NVMe for EUR 7.99/month — plenty of room for Portainer itself plus 10-20 application containers.

Table of Contents

  • What is Portainer?
  • Why Self-Host a Docker Management UI?
  • Prerequisites
  • Step 1: Update System Packages
  • Step 2: Install Docker Engine
  • Step 3: Create the Portainer Volume
  • Step 4: Deploy Portainer CE
  • Step 5: Create the First Admin User
  • Step 6: Configure the TLS Certificate
  • Step 7: Add Environments (Docker, Edge, Kubernetes)
  • Step 8: Deploy Your First Stack
  • Step 9: Use App Templates
  • Step 10: Connect Registries
  • Step 11: Set Up Teams and RBAC
  • Step 12: Optional — Nginx Reverse Proxy with Certbot
  • Step 13: Backup and Restore
  • Troubleshooting
  • FAQ
  • Next Steps
  • What is Portainer?

    Portainer is a lightweight, container-based management UI for Docker, Docker Swarm, and Kubernetes. It runs as a single container on your host and connects to the local Docker socket (and optionally to remote environments via agents), giving you a browser-based alternative to the docker CLI. The Community Edition (CE) is free and open source; a paid Business Edition adds SSO, registry scanning, and advanced RBAC.

    Portainer understands three primary object types: environments (the hosts or clusters it manages), stacks (Docker Compose or Swarm deployments), and containers (individual workloads). On top of those, it adds app templates for one-click deployments, registries for private image sources, teams for role-based access, and a volumes / networks / images browser that maps directly onto Docker primitives. Once you have it running, most day-to-day tasks — restarting a container, tailing logs, editing environment variables, redeploying a stack — happen in two or three clicks.

    The platform supports a broad set of back ends. At the Docker layer you can manage a standalone Docker Engine, a Docker Swarm cluster, or Docker-in-Docker CI runners. For orchestration at scale, Portainer connects to Kubernetes clusters — vanilla, K3s, RKE2, or cloud-managed — and renders manifests, Helm charts, and resource quotas in the same UI. Edge agents let you manage IoT fleets and branch-office hosts behind NAT without opening inbound ports. And because everything Portainer does is just Docker API calls under the hood, anything you can configure in the UI you can also configure via docker-compose.yml, manifests, or the Portainer REST API.

    Why Self-Host a Docker Management UI?

    The Docker CLI is perfectly fine for a single developer on a single host. The moment you have more than that, the trade-offs shift:

    • Visibility across the whole fleet -- docker ps shows you one host at a time. Portainer shows every container across every environment in one list, with CPU and memory sparklines, restart counts, and health-check status.
    • Faster incident response -- When a service goes sideways at 2 AM, tailing logs, exec-ing into a container, and redeploying a stack from a phone browser is faster than SSH + CLI on a flaky connection.
    • Safer delegation -- Giving a junior engineer or a support rep shell access to production is a big blast radius. Giving them "Read-only on the staging environment, deploy-only on the apps team's stacks" is a small one. RBAC in Portainer maps cleanly to team structures.
    • Fewer transcription errors -- A Compose file pasted into the Stacks editor is harder to typo than a long CLI command with a dozen -e flags. Portainer validates the YAML before deploying.
    • Auditability -- Portainer logs who did what. The CLI logs nothing by default. For SOC 2 and ISO 27001 environments, that audit trail matters.
    • Uniform workflow across Docker, Swarm, and Kubernetes -- Teams often run a mix. Instead of learning three CLIs, the same UI manages all of them.
    • No per-seat SaaS fees -- Portainer CE is free forever. Hosted alternatives (AWS Copilot console, GCP Cloud Run UI, various SaaS Docker dashboards) charge per user or per host, or lock you into their cloud.

    When the CLI is still the right tool

    Portainer is additive, not a replacement. Shell scripts, CI/CD pipelines, docker compose in a Git repo, and one-off debugging are still CLI territory. The UI shines for interactive, cross-host, multi-person work. Most serious Docker shops end up using both.

    Prerequisites

    Before you begin, make sure you have:

    • A VPS running Ubuntu 24.04 LTS with root or sudo access
    • SSH access to your server
    • At least 2 GB of RAM (Portainer itself needs ~100 MB; the rest is for Docker and your workloads)
    • At least 20 GB of free disk space for images, volumes, and Portainer data
    • Open ports 9443 (HTTPS UI) and 8000 (Edge agent tunnel) — or port 443 if you plan to front it with Nginx
    • A domain name pointed at your server (only required for the optional Certbot section)
    Recommended Plan: Starter VPS
    >
    For a production-grade Portainer install that can manage itself plus 10-20 application containers, we recommend our Starter plan:
    >
    - 2 vCPU cores
    - 4 GB RAM
    - 50 GB NVMe SSD
    - Unmetered bandwidth
    - EUR 7.99/month
    >
    Scale up to larger plans when your container count grows or when Portainer starts managing remote environments.

    Connect to your server via SSH:

    bash
    ssh root@your-server-ip

    Step 1: Update System Packages

    Start by bringing the package index and installed packages up to date. Fresh images often lag a few weeks behind on security patches.

    bash
    sudo apt update && sudo apt upgrade -y

    Expected output (abbreviated):

    text
    Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
    Reading package lists... Done
    Calculating upgrade... Done
    0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

    If a new kernel was installed, reboot before continuing:

    bash
    sudo reboot

    Then reconnect via SSH after about a minute.

    Step 2: Install Docker Engine

    Portainer needs Docker to run. Ubuntu's docker.io package works but tends to trail the upstream release by months, so install Docker CE from the official repository instead. This is the same procedure covered in our dedicated Docker install guide.

    Install prerequisite packages:

    bash
    sudo apt install -y ca-certificates curl gnupg

    Add Docker's official GPG key:

    bash
    sudo install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
      sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    sudo chmod a+r /etc/apt/keyrings/docker.gpg

    Add the Docker repository:

    bash
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
      https://download.docker.com/linux/ubuntu \
      $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
      sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    Update the index and install Docker Engine plus the Compose plugin:

    bash
    sudo apt update
    sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

    Verify Docker is running:

    bash
    sudo systemctl status docker --no-pager

    Expected output:

    text
    ● docker.service - Docker Application Container Engine
         Loaded: loaded (/lib/systemd/system/docker.service; enabled; preset: enabled)
         Active: active (running) since Thu 2026-04-16 10:00:00 UTC; 10s ago

    Run the Docker hello-world container to confirm end-to-end functionality:

    bash
    sudo docker run --rm hello-world

    Step 3: Create the Portainer Volume

    Portainer stores its database, user accounts, settings, and SSL certificates in /data inside the container. We persist that directory to a named Docker volume so everything survives container upgrades and restarts.

    bash
    sudo docker volume create portainer_data

    Expected output:

    text
    portainer_data

    Confirm the volume exists:

    bash
    sudo docker volume inspect portainer_data

    Expected output (abbreviated):

    json
    [
        {
            "Name": "portainer_data",
            "Driver": "local",
            "Mountpoint": "/var/lib/docker/volumes/portainer_data/_data",
            "CreatedAt": "2026-04-16T10:00:00Z"
        }
    ]

    The real files live at /var/lib/docker/volumes/portainer_data/_data on the host — remember that path for backups.

    Step 4: Deploy Portainer CE

    Now deploy the Portainer CE container. It exposes two ports:

    • 9443 — the HTTPS web UI (self-signed cert by default)
    • 8000 — the TCP tunnel used by Edge agents to phone home
    bash
    sudo docker run -d \
      --name portainer \
      --restart=always \
      -p 8000:8000 \
      -p 9443:9443 \
      -v /var/run/docker.sock:/var/run/docker.sock \
      -v portainer_data:/data \
      portainer/portainer-ce:latest

    Expected output:

    text
    Unable to find image 'portainer/portainer-ce:latest' locally
    latest: Pulling from portainer/portainer-ce
    a1b2c3d4e5f6: Pull complete
    ...
    Status: Downloaded newer image for portainer/portainer-ce:latest
    3f4a2b9c1d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a

    Flag-by-flag explanation:

    • -d runs the container in the background (detached).
    • --name portainer pins a human-readable name so you can reference it with docker logs portainer, docker restart portainer, etc.
    • --restart=always tells Docker to restart the container automatically on reboot or crash.
    • -p 8000:8000 maps the Edge agent tunnel port.
    • -p 9443:9443 maps the HTTPS UI port.
    • -v /var/run/docker.sock:/var/run/docker.sock mounts the host Docker socket into the container, letting Portainer manage the local Docker daemon.
    • -v portainer_data:/data persists Portainer's state in the named volume we just created.
    Verify the container is running:

    bash
    sudo docker ps

    Expected output:

    text
    CONTAINER ID   IMAGE                          COMMAND        STATUS         PORTS                                  NAMES
    3f4a2b9c1d8e   portainer/portainer-ce:latest  "/portainer"   Up 10 seconds  0.0.0.0:8000->8000/tcp, 9443/tcp      portainer

    Open UFW for the UI port if a firewall is enabled:

    bash
    sudo ufw allow 9443/tcp
    sudo ufw allow 8000/tcp

    Step 5: Create the First Admin User

    Open a browser and navigate to:

    text
    https://your-server-ip:9443

    Because Portainer is using a self-signed TLS certificate by default, your browser will warn about the connection. For the initial setup this is expected — click through the warning (in Chrome: "Advanced" then "Proceed to ...").

    You have five minutes from the container's first start to create the initial admin user. If you wait longer, Portainer locks itself for security and you must restart the container to open the window again:

    bash
    sudo docker restart portainer

    On the setup screen:

  • Enter a username (default suggestion: admin).
  • Enter a password of at least 12 characters. Portainer enforces complexity rules.
  • Confirm the password.
  • Decide whether to opt in to anonymous usage statistics (optional).
  • Click Create user.
  • You will land on the home dashboard. The local Docker environment is auto-connected because we mounted the Docker socket — you should see one environment tile labelled local with a green "up" indicator.

    Step 6: Configure the TLS Certificate

    Portainer's built-in HTTPS listener uses a self-signed certificate generated on first start. That is fine for a private install, but browsers will keep complaining. You have three options for a trusted certificate:

  • Bring your own cert — Upload a fullchain and key in Settings → SSL certificate. Useful if you already have a wildcard cert from Let's Encrypt or a commercial CA.
  • Let Portainer manage it — Not available in CE for the built-in listener; this is a Business Edition feature.
  • Put a reverse proxy in front — Run Nginx or Traefik with Certbot and let them handle TLS, while Portainer listens on HTTP internally. We cover this in Step 12.
  • For option 1, navigate to Settings → SSL certificate, upload fullchain.pem and privkey.pem, and click Apply. Portainer reloads the listener without restarting the container.

    Step 7: Add Environments (Docker, Edge, Kubernetes)

    An environment in Portainer is any Docker host, Swarm cluster, or Kubernetes cluster it can manage. The local Docker daemon is already connected. Here is how to add more.

    Local Docker (already connected)

    The Docker socket mount in Step 4 auto-registered the host as the local environment. No further action needed. Click into it to manage containers, images, volumes, and networks on this server.

    Remote Docker host via Edge Agent

    Edge agents are the recommended way to add remote hosts, especially when they sit behind NAT, a dynamic IP, or a restrictive firewall. The agent makes an outbound connection to port 8000 on the Portainer server — you do not need to open any inbound port on the remote host.

    In Portainer:

  • Go to Environments → Add environment.
  • Choose Docker Standalone → Edge Agent Standard.
  • Give it a name (e.g. edge-london-01).
  • Set the Portainer server URL to https://your-portainer-host:9443.
  • Click Create — Portainer shows you a one-line docker run command.
  • On the remote host, install Docker and run the command Portainer gave you. Within a few seconds the environment will show as "Up" in the Portainer UI.

    Kubernetes cluster

    Portainer can manage Kubernetes clusters, rendering workloads, services, ingresses, config maps, and Helm charts in the UI. This is a popular middle ground for teams who find Rancher too heavy but still want a GUI over kubectl.

  • Go to Environments → Add environment.
  • Choose Kubernetes → Agent.
  • Apply the manifest Portainer provides to your cluster with kubectl apply -f.
  • Portainer auto-discovers the cluster once the agent is running.
  • For K3s, RKE2, and most managed offerings, the agent manifest works unchanged. For stricter clusters, you may need to adjust the ClusterRoleBinding to match your RBAC policies.

    Step 8: Deploy Your First Stack

    A stack in Portainer is a Docker Compose deployment. You can write the YAML directly in the web editor, point Portainer at a Git repo, or upload a file. Compare this workflow to the equivalent raw CLI flow covered in our docker-compose tutorial.

    Let's deploy a simple Nginx + Redis stack:

  • In the local environment, go to Stacks → Add stack.
  • Name it web-demo.
  • Paste the following Compose YAML into the Web editor:
  • yaml
    version: "3.8"

    services: web: image: nginx:alpine ports: - "8080:80" restart: unless-stopped

    cache: image: redis:7-alpine restart: unless-stopped volumes: - redis_data:/data

    volumes: redis_data:

  • Scroll down and click Deploy the stack.
  • Portainer parses the YAML, pulls the images, creates the network, and starts the containers. After 10-30 seconds the stack page shows both services with green status dots. Visit http://your-server-ip:8080 to see the Nginx welcome page.

    You can now Edit the stack to change the YAML and redeploy, Stop it to halt all services, or Delete it to remove everything including volumes (optional checkbox).

    For production, prefer the Repository tab instead of pasting YAML — point it at a Git URL and enable Automatic updates (polling) so Portainer redeploys on every push.

    Step 9: Use App Templates

    App templates are one-click deployment recipes. Portainer ships with ~30 community templates (WordPress, GitLab, Plex, Home Assistant, etc.) and you can add your own catalogue.

  • Navigate to App Templates → Applications.
  • Browse or search for what you want, for example "WordPress".
  • Click the template, fill in the parameters (MySQL password, site title, port).
  • Click Deploy.
  • Under the hood, a template is a Compose stack with a form schema attached. The template spec is just a JSON file, so you can fork the official templates repo, add your own entries, and point Portainer at your custom URL under Settings → App Templates → URL. This is how internal platform teams expose a curated catalogue to developers — a "paved road" of approved stacks, with sane defaults baked in.

    Step 10: Connect Registries

    By default Portainer can pull from Docker Hub anonymously. For private images you need to register credentials.

    Go to Registries → Add registry. Choose the registry type:

    • Docker Hub (authenticated) — Needed for private repos or to bypass Docker Hub's anonymous pull rate limits. Supply your Docker ID and a Personal Access Token.
    • GitHub Container Registry (ghcr.io) — Use a GitHub PAT with read:packages scope.
    • GitLab Container Registry — Use a project or group deploy token.
    • AWS ECR, Google Artifact Registry, Azure Container Registry — Supply the region and credentials; Portainer handles token rotation for AWS.
    • Custom / generic — Any registry that speaks the Docker Registry v2 API (Harbor, Nexus, self-hosted Distribution, etc.).
    Once a registry is added, Portainer routes pulls for any image prefixed with that registry's host through the stored credentials. Your Compose files and manifests stay clean — no embedded passwords.

    Step 11: Set Up Teams and RBAC

    Portainer CE ships with team-based role-based access control. The concept is simple: users belong to teams, teams are granted roles on environments and resources.

  • Go to Users → Add user. Create an account for each teammate (or enable OAuth under Settings → Authentication to delegate to Google/GitHub/OIDC).
  • Go to Teams → Add team. Example teams: platform, apps, support.
  • Assign users to teams via Teams → Members.
  • Grant access per environment under Environments → [name] → Manage access.
  • The built-in roles are:

    RoleCan
    Environment AdministratorEverything in the environment — deploy stacks, manage users, change settings.
    HelpdeskRead containers, view logs, inspect resources. Cannot modify anything.
    Standard UserCreate/manage resources they own (containers, stacks, volumes, networks).
    Read-only UserView everything, modify nothing.
    For finer-grained control (per-stack, per-resource), upgrade to Portainer Business. For most small-to-medium teams the four CE roles plus careful environment segmentation are plenty.

    Security tip: Disable the default admin account once you have individual user accounts for every teammate. Shared credentials make audit trails useless.

    Step 12: Optional — Nginx Reverse Proxy with Certbot

    For a polished setup, run Portainer behind Nginx and let Certbot handle TLS. This gives you a clean https://portainer.yourdomain.com URL with a trusted certificate and frees you from Portainer's self-signed quirks.

    Switch Portainer to plain HTTP first. Stop and replace the container:

    bash
    sudo docker stop portainer
    sudo docker rm portainer

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

    The key changes: we dropped -p 9443:9443, added -p 127.0.0.1:9000:9000 (HTTP, bound to localhost only so nothing external can reach it), and kept the Edge tunnel on 8000.

    Install Nginx and Certbot:

    bash
    sudo apt install -y nginx certbot python3-certbot-nginx

    Create the Nginx config:

    bash
    sudo tee /etc/nginx/sites-available/portainer > /dev/null <<'EOF'
    server {
        listen 80;
        server_name portainer.yourdomain.com;

    location / { proxy_pass http://127.0.0.1:9000; 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;

    # WebSocket support for container consoles proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";

    # Long timeouts for log streaming and exec sessions proxy_read_timeout 3600s; proxy_send_timeout 3600s; client_max_body_size 100m; } } EOF

    sudo ln -s /etc/nginx/sites-available/portainer /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx

    Point portainer.yourdomain.com at your server's IP via your DNS provider, then issue the certificate:

    bash
    sudo certbot --nginx -d portainer.yourdomain.com

    Certbot edits the Nginx config to redirect HTTP to HTTPS and adds cert paths. Certbot's systemd timer renews the certificate automatically every 60 days.

    You can now access Portainer at https://portainer.yourdomain.com with a trusted certificate. Close the firewall on port 9443 since nothing uses it any more:

    bash
    sudo ufw delete allow 9443/tcp

    Step 13: Backup and Restore

    Portainer's entire state — users, environments, stacks, registries, settings — lives in the portainer_data volume. Backing it up is a one-line rsync or a tarball.

    Option A: Built-in UI backup

    Portainer itself can export a password-encrypted backup archive. Go to Settings → Backup Portainer, set a password, click Download backup. Save the resulting .tar.gz somewhere off-server (S3, Backblaze B2, etc.). Restore by uploading the same file on a fresh Portainer install before creating the first admin user.

    Option B: Volume-level backup (scripted)

    For automated offsite backups, tar the volume while the container is stopped:

    bash
    sudo docker stop portainer

    sudo tar -czf /backup/portainer-$(date +%F).tar.gz \ -C /var/lib/docker/volumes/portainer_data _data

    sudo docker start portainer

    Wrap that in a cron job:

    bash
    sudo crontab -e

    Add:

    text
    0 3   * docker stop portainer && tar -czf /backup/portainer-$(date +\%F).tar.gz -C /var/lib/docker/volumes/portainer_data _data && docker start portainer

    This snapshots at 03:00 daily. Pair it with a restic or rclone job that copies /backup/ to offsite storage and you have a 3-2-1 setup with about two minutes of nightly downtime.

    Restore

    Stop the container, wipe the volume, extract the backup, start again:

    bash
    sudo docker stop portainer
    sudo rm -rf /var/lib/docker/volumes/portainer_data/_data/*
    sudo tar -xzf /backup/portainer-2026-04-16.tar.gz \
      -C /var/lib/docker/volumes/portainer_data/
    sudo docker start portainer

    Troubleshooting

    ProblemCauseSolution
    Your Portainer instance timed out for security purposes on first loginMore than 5 minutes elapsed between container start and first loginRun sudo docker restart portainer, then reload the UI and create the admin within 5 minutes.
    Browser shows ERR_CERT_AUTHORITY_INVALIDDefault self-signed TLS certificateExpected. Proceed through the warning, upload a real cert, or follow Step 12.
    Cannot connect to the local Docker environmentMissing or wrong socket mountVerify -v /var/run/docker.sock:/var/run/docker.sock in the docker run command. Check ls -l /var/run/docker.sock shows socket is readable.
    Edge agent stays DownOutbound 8000 blocked on remote host, or wrong Portainer URLTest curl -v https://your-portainer-host:9443 from the edge host. Check firewall rules. Confirm the URL entered during environment creation matches reality.
    Stack deploy fails with version is obsolete warningCompose v2 ignores the top-level version keyHarmless warning; remove the version: line to clean up.
    Container console closes immediately after openingReverse proxy dropping WebSocketEnsure proxy_http_version 1.1 and Upgrade/Connection headers are set (see Nginx config in Step 12).
    Portainer uses excessive CPUVery large container/image count being listed repeatedlySet longer refresh intervals in Settings → General → Dashboard refresh or split workloads into multiple environments.

    Viewing Logs

    Tail the Portainer container logs to debug UI errors and API issues:

    bash
    sudo docker logs -f portainer

    Check the last 100 lines without following:

    bash
    sudo docker logs --tail 100 portainer

    FAQ

    Is Portainer CE really free for commercial use?

    Yes. Portainer Community Edition is released under the zlib/libpng licence and is free for personal and commercial use, with no host count or user limits. The paid Business Edition adds features like registry scanning, RBAC at the resource level, SSO with SAML, and commercial support. For most self-hosted and small-to-medium commercial deployments, CE is fully sufficient.

    How does Portainer compare to Rancher?

    Portainer and Rancher both offer web UIs for container orchestration, but they target different audiences. Portainer is deliberately lightweight — one container, simple install, works across Docker, Swarm, and Kubernetes with the same UI. Rancher is a full Kubernetes-first platform with cluster provisioning, continuous delivery (Fleet), and service mesh integration, and it scales to managing thousands of downstream clusters. Rule of thumb: if your primary surface is Docker or Swarm, choose Portainer. If you are standing up multiple Kubernetes clusters and want cluster lifecycle automation, choose Rancher.

    Can I use Portainer without exposing it to the public internet?

    Absolutely, and this is the most secure configuration. Bind the UI to 127.0.0.1 only (as shown in Step 12), then access it via SSH tunnel:

    bash
    ssh -L 9443:127.0.0.1:9443 user@your-server

    Then open https://localhost:9443 on your laptop. No inbound ports, no reverse proxy, no certificate hassle. The trade-off is that Edge agents still need outbound access to port 8000 if you use them.

    How much memory does Portainer itself consume?

    The portainer-ce container idles at around 80-120 MB of RAM and uses negligible CPU outside of active UI sessions. On a 4 GB VPS you will barely notice it — the containers it manages are what eats memory, not Portainer. Heavy operations like rendering a 500-container list or streaming hundreds of megabytes of logs can spike usage temporarily; increase the container memory limit if you see OOM events in docker logs portainer.

    Can Portainer deploy containers from a Git repository automatically?

    Yes. When creating a stack, choose the Repository source instead of the Web editor. Point it at a Git URL, select the Compose file path, and enable Automatic updates with a polling interval (default 5 minutes). Portainer checks the branch, and redeploys the stack whenever the file changes. This gives you a lightweight GitOps workflow without needing Argo CD or Flux. Supports Git over HTTPS with token auth or SSH keys.

    What is the difference between Portainer's Docker socket mount and socket proxy?

    Mounting /var/run/docker.sock directly (what we did in Step 4) gives Portainer full control over the Docker daemon — effectively root on the host. That is fine when Portainer itself is the only thing talking to Docker and you trust its admin users. For stricter setups, put a socket proxy (such as tecnativa/docker-socket-proxy) between Portainer and the real socket, exposing only the specific Docker API endpoints Portainer needs. This reduces blast radius if Portainer is ever compromised. It is overkill for a single-admin install but worth considering in shared environments.

    How do I upgrade Portainer to a new version?

    Pull the new image, stop the current container, and recreate it with the same flags. Because the portainer_data volume is external, all state survives:

    bash
    sudo docker pull portainer/portainer-ce:latest
    sudo docker stop portainer
    sudo docker rm portainer
    

    Re-run the docker run command from Step 4

    Watchtower or Diun can automate this, or you can pin to specific version tags (e.g. portainer/portainer-ce:2.21.4) and upgrade on your schedule. Official release notes live at docs.portainer.io.

    Next Steps

    Now that Portainer is running and managing your containers, here are recommended directions to take the setup further:

    • Automate with the Portainer API — Every UI action maps to a REST endpoint. Generate an access token under My account → Access tokens and drive stack deploys from CI. The docs at docs.portainer.io list every endpoint.
    • Add a second environment — Provision a second VPS, install Docker, and connect it via Edge agent. Portainer scales to hundreds of environments with minimal overhead.
    • Install Kubernetes — Spin up a lightweight Kubernetes cluster (K3s is great for a single-VPS start) and manage it alongside your Docker hosts in the same Portainer UI.
    • Set up monitoring — Deploy Prometheus + Grafana via an app template and scrape cAdvisor for container metrics. Pipe alerts into Slack, Discord, or email.
    • Use Git-backed stacks — Move all your Compose files into a Git repo and let Portainer auto-deploy on every commit. This turns Portainer into a simple GitOps platform without extra tooling.
    • Harden with a socket proxy — Add tecnativa/docker-socket-proxy between Portainer and the Docker socket to restrict the blast radius of a compromised admin account.

    Prefer a One-Click Deploy?
    >
    We are working on a Portainer-pre-installed VPS image that includes Docker Engine, Portainer CE with Let's Encrypt TLS, UFW hardened, and automatic daily backups to offsite storage.
    >
    In the meantime, the Starter VPS gives you the ideal baseline for this tutorial at EUR 7.99/month — 2 vCPU, 4 GB RAM, 50 GB NVMe, unmetered bandwidth.
    >
    Deploy a Starter VPS now and have Portainer running in 20 minutes.

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket