JustToThePoint English Website Version
JustToThePoint en español

Deploy and Manage Containers with Portainer on Proxmox VE

Quantity has a quality of its own, Joseph Stalin.

Portainer is a container management platform that provides a user-friendly interface for deploying, managing, and monitoring containerized applications —especially those running on Docker or Kubernetes.

image info

Portainer lets you:

In this guide, we’ll walk through:

  1. Creating an Ubuntu CT (Container) in Proxmox VE
  2. Installing Docker on that CT.
  3. Deploying Portainer via a Docker container.
  4. Using Portainer to deploy an Nginx web server and a full WordPress + MySQL stack.

Creating CT via GUI

  1. In Proxmox VE, Datacenter, Node/Host (e.g., myserver), right click Create CT.
  2. General. Assign CT ID (e.g., 110), Hostname (a descriptive name, e.g., myportainer), and set a strong password for root.
  3. Template, choose an Ubuntu template, e.g., ubuntu-24.04-standard…
  4. Disks. Storage (local or mypool). Allocate Root Disk (80 GB) and optionally extra storage for downloads (Add).
  5. Set CPU & Memory, e.g., 4 vCPU / 2048 MiB (2 GiB RAM)/ 512 MiB (Swap).
  6. Configure Network, use an static IP (e.g., 192.168.1.40/24), gateway 192.168.1.1, bridge (vmbr0).
  7. DNS. Leave defaults as is. Enable Start after created and finish.
  8. Initial OS Update.
     sudo apt update && sudo apt upgrade -y
     sudo reboot
    

Installing Docker (the easy way)

Docker allows us to run applications in isolated containers.

# Install prerequisites
sudo apt update
sudo apt install -y \
  apt-transport-https \
  ca-certificates \
  curl \
  gnupg \
  lsb-release

# Add Docker’s official GPG key and repo (optional if using get.docker.com).
# Using Docker’s official repo ensures the latest stable Docker CE.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt install -y docker-ce docker-ce-cli containerd.io

# Manage Docker as a non-root user
# Create a new user
adduser nmaximo7
# Add user nmaximo7 to the sudo and docker groups
sudo usermod -aG docker,sudo nmaximo7

# Log in to the docker group
newgrp docker

# Verify:
id nmaximo7
uid=1000(nmaximo7) gid=1000(nmaximo7) groups=1000(nmaximo7),27(sudo),100(users),990(docker)

docker version
root@ubuntu-vpn:~# docker version
Client: Docker Engine - Community
 Version:           28.2.2
 API version:       1.50
 Go version:        go1.24.3
 Git commit:        e6534b4
 Built:             Fri May 30 12:08:34 2025
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
[...]

root@ubuntu-vpn:~# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
[...]
Hello from Docker!
[...]

PORTAINER

Portainer is a lightweight management UI for Docker that simplifies the management of Docker environments. It provides a user-friendly interface to visualize and manage containers, networks, and volumes.

Key Features:

Install Portainer on Docker using docker-compose

  1. Installation Steps

    # 1. First, pull the latest version of the Portainer CE (Community Edition) image:
    sudo docker pull portainer/portainer-ce:latest
    # 2. Create a persistent volume where data will be permanently stored:
    docker volume create portainer_data
    # 2. Run the Portainer Container with the following command.
    sudo docker run -d \
        -p 9000:9000 \ # Map port 9000 on the host to port 9000 in the container
        --name=portainer \ # Name the container "portainer" for easy management
        --restart=always \ # Automatically restart the container if it stops unexpectedly
        - v /var/run/docker.sock:/var/run/docker.sock \ # Allow Portainer to communicate with the Docker daemon
        -v portainer_data:/data \ # Persist Portainer data in a Docker volume
        portainer/portainer-ce:latest  # Use the latest Portainer CE image
    
  2. Access the Portainer UI. Open your favorite browser and type the following: https://your-host-ip:9000. You will come across a security warning informing you that the connection is not private: Advanced, Proceed to [server IP address].

  3. Create your first user. Upon launching Portainer’s web interface, you will need to create an admin account. You’ll need to choose a username and a strong password (at least 12 characters). Then click Create user to create the user.

  4. Connect to your local environment. The installation process will automatically detect your local Docker environment. Click Get Started" to proceed with your local portainer and begin managing your Docker containers and services.

  5. Local Dashboard. Selecting local will take you to the Portainer dashboard, where you can manage various aspects of your Docker environment, including:

Deploy Nginx Web Server with Docker Compose on Portainer

Portainer is a powerful web-based management interface for Docker environments that simplifies deploying applications. One of its most valuable features is the Stacks functionality, which wraps around Docker Compose to provide an intuitive way to deploy multi-container applications.

A stack is a collection of one or more containers that work together to form a complete application. It could consist of a frontend user interface, backend api services, database servers, caching layers and/or load balancers.

This section demonstrates how to deploy a simple Nginx web server using the Docker compose functionality.

  1. Open your web browser and access your Portainer instance (typically http://your-server-ip:9000).

  2. Head over to the left sidebar, click on Stacks.

  3. Choose Deployment Method: Portainer offers four deployment options: Web editor (Write/paste Docker Compose directly in the browser), Upload (Upload a docker-compose.yml file), Git repository (Deploy from a Git repository), and Custom template (Use predefined templates). For this tutorial, we’ll use the Web editor option for maximum flexibility.

  4. In our case, we will deploy a basic Nginx web server using the web editor. Here is a Docker compose file you can use.

    services:
    nginx:
        image: nginx:latest # Use the latest Nginx image from Docker Hub
        container_name: my-blog # Name the container "my-blog"
        ports:
        - "8080:80" # Map port 8080 on the host to port 80 in the container
        volumes:
        - /var/www/html:/usr/share/nginx/html # Mount the host directory for serving HTML files
        restart: always # Always restart the container unless it is stopped manually
        healthcheck: # Configure a health check for the container
        test: ["CMD", "curl", "-f", "http://localhost:80/"] # Check if the Nginx server is responding
        interval: 30s # Check every 30 seconds
        timeout: 10s # Time out after 10 seconds if there's no response
        retries: 3 # Retry 3 times before marking the container as unhealthy
        start_period: 40s # Wait 40 seconds before starting health checks after container starts
    
  5. Next, scroll down and toggle off the Enable access control option to make the application publicly available or on if you want to restrict access to specific users or teams. Then, smash the Deploy the stack button. Your newly created stack will appear in the Stacks list section.

  6. Creating the Web Directory Structure
    # Create the web root directory
    sudo mkdir -p /var/www/html
    
    # Set proper permissions
    sudo chown -R 1000:1000 /var/www/html
    sudo chown -R root:root /var/www/nginx
    
    # Navigate to web root
    cd /var/www/html
    
    # Create main index.html
    sudo nvim index.html
    
    # Test local access
    curl http://localhost:8080
    
    # Test from another machine
    curl http://your-server-ip:8080
    
    # Check health status
    docker exec my-blog-nginx nginx -t
    

Next, navigate to the web root directory on your Docker host: cd /var/www/html/. Create an index.html file: sudo nano index.html. Next, visit your host’s IP address on port 8080.

image info

Deploy WordPress with Docker Composer on Portainer

WordPress is a free and open-source content management system written in PHP and paired with a MySQL or MariaDB database. Here’s a step-by-step guide to deploy WordPress using Docker Compose in Portainer:

  1. Open your web browser, navigate to [http://] + your-server-ip + [:9000], and log in to Portainer.

  2. In the left sidebar, go to Stacks, Add stack.

  3. Configure Stack. Name: enter a name (e.g., mywordpress). Build Method: Portainer offers four deployment options: Web editor, Upload, Git repository (Deploy from a Git repository), and Custom template (Use predefined templates). Select Web editor.

  4. Copy and paste the YAML below into the editor:

    version: '3.8'  # Specify the version of the Docker Compose file format
    services:
      db:  # Define the MySQL database service
        image: mysql:8.0  # Use the MySQL 8.0 Docker image
        environment:
          - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}  # Set the root password for MySQL
          - MYSQL_DATABASE=${MYSQL_DATABASE}  # Name of the database to create
          - MYSQL_USER=${MYSQL_USER}  # MySQL user to create
          - MYSQL_PASSWORD=${MYSQL_PASSWORD}  # Password for the MySQL user
        volumes:
          - db:/var/lib/mysql  # Persist MySQL data in a Docker volume
        restart: unless-stopped  # Restart the container unless stopped manually
    
      wordpress:  # Define the WordPress service
        image: wordpress:latest  # Use the latest WordPress Docker image
        ports:
          - 8880:80  # Map port 8880 on the host to port 80 on the container
          # If port 8880 is in use, change the left-side port in the Compose file (e.g., 8080:80).
        environment:
          - WORDPRESS_DB_HOST=db  # Specify the database host
          - WORDPRESS_DB_USER=${MYSQL_USER}  # MySQL user for WordPress
          - WORDPRESS_DB_PASSWORD=${MYSQL_PASSWORD}  # Password for the MySQL user
          - WORDPRESS_DB_NAME=${MYSQL_DATABASE}  # Database name for WordPress
        depends_on:
          - db  # Ensure the database service starts before WordPress
        restart: unless-stopped  # Restart the container unless stopped manually
    
    volumes:
      db: # Define a persistent volume for the MySQL database
      # A volume is an abstraction of a file system that is available to applications.
    

    To delete a volume in Portainer, first navigate to the Volumes section, select the volume(s) you wish to remove (e.g., mywordpress_db), and then click Remove. Volumes must be unused (not attached to a container or other resource) before they can be deleted. You may want to inspect a volume. portainer.io provides detailed information about it, including its name, size, and usage.

  5. Set Environment Variables. Under Environment variables, click Add an environment variable (these are necessary variables for the containers you deploy). Define these 4 values: MYSQL_ROOT_PASSWORD (MySQL root user password, set it to a strong unique password), MYSQL_DATABASE (WordPress database name, e.g., wordpress), MYSQL_USER (MySQL user for WordPress, e.g., wordpress or wp_user), and MYSQL_PASSWORD (Password for the WordPress user).

  6. Deploy the Stack. Scroll down and toggle off the Enable access control option to make the application publicly available. Then, smash the Deploy the stack button. Your newly created stack will appear in the Stacks list section.

  7. Post-Deployment. Visit [http://] + your-server-ip + [:8880] in your browser to complete WordPress setup. In Portainer, go to Stacks, your stack (e.g., mywordpress), Containers to check if both containers (mywordpress-db and mywordpress-wordpress) are running.

Bitcoin donation

JustToThePoint Copyright © 2011 - 2025 Anawim. ALL RIGHTS RESERVED. Bilingual e-books, articles, and videos to help your child and your entire family succeed, develop a healthy lifestyle, and have a lot of fun. Social Issues, Join us.

This website uses cookies to improve your navigation experience.
By continuing, you are consenting to our use of cookies, in accordance with our Cookies Policy and Website Terms and Conditions of use.