# How to install Portainer on a Linux VPS

**URL:** <https://forum.boxtoplay.com/t/how-to-install-portainer-on-a-linux-vps/31868>\
**Category:** VPS\
**Tags:** english, vps\
**Created:** [Août 27, 2026, 3:35 UTC](https://forum.boxtoplay.com/t/how-to-install-portainer-on-a-linux-vps/31868 "2026-08-27T15:35:01Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![BoxToPlay-helper](https://forum.boxtoplay.com/user_avatar/forum.boxtoplay.com/boxtoplay-helper/32/5468_2.png) [@BoxToPlay-helper](https://forum.boxtoplay.com/u/BoxToPlay-helper)\
**Post date:** [Août 27, 2026, 3:35 UTC](https://forum.boxtoplay.com/t/how-to-install-portainer-on-a-linux-vps/31868/1 "2026-08-27T15:35:01Z")

</div>

![How to install Portainer on a Linux VPS](https://forum.boxtoplay.com/uploads/default/original/2X/a/aa964003223a81987b4129f8a76c0b8fe63d678e.jpeg)

### Install Portainer on a **Linux VPS**

[Portainer](https://www.portainer.io/) is a web UI for Docker. Instead of driving everything from SSH, you see containers, images, volumes and Docker Compose stacks in a dashboard, with buttons to start, stop, read logs or deploy a Compose file. The project is open source: the code lives in the [official GitHub repository](https://github.com/portainer/portainer).

This guide covers **Portainer Community Edition** (CE), the free edition. It works well on a personal VPS or a small lab. The official UI is English-only, so the labels in the screenshots match what you will see after install.

When you finish, you will have:

- a Portainer container that Docker restarts on its own
- an administrator account protected by a password
- local Docker already detected and ready to manage in the browser
- port `9443` limited to your IP, with `8000` and `9000` left closed

This is the dashboard once local Docker is connected: left menu, top bar, environment info, and the counters in the middle (stacks, containers, images, volumes, networks).

 ![Portainer dashboard with the local menu and Docker environment info](https://forum.boxtoplay.com/uploads/default/original/2X/4/460bedd3ee6f1f6b1b5f153759e38c04caa1d68f.png)

### The plan

If Docker is already running on the VPS, it comes down to five moves:

1. Create the `portainer_data` volume, then start the official container.
2. Open `https://xxxx:9443/` in the browser (self-signed certificate on the first visit).
3. Read the **setup token** from the logs and create the admin user within five minutes.
4. Click **Get Started** to stay on local Docker.
5. Restrict port `9443`: Portainer talks to Docker with the same power as root.

### Prerequisites

Before you paste the commands:

- you are logged in as **root** on a BoxToPlay Linux VPS, typically **Ubuntu 24.04** or **Debian 12** and newer
- **Docker** is already working. If it is not, start with [Install Docker on Linux, a practical getting-started guide](https://www.boxtoplay.com/en/news/install-docker-on-linux-a-practical-getting-started-guide-31747)
- TCP port **9443** is not already used by another service
- you can allow TCP port **9443** in the hardware firewall of your BoxToPlay client area, **only from your IP** , before starting Portainer

Docker should come from the official repository, not from an Ubuntu `snap` package. Portainer advises against snap, and our Docker guide already uses the `get.docker.com` sequence.

### Step 1: start Portainer

First create the volume that stores Portainer’s internal database (users, settings, history). Without it, a plain `docker rm` also wipes the admin account.

```bash
docker volume create portainer_data

```

Explicitly download the latest LTS image so Docker does not reuse an older version left in its cache:

```bash
docker pull portainer/portainer-ce:lts

```

Then start the official image with the **`lts`** tag, not `latest`. That is Portainer’s current recommendation for a server.

```bash
docker run -d \
  -p 9443:9443 \
  --name portainer \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:lts

```

Compared with the official docs, we simplify three points:

- we **do not** publish port `8000`. It is the tunnel for **Edge agents**. On a single VPS that only manages its own Docker, you do not need it
- we **do not** publish HTTP port `9000` by default. Normal access is **HTTPS on 9443**. Port `9000` only exists for old bookmarks
- `/var/run/docker.sock` is mounted read-write, as in the official procedure. A `:ro` mount would break creating containers from the UI

Check that the container is **Up** :

```bash
docker ps --filter name=portainer

```

Example output:

```plaintext
CONTAINER ID IMAGE STATUS PORTS NAMES
a1b2c3d4e5f6 portainer/portainer-ce:lts Up 8 seconds 8000/tcp, 9000/tcp, 0.0.0.0:9443->9443/tcp, [::]:9443->9443/tcp portainer

```

The `8000/tcp` and `9000/tcp` entries **without** `0.0.0.0` are ports exposed by the image, not published on the VPS. They are not listening on the internet. Only `9443` is actually open, including IPv6 if Docker maps it.

If you really need legacy HTTP as well as HTTPS, add `-p 9000:9000` to the `docker run`. That is not the path we recommend.

### Step 2: create the first administrator

Open this URL in the browser:

```plaintext
https://xxxx:9443/

```

Replace `xxxx` with the public IP or DNS name of your VPS. On the first load, the browser shows a certificate warning: Portainer generates a **self-signed** certificate until you provide a real one. That is expected. Continue only if you are on **your** machine.

A brand-new Portainer CE instance requires a **setup token**. Without it, anyone who hits port `9443` in the first minutes could claim the admin account. The token is one-time use, only to create the first user or restore a backup.

Print it from the logs:

```bash
docker logs portainer

```

Look for `setup_token=`. Copy only the long hex string that follows, nothing else. The [official setup token FAQ](https://docs.portainer.io/faqs/installing/setup-token) describes the same reflex.

You have **five minutes** to create the user. After that, Portainer refuses setup for security reasons. If that happens, use the collapsible section at the bottom of this article: restarting the container issues a **new** token.

The screen looks like this. The password must be **at least 12 characters**. The suggested username is `admin`; you can change it.

 ![Portainer first-admin screen with the Setup token field](https://forum.boxtoplay.com/uploads/default/original/2X/2/21c36d1235c2510039488c606b46193d80b958e6.png)

Enter the password twice, paste the setup token, then click **Create user**. Never commit that password in a repository, a ticket or a Discord channel.

### Step 3: stay on local Docker

Right after that, the **Environment Wizard** opens. Portainer has already seen the VPS Docker socket. On a single server, click **Get Started**. **Add Environments** is for extra hosts (agent, Kubernetes, cloud). You do not need it here. That screen appears only once: the next login opens **Home** directly.

 ![Portainer Environment Wizard with Get Started for local Docker](https://forum.boxtoplay.com/uploads/default/original/2X/0/05a645b38e039a89932e29ccb85e21af788481ab.png)

You then land on **Home**. The environment is named **local** , status **Up** , and the URL shown is the Unix socket `/var/run/docker.sock`. Click that card to open the Docker dashboard.

 ![Portainer Home page with the local Docker environment](https://forum.boxtoplay.com/uploads/default/original/2X/0/013783a21dd5eff4cd5a58416250c9040529a6a3.png)

### Step 4: containers and stacks

The left menu covers day-to-day work:

- **Containers** : list, start/stop, logs, console
- **Images** : what is already pulled
- **Volumes** and **Networks**
- **Stacks** : deploy a Docker Compose file

Right after install, the container list often shows only Portainer itself:

 ![Portainer container list with only HTTPS port 9443 published](https://forum.boxtoplay.com/uploads/default/original/2X/8/83ee55da09b4b86b3b1b1bebb3b0040ebd9f2bbb.png)

**Stacks** start empty. The simple path: **Add stack** , a name (for example `web`), paste the Compose file in the editor, then **Deploy the stack**. Git and upload are there too if you prefer them.

 ![Empty Portainer stacks list with the Add stack button](https://forum.boxtoplay.com/uploads/default/original/2X/3/34772854198e2fbc5121f5af9208e841ac503ac3.png)

A minimal example to check that a web deploy works. It makes Nginx available only from the VPS itself at `127.0.0.1:8080`. To expose it to the internet, explicitly choose a public port mapping and protect that port in the BoxToPlay hardware firewall.

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

```

Once deployed, stack `web` shows up under **Stacks** , and the container is usually named `web-web-1` in **Containers**. Start, stop and logs stay in the UI, with no extra `docker compose` over SSH.

### Security: treat Portainer like root access

Mounting `docker.sock` is not a detail. Anyone who can log into Portainer can, in practice, start any container, mount the host disk and become root on the VPS. The admin password is not “one more login”: it is the key to the machine.

Configure the BoxToPlay hardware firewall **before** `docker run`, then allow `9443/tcp` only from your IP, never from `0.0.0.0/0`. Check the IPv6 rule as well if your VPS has an IPv6 address. Complete setup immediately afterwards instead of leaving Portainer open “for later”.

A port published by Docker can bypass classic UFW rules. A command such as `ufw allow 9443/tcp` would also allow every source instead of limiting access to your IP. Likewise, a rule appended to the iptables `INPUT` chain does not correctly filter traffic forwarded to a Docker container.

For an additional restriction directly on the VPS, use the `DOCKER-USER` chain with the actual source IP and network interface. This is an advanced configuration that depends on the server network, so do not blindly paste a generic rule. The BoxToPlay hardware firewall remains the simplest way to restrict access before the first start.

Do **not** publish `8000` until you actually run Edge agents, and do not share the Portainer URL, even “just for the install”. Portainer already has web authentication: extra reverse-proxy **Basic Auth** is not required. It still helps if you want a DNS name and a proper Let’s Encrypt certificate.

> **Optional HTTPS reverse proxy with Nginx**
>
> If you prefer `https://portainer.xxxx/` instead of port `9443` directly on the server IP, put Nginx (or Apache) in front with a valid certificate, and proxy to `https://127.0.0.1:9443`. Recreate Portainer with `-p 127.0.0.1:9443:9443` so only the reverse proxy can reach that port, then let Nginx listen on 443.
> 
> Remember that Portainer’s built-in certificate is self-signed: depending on the proxy, you will either give Portainer a real certificate or tell the backend to accept that internal one. The goal is not three layers of auth. It is one clean URL and one exposed port.

### Updates and backups

Durable data lives in the `portainer_data` volume. To update:

```bash
docker pull portainer/portainer-ce:lts
docker stop portainer
docker rm portainer

```

Then run **exactly** the same `docker run` as at install (same ports, same volumes, same `lts` tag). Do not recreate the volume: accounts and settings stay.

For a manual backup, stop the container and archive the volume, or snapshot the VPS from the BoxToPlay client area before a major upgrade. The named `portainer_data` volume survives `docker rm`, including with the `-v` option. The installation is only erased if you explicitly remove that volume, for example with `docker volume rm portainer_data` after removing the container.

> **The initial setup timed out**
>
> If you see a _timed out for security purposes_ message, the five-minute window is gone. Restart the container, read the logs again, and use the **new** `setup_token`:
> 
> ```bash
> docker stop portainer
> docker start portainer
> docker logs portainer
> 
> ```
> 
> Do not reuse the old token. Recreate the admin immediately, still within five minutes.

### What next

Portainer does not replace backups, the firewall or OS updates. It is useful every day, and dangerous if left open on the internet.

If you want a **Linux VPS** delivered with root access, ready for Docker, with a hardware firewall in the client area, you can [start your server at BoxToPlay](https://www.boxtoplay.com/en/vps-hosting/vps-server).
