Docker auf Proxmox im LXC Container

Will man mal schnell einen separaten Docker Host erstellen, so geht das in Proxmox recht schnell. Hier gibt es die Virtualisierung „LXC“ – die Linux Container Runtime. Hier kann basierend auf dem Host-Betriebssystem (Proxmox 8.2.8 in meinem Fall) eine VM erstellt werden. Sieht aus, wie eine echte VM, ist es aber nicht. Das LXC Betriebssystem basiert vollständig auf dem Host-Betriebssystem.

Mit einem solchen Container kann man in wenigen Schritten Docker installieren. Im folgenden habe ich zusammengeschrieben, welche Schritte dafür notwendig sind – quasi „quick and dirty“.

Table of Contents

    LXC VM erstellen

    Webinterface – Rechts oben „Create CT“

    Hostname definieren (docker01)

    „Unprivileged container“ deaktivieren

    Passwort zwei mal eintippen.

    Next

    Storage wählen und darauf das
    Debian Image auswählen (12-standard_12.7-1_amd64.tar.zst) stand heute.

    Strage „rootfs“ Größe definieren (30G)

    Zweiten Storage erstellen (mp0) – path /mnt/containers
    Disk size 1000 GB

    Next

    4 Cores

    Next

    Memory 16000 und swap 2000

    Next

    Network – IPv4 – DHCP anwählen oder statische IP vergeben – je nach Bedarf

    Next

    Next

    „Finish“

    VM – Options – Doppelklick „Features“ – aktivieren:
    – Nesting
    – NFS
    – SMB/CIFS

    OK

    VM starten

    VM – Installation mit Docker und Portainer

    Login in die Console mit root und dem angelegten Passwort

    ip addr

    Zeigt die IP an, die das System hat. Danach permit root login und Updates

    sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
    
    apt autoclean -y && apt autoremove --purge -y && apt update && apt upgrade -y && apt dist-upgrade -y && reboot now
    

    Jetzt per kitty anmelden und Docker installieren.

    Offizielle Doku: https://docs.docker.com/engine/install/debian/
    Das ganze aber ohne sudo ausführen:

    # Add Docker's official GPG key:
    apt-get update
    apt-get install ca-certificates curl
    install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
    chmod a+r /etc/apt/keyrings/docker.asc
    
    # Add the repository to Apt sources:
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
      $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
      tee /etc/apt/sources.list.d/docker.list > /dev/null
    apt-get update
    

    Installieren:

    apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin htop -y
    

    Spaßeshalber die Installation testen:

    docker run hello-world
    

    Danach Portainer installieren und starten

    docker run -d -p 9000:9000 -p 9443:9443 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v /mnt/containers/portainer/data:/data portainer/portainer-ce
    

    Danach per Webinterface Portainer aufrufen und entweder das Backup wiederherstellen oder Portainer einrichten.

    Docker Container

    Einige Docker Container sind für mich für jede Installation unerlässlich. Deswegen kurz und bündig einige meiner Favoriten, auf die ich gerne zurückgreife.

    Nice-to-have: Portainer Registry

    version: "3.2"
    services:
      docker-registry:
        image: registry:2
        restart: unless-stopped
        ports:
          - 5000:5000
        volumes:
          - /mnt/containers/docker-registry/data/:/var/lib/registry/
          - /mnt/containers/docker-registry/config/config.yml:/etc/docker/registry/config.yml
        environment:
          - REGISTRY_STORAGE_DELETE_ENABLED=TRUE
    

    Dazu die config.yml

    version: 0.1
    log:
      fields:
        service: registry
    storage:
      cache:
        blobdescriptor: inmemory
      filesystem:
        rootdirectory: /var/lib/registry
      delete:
        enabled: true
    #  tag:
    #    concurrencylimit: 8
    http:
      addr: :5000
      headers:
        X-Content-Type-Options: [nosniff]
    health:
      storagedriver:
        enabled: true
        interval: 10s
        threshold: 3
    proxy:
      remoteurl: https://registry-1.docker.io
    

    Das wird alles hinter den HAProxy gehängt oder hinter einen traefik.

    Url: registry.xxxx.example.org

    Must-have: Watchtower für automatische Updates von Container

    version: "3"
    services:
      watchtower:
        restart: unless-stopped
        image: containrrr/watchtower:latest
        tty: true
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
        environment:
          - WATCHTOWER_CLEANUP=true
          - WATCHTOWER_DEBUG=true
          #- WATCHTOWER_LABEL_ENABLE=true
          - WATCHTOWER_INCLUDE_RESTARTING=true
          # Entry                  | Description                                | Equivalent To
          # -----                  | -----------                                | -------------
          # @yearly (or @annually) | Run once a year, midnight, Jan. 1st        | 0 0 0 1 1 *
          # @monthly               | Run once a month, midnight, first of month | 0 0 0 1 * *
          # @weekly                | Run once a week, midnight between Sat/Sun  | 0 0 0 * * 0
          # @daily (or @midnight)  | Run once a day, midnight                   | 0 0 0 * * *
          # @hourly                | Run once an hour, beginning of hour        | 0 0 * * * *
          # I want watchtower to check for new updates every night at 4am.
          #- WATCHTOWER_SCHEDULE: 0 0 4 * * *
          #- WATCHTOWER_SCHEDULE=0 0 5 1 * *
          - WATCHTOWER_SCHEDULE=0 */15 * * * *
          - TZ=Europe/Berlin
        #labels:
        #  - "com.centurylinklabs.watchtower.enable=true"
    

    Nice-to-have: Filebrowser

    Schone Weboberfläche um auf dem Host ein paar Daten anzuschauen. Geht auch als Mount von SMB Shares.

    version: "3.8"
    
    services:
      filebrowser:
        # Default User und Passwort Kombination = admin:admin
        image: hurlenko/filebrowser
        ports:
          - 8088:8080
        volumes:
          # Shared remote SMB folder from a nas with healthcheck to be shown in filebrowser
          - smb_nas_containers:/data/nas/containers
          # Local folder to be shown in filebrowser
          - /mnt/containers:/data/local/containers
          - /mnt/containers/filebrowser/config:/config
        environment:
          - TZ=Europe/Berlin
          - FB_BASEURL=/filebrowser
        # Docker Default Settings
        restart: unless-stopped
        tty: true
        # Healthcheck if mounted file exists - check local folder for file ".healthcheck"
        healthcheck:
          test: ["CMD", "test", "-f", "/data/nas/containers/.healthcheck"]
          interval: 3s
          retries: 3
          start_period: 20s
          timeout: 10s
    
    # Mount Network SMB/CIFS Share
    volumes:
        smb_nas_containers:
          driver: local
          driver_opts:
            type: cifs
            device: //xxxx.example.com/containers
            o: username=${smb_user},password=${smb_password}
    

    Nice-to-have: System Prune (System automatisch aufräumen)

    version: '3.7'
    
    x-default-opts: 
      &default-opts
      logging:
        options:
          max-size: "1m" 
    
    services:
      docker-system-prune:
        image: alpinelinux/docker-cli
        # 86400 = 24h
        command: sh -c "while true; do docker image prune -af; sleep 86400; done"
        volumes:
         - /var/run/docker.sock:/var/run/docker.sock
        logging:
          driver: json-file
        deploy:
          mode: global
    

    Nice-to-have: IT-Tools

    version: '3.9'
    services:
      it-tools:
        image: corentinth/it-tools:latest
        ports:
          - '5541:80'
        container_name: it-tools
        # Docker Default Settings
        restart: unless-stopped
        tty: true
    

    Must-have: Portainer-backup

    Voraussetzung: Portainer muss per http zur Verfügung stehen, sonst funktioniert es nach meinem Wissen nicht.

    Hier wird nur die Portainer Instanz „gesichert“. Das „richtige“ Backup wird danach über rsync, duplicati o. ä. realisiert. Hier wird also nur ein konsistenter Applikationszustand erzeugt und abgelegt.

    version: '3'
    
    services:
      portainer-backup:
        container_name: portainer-backup
        image: dockurr/portainer-backup:latest
        # backup	Backup portainer data archive
        # schedule	Run scheduled portainer backups
        # stacks	Backup portainer stacks
        # test	Test backup (no files are saved)
        # info	Get portainer server info
        command: schedule
        environment:
          TZ: "Europe/Berlin"
          PORTAINER_BACKUP_URL: "http://XXX.example.com:9000"
          PORTAINER_BACKUP_TOKEN: "PORTAINER_ACCESS_TOKEN"
          PORTAINER_BACKUP_IGNORE_VERSION: 1
          PORTAINER_BACKUP_PASSWORD: ""
          PORTAINER_BACKUP_OVERWRITE: 1
          #      Syntax Format:
          #
          #    ┌──────────────────────── second (optional)
          #    │   ┌──────────────────── minute
          #    │   │   ┌──────────────── hour
          #    │   │   │   ┌──────────── day of month
          #    │   │   │   │   ┌──────── month
          #    │   │   │   │   │   ┌──── day of week
          #    │   │   │   │   │   │
          #    │   │   │   │   │   │
          #    *   *   *   *   *   *
          #Examples:
          #    0   0   0   *   *   *   Daily at 12:00am
          #    0   0   5   1   *   *   1st day of month @ 5:00am
          #    0 */15  0   *   *   *   Every 15 minutes
          PORTAINER_BACKUP_SCHEDULE: "0 */15 * * * *"
          PORTAINER_BACKUP_STACKS: 1
          PORTAINER_BACKUP_DRYRUN: 0
          PORTAINER_BACKUP_CONCISE: 50
          PORTAINER_BACKUP_DIRECTORY: "/backup"
          PORTAINER_BACKUP_FILENAME: "{{DATE}} portainer-backup.tar.gz"
        volumes:
          - /mnt/containers/portainer-backup/:/backup
    

    Nice-to-have: Rundeck – Updates automatisieren

    version: '3'
    # Default login admin:admin
    services:
      rundeck:
        image: rundeck/rundeck:SNAPSHOT
        tty: true
        links:
          - postgres
        environment:
            RUNDECK_DATABASE_DRIVER: org.postgresql.Driver
            RUNDECK_DATABASE_USERNAME: rundeck
            RUNDECK_DATABASE_PASSWORD: rundeck
            RUNDECK_DATABASE_URL: jdbc:postgresql://postgres/rundeck?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
            RUNDECK_GRAILS_URL: http://xxx.xxx.xxx.xxx:4440
        volumes:
          - /mnt/containers/rundeck/rundeck/data:/home/rundeck/server/data
          - /mnt/containers/rundeck/rundeck/logs:/home/rundeck/var/logs
          - /mnt/containers/rundeck/rundeck/etc/rundeck:/etc/rundeck/
          #- ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key
        ports:
         - 4440:4440
      postgres:
        image: library/postgres:latest
        tty: true
        expose:
          - 5432
        environment:
          - POSTGRES_DB=rundeck
          - POSTGRES_USER=rundeck
          - POSTGRES_PASSWORD=rundeck
        volumes:
          - /mnt/containers/rundeck/db/postgresql:/var/lib/postgresql/data
        healthcheck:
          # test: ["CMD-SHELL", "pg_isready -d db-name -U db-user"] 
          # POSTGRES_DB & POSTGRES_USER env vars.
          test: ["CMD-SHELL", "pg_isready -d rundeck -U rundeck"]
          interval: 1s
          timeout: 5s
          retries: 10
    

    Nice-to-have: Portainer Agent

    Wenn mehrere Portainer Instanzen existieren, kann man von einer auf mehrere Docker Hostsysteme zugreifen. Dazu gibt es den Agent. Ich installiere auf jedem Docker Hostsystem Portainer.

    version: '3.2'
    services:
      agent:
        image: portainer/agent:latest
        ports:
          - 9001:9001
        volumes:
          - /etc/localtime:/etc/localtime:ro
          - /var/run/docker.sock:/var/run/docker.sock
          - /var/lib/docker/volumes:/var/lib/docker/volumes
    

    Nice-to-have: qrdirstat – Verzeichnisgrößen containers anschauen

    version: '3'
    services:
      qdirstat:
        image: jlesage/qdirstat
        restart: unless-stopped
        ports:
          - "5800:5800"
        volumes:
          - /mnt/containers/qdirstat/config:/config:rw
          - /mnt/containers:/storage:ro
    

    Schreiben Sie einen Kommentar

    Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie mehr darüber, wie Ihre Kommentardaten verarbeitet werden .