Skip to main content

Portainer Server + Agent Setup - Kompletní návod (Docker Run)

Přehled architektury

  • Hlavní RPi (Master): Portainer Server - hlavní UI pro správu
  • Ostatní RPi (Workers): Portainer Agent - odesílají data do hlavního serveru
  • Výsledek: Jeden centrální dashboard pro všechny Docker prostředí

1. HLAVNÍ RPI (PORTAINER SERVER)

Adresářová struktura

/opt/portainer/
├── data/                    # Portainer data (automaticky vytvoří)
├── backups/                 # Zálohy dat
├── scripts/
│   ├── install.sh          # Instalační skript
│   ├── start.sh            # Start kontejneru
│   ├── stop.sh             # Stop kontejneru
│   ├── restart.sh          # Restart kontejneru
│   ├── update.sh           # Update na nejnovější verzi
│   └── backup.sh           # Zálohovací skript
└── config.env              # Environment proměnné

Vytvoření adresářů a souborů

# Vytvoření základní struktury s backup adresářem
sudo mkdir -p /opt/portainer/{data,scripts,backups}
cd /opt/portainer

/opt/portainer/config.env

# Portainer Server Configuration
PORTAINER_VERSION=latest
PORTAINER_DATA_DIR=/opt/portainer/data
PORTAINER_HTTP_PORT=9000
PORTAINER_HTTPS_PORT=9443
PORTAINER_AGENT_PORT=8000
CONTAINER_NAME=portainer_server

/opt/portainer/scripts/install.sh

#!/bin/bash
set -e

# Načtení konfigurace
source /opt/portainer/config.env

echo "🚀 Instalace Portainer Server..."

# Kontrola, zda běží jako root
if [ "$EUID" -ne 0 ]; then
    echo "❌ Spusťte jako root nebo s sudo"
    exit 1
fi

# Kontrola Docker
if ! command -v docker &> /dev/null; then
    echo "❌ Docker není nainstalován!"
    exit 1
fi

# Kontrola portů
echo "🔍 Kontrola dostupnosti portů..."
if netstat -tuln | grep -q ":$PORTAINER_HTTP_PORT "; then
    echo "❌ Port $PORTAINER_HTTP_PORT je již obsazený!"
    exit 1
fi

if netstat -tuln | grep -q ":$PORTAINER_HTTPS_PORT "; then
    echo "❌ Port $PORTAINER_HTTPS_PORT je již obsazený!"
    exit 1
fi

if netstat -tuln | grep -q ":$PORTAINER_AGENT_PORT "; then
    echo "❌ Port $PORTAINER_AGENT_PORT je již obsazený!"
    exit 1
fi

# Zastavení a smazání existujícího kontejneru (pokud existuje)
echo "🛑 Zastavení existujících Portainer kontejnerů..."
docker stop $CONTAINER_NAME 2>/dev/null || true
docker rm $CONTAINER_NAME 2>/dev/null || true

# Stažení nejnovější verze
echo "⬇️ Stahování Portainer obrazu..."
docker pull portainer/portainer-ce:$PORTAINER_VERSION

# Vytvoření data adresáře s správnými oprávněními
mkdir -p $PORTAINER_DATA_DIR
chown -R 1000:1000 $PORTAINER_DATA_DIR

# Spuštění Portainer Server
echo "▶️ Spouštění Portainer Server..."
docker run -d \
  -p $PORTAINER_AGENT_PORT:8000 \
  -p $PORTAINER_HTTP_PORT:9000 \
  -p $PORTAINER_HTTPS_PORT:9443 \
  --name $CONTAINER_NAME \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $PORTAINER_DATA_DIR:/data \
  portainer/portainer-ce:$PORTAINER_VERSION

# Čekání na spuštění
echo "⏳ Čekání na spuštění Portainer..."
sleep 10

# Kontrola stavu
if docker ps | grep -q $CONTAINER_NAME; then
    echo "✅ Portainer Server úspěšně spuštěn!"
    echo ""
    echo "📋 Přístupové údaje:"
    echo "   HTTP:  http://$(hostname -I | awk '{print $1}'):$PORTAINER_HTTP_PORT"
    echo "   HTTPS: https://$(hostname -I | awk '{print $1}'):$PORTAINER_HTTPS_PORT"
    echo ""
    echo "⚠️ Při prvním přístupu si nastavte admin heslo!"
else
    echo "❌ Chyba při spouštění Portainer Server"
    docker logs $CONTAINER_NAME
    exit 1
fi

/opt/portainer/scripts/start.sh

#!/bin/bash
source /opt/portainer/config.env

echo "▶️ Spouštění Portainer Server..."
docker start $CONTAINER_NAME

# Čekání na spuštění
sleep 3

if docker ps | grep -q $CONTAINER_NAME; then
    echo "✅ Portainer Server spuštěn!"
    echo "📋 Dostupný na: https://$(hostname -I | awk '{print $1}'):$PORTAINER_HTTPS_PORT"
else
    echo "❌ Chyba při spouštění!"
    docker logs $CONTAINER_NAME
fi

/opt/portainer/scripts/stop.sh

#!/bin/bash
source /opt/portainer/config.env

echo "🛑 Zastavování Portainer Server..."
docker stop $CONTAINER_NAME
echo "✅ Portainer Server zastaven!"

/opt/portainer/scripts/restart.sh

#!/bin/bash
source /opt/portainer/config.env

echo "🔄 Restartování Portainer Server..."
docker restart $CONTAINER_NAME

# Čekání na spuštění
sleep 5

if docker ps | grep -q $CONTAINER_NAME; then
    echo "✅ Portainer Server restartován!"
    echo "📋 Dostupný na: https://$(hostname -I | awk '{print $1}'):$PORTAINER_HTTPS_PORT"
else
    echo "❌ Chyba při restartu!"
    docker logs $CONTAINER_NAME
fi

/opt/portainer/scripts/update.sh

#!/bin/bash
source /opt/portainer/config.env

echo "🔄 Aktualizace Portainer Server..."
echo "📋 Současná verze:"
docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"

echo ""
echo "🛑 Zastavení kontejneru..."
docker stop $CONTAINER_NAME

echo "⬇️ Stahování nové verze..."
docker pull portainer/portainer-ce:$PORTAINER_VERSION

echo "🗑️ Odstranění starého kontejneru..."
docker rm $CONTAINER_NAME

echo "▶️ Spuštění s novou verzí..."
docker run -d \
  -p $PORTAINER_AGENT_PORT:8000 \
  -p $PORTAINER_HTTP_PORT:9000 \
  -p $PORTAINER_HTTPS_PORT:9443 \
  --name $CONTAINER_NAME \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $PORTAINER_DATA_DIR:/data \
  portainer/portainer-ce:$PORTAINER_VERSION

echo "🧹 Čištění starých images..."
docker image prune -f

# Čekání na spuštění
sleep 5

echo ""
echo "✅ Portainer Server aktualizován!"
echo "📋 Nová verze:"
docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"

/opt/portainer/scripts/backup.sh

#!/bin/bash
set -e

BACKUP_DIR="/opt/portainer/backups"
BACKUP_NAME="portainer_backup_$(date +%Y%m%d_%H%M%S).tar.gz"
RETENTION_DAYS=30

echo "💾 Vytváření zálohy Portainer dat..."

# Vytvoření backup adresáře
mkdir -p "$BACKUP_DIR"

# Vytvoření zálohy
tar -czf "$BACKUP_DIR/$BACKUP_NAME" -C /opt/portainer data/

# Kontrola velikosti
BACKUP_SIZE=$(du -h "$BACKUP_DIR/$BACKUP_NAME" | cut -f1)
echo "✅ Záloha vytvořena: $BACKUP_NAME ($BACKUP_SIZE)"

# Smazání starých záloh (starších než RETENTION_DAYS dnů)
find "$BACKUP_DIR" -name "portainer_backup_*.tar.gz" -type f -mtime +$RETENTION_DAYS -delete 2>/dev/null || true

# Výpis aktuálních záloh
echo "📋 Dostupné zálohy:"
ls -lh "$BACKUP_DIR"/portainer_backup_*.tar.gz 2>/dev/null || echo "Žádné zálohy nenalezeny"

2. OSTATNÍ RPI (PORTAINER AGENT)

Adresářová struktura

/opt/portainer-agent/
├── data/                    # Agent data (automaticky vytvoří)
├── scripts/
│   ├── install.sh          # Instalační skript
│   ├── start.sh            # Start kontejneru
│   ├── stop.sh             # Stop kontejneru
│   ├── restart.sh          # Restart kontejneru
│   └── update.sh           # Update na nejnovější verzi
└── config.env              # Environment proměnné

Vytvoření adresářů a souborů

# Vytvoření základní struktury
sudo mkdir -p /opt/portainer-agent/{data,scripts}
cd /opt/portainer-agent

/opt/portainer-agent/config.env

# Portainer Agent Configuration
AGENT_VERSION=latest
AGENT_DATA_DIR=/opt/portainer-agent/data
AGENT_PORT=9001
CONTAINER_NAME=portainer_agent

/opt/portainer-agent/scripts/install.sh

#!/bin/bash
set -e

# Načtení konfigurace
source /opt/portainer-agent/config.env

echo "🚀 Instalace Portainer Agent..."

# Kontrola, zda běží jako root
if [ "$EUID" -ne 0 ]; then
    echo "❌ Spusťte jako root nebo s sudo"
    exit 1
fi

# Kontrola Docker
if ! command -v docker &> /dev/null; then
    echo "❌ Docker není nainstalován!"
    exit 1
fi

# Kontrola portu
echo "🔍 Kontrola dostupnosti portu $AGENT_PORT..."
if netstat -tuln | grep -q ":$AGENT_PORT "; then
    echo "❌ Port $AGENT_PORT je již obsazený!"
    exit 1
fi

# Zastavení a smazání existujícího kontejneru (pokud existuje)
echo "🛑 Zastavení existujících Portainer Agent kontejnerů..."
docker stop $CONTAINER_NAME 2>/dev/null || true
docker rm $CONTAINER_NAME 2>/dev/null || true

# Stažení nejnovější verze
echo "⬇️ Stahování Portainer Agent obrazu..."
docker pull portainer/agent:$AGENT_VERSION

# Vytvoření data adresáře s správnými oprávněními
mkdir -p $AGENT_DATA_DIR
chown -R 1000:1000 $AGENT_DATA_DIR

# Spuštění Portainer Agent
echo "▶️ Spouštění Portainer Agent..."
docker run -d \
  -p $AGENT_PORT:9001 \
  --name $CONTAINER_NAME \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /var/lib/docker/volumes:/var/lib/docker/volumes \
  -v $AGENT_DATA_DIR:/data \
  portainer/agent:$AGENT_VERSION

# Čekání na spuštění
echo "⏳ Čekání na spuštění Agent..."
sleep 5

# Kontrola stavu
if docker ps | grep -q $CONTAINER_NAME; then
    echo "✅ Portainer Agent úspěšně spuštěn!"
    echo ""
    echo "📋 Agent endpoint:"
    echo "   $(hostname -I | awk '{print $1}'):$AGENT_PORT"
    echo ""
    echo "➡️ Nyní přidejte tento agent do Portainer Server UI"
else
    echo "❌ Chyba při spouštění Portainer Agent"
    docker logs $CONTAINER_NAME
    exit 1
fi

/opt/portainer-agent/scripts/start.sh

#!/bin/bash
source /opt/portainer-agent/config.env

echo "▶️ Spouštění Portainer Agent..."
docker start $CONTAINER_NAME

# Čekání na spuštění
sleep 3

if docker ps | grep -q $CONTAINER_NAME; then
    echo "✅ Portainer Agent spuštěn!"
    echo "📋 Endpoint: $(hostname -I | awk '{print $1}'):$AGENT_PORT"
else
    echo "❌ Chyba při spouštění!"
    docker logs $CONTAINER_NAME
fi

/opt/portainer-agent/scripts/stop.sh

#!/bin/bash
source /opt/portainer-agent/config.env

echo "🛑 Zastavování Portainer Agent..."
docker stop $CONTAINER_NAME
echo "✅ Portainer Agent zastaven!"

/opt/portainer-agent/scripts/restart.sh

#!/bin/bash
source /opt/portainer-agent/config.env

echo "🔄 Restartování Portainer Agent..."
docker restart $CONTAINER_NAME

# Čekání na spuštění
sleep 3

if docker ps | grep -q $CONTAINER_NAME; then
    echo "✅ Portainer Agent restartován!"
    echo "📋 Endpoint: $(hostname -I | awk '{print $1}'):$AGENT_PORT"
else
    echo "❌ Chyba při restartu!"
    docker logs $CONTAINER_NAME
fi

/opt/portainer-agent/scripts/update.sh

#!/bin/bash
source /opt/portainer-agent/config.env

echo "🔄 Aktualizace Portainer Agent..."
echo "📋 Současná verze:"
docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"

echo ""
echo "🛑 Zastavení kontejneru..."
docker stop $CONTAINER_NAME

echo "⬇️ Stahování nové verze..."
docker pull portainer/agent:$AGENT_VERSION

echo "🗑️ Odstranění starého kontejneru..."
docker rm $CONTAINER_NAME

echo "▶️ Spuštění s novou verzí..."
docker run -d \
  -p $AGENT_PORT:9001 \
  --name $CONTAINER_NAME \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /var/lib/docker/volumes:/var/lib/docker/volumes \
  -v $AGENT_DATA_DIR:/data \
  portainer/agent:$AGENT_VERSION

echo "🧹 Čištění starých images..."
docker image prune -f

# Čekání na spuštění
sleep 3

echo ""
echo "✅ Portainer Agent aktualizován!"
echo "📋 Nová verze:"
docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"

3. INSTALAČNÍ POSTUP

Krok 1: Instalace na hlavním RPi (Server)

# Vytvoření struktury a souborů
sudo mkdir -p /opt/portainer/{data,scripts,backups}

# Zkopírování konfiguračních souborů (viz výše)
# Následně:

cd /opt/portainer
sudo chmod +x scripts/*.sh
sudo ./scripts/install.sh

Krok 2: Instalace na ostatních RPi (Agent)

# Vytvoření struktury a souborů
sudo mkdir -p /opt/portainer-agent/{data,scripts}

# Zkopírování konfiguračních souborů (viz výše)
# Následně:

cd /opt/portainer-agent
sudo chmod +x scripts/*.sh
sudo ./scripts/install.sh

Krok 3: Propojení přes UI

  1. Otevři https://HLAVNI_RPI_IP:9443
  2. Nastav admin heslo při prvním přístupu
  3. Přejdi na Environments → Add Environment
  4. Vyber Agent
  5. Zadej endpoint: AGENT_RPI_IP:9001
  6. Klikni Connect

4. RYCHLÉ DOCKER RUN PŘÍKAZY

Portainer Server (jednorázové spuštění)

docker run -d \
  -p 8000:8000 \
  -p 9000:9000 \
  -p 9443:9443 \
  --name portainer_server \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /opt/portainer/data:/data \
  portainer/portainer-ce:latest

Portainer Agent (jednorázové spuštění)

docker run -d \
  -p 9001:9001 \
  --name portainer_agent \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /var/lib/docker/volumes:/var/lib/docker/volumes \
  -v /opt/portainer-agent/data:/data \
  portainer/agent:latest

5. SPRÁVA A ÚDRŽBA

Užitečné příkazy

# Server
cd /opt/portainer
sudo ./scripts/start.sh      # Spuštění
sudo ./scripts/stop.sh       # Zastavení
sudo ./scripts/restart.sh    # Restart
sudo ./scripts/update.sh     # Aktualizace
sudo ./scripts/backup.sh     # Ruční záloha

# Agent
cd /opt/portainer-agent
sudo ./scripts/start.sh      # Spuštění
sudo ./scripts/stop.sh       # Zastavení
sudo ./scripts/restart.sh    # Restart
sudo ./scripts/update.sh     # Aktualizace

Kontrola stavu

# Kontrola běžících kontejnerů
docker ps | grep portainer

# Zobrazení logů
docker logs portainer_server     # Server
docker logs portainer_agent      # Agent

# Kontrola portů
sudo netstat -tuln | grep -E "(8000|9000|9001|9443)"

Řešení problémů

# Restart Docker daemon
sudo systemctl restart docker

# Vyčištění nepoužívaných Docker objektů
docker system prune -f

# Reinstalace kontejneru
cd /opt/portainer
sudo ./scripts/stop.sh
docker rm portainer_server
sudo ./scripts/install.sh

6. ZABEZPEČENÍ A TIPY

Firewall nastavení

# Server (pouze LAN přístup)
sudo ufw allow from 192.168.0.0/16 to any port 8000 proto tcp
sudo ufw allow from 192.168.0.0/16 to any port 9000 proto tcp
sudo ufw allow from 192.168.0.0/16 to any port 9443 proto tcp
sudo ufw allow from 10.0.0.0/8 to any port 8000 proto tcp
sudo ufw allow from 10.0.0.0/8 to any port 9000 proto tcp
sudo ufw allow from 10.0.0.0/8 to any port 9443 proto tcp

# Agent (pouze LAN přístup)
sudo ufw allow from 192.168.0.0/16 to any port 9001 proto tcp
sudo ufw allow from 10.0.0.0/8 to any port 9001 proto tcp

# ⚠️ NIKDY neotvírat na internet:
# sudo ufw allow 8000/tcp  ❌ NEPOUŽÍVAT
# sudo ufw allow 9001/tcp  ❌ NEPOUŽÍVAT

Edge Agent pro vzdálený přístup

Pokud potřebuješ spravovat Portainer přes internet, použij Edge Agent místo klasického agenta:

# Na vzdálených strojích místo běžného agenta:
docker run -d \
  --name portainer_edge_agent \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /var/lib/docker/volumes:/var/lib/docker/volumes \
  portainer/agent:latest

Edge Agent se připojuje ven (port 443) → žádné otevírání portů dovnitř!

Automatické zálohování

Přidej do crontab pro pravidelné zálohování:

# Editace crontab
sudo crontab -e

# Přidej řádek pro týdenní zálohu (každou neděli ve 2:00)
0 2 * * 0 /opt/portainer/scripts/backup.sh

# Pro denní zálohu (každý den ve 2:00)
# 0 2 * * * /opt/portainer/scripts/backup.sh

Obnovení ze zálohy

# Zastavení Portainer
cd /opt/portainer
sudo ./scripts/stop.sh

# Zálohování aktuálních dat (pro jistotu)
sudo mv data data_old_$(date +%Y%m%d_%H%M%S)

# Obnovení ze zálohy
sudo tar -xzf backups/portainer_backup_YYYYMMDD_HHMMSS.tar.gz -C /opt/portainer

# Nastavení oprávnění
sudo chown -R 1000:1000 data/

# Spuštění Portainer
sudo ./scripts/start.sh

Automatické spuštění po restartu

Všechny kontejnery mají nastaveno --restart=always, takže se automaticky spustí po restartu systému.


✅ HOTOVO!

Nyní máš kompletní Portainer Server + Agent setup s:

  • ✅ Čistými docker run příkazy (bez compose)
  • ✅ Strukturovanými adresáři
  • ✅ Automatizovanými skripty
  • ✅ Konfiguračními soubory (.env)
  • ✅ Jednoduchou správou a údržbou
  • ✅ Centralizovaným dashboardem pro všechny RPi

Pro rychlé nasazení stačí:

  1. Zkopírovat soubory do /opt/portainer/ nebo /opt/portainer-agent/
  2. Spustit sudo ./scripts/install.sh
  3. Propojit přes UI

Žádné compose soubory, jen čisté Docker Run! 🚀