Archive for the ‘Docker’ Category

วิธีการ Upgrade Portainer.io

1. ตรวจสอบ Portainer ที่ใช้อยู่
เปิด Terminal บน Mac แล้วรัน
teee@NP Portainer.io % docker ps –filter name=portainer
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
87ed559b6a22 portainer/portainer-ce:latest “/portainer” 3 minutes ago Up 3 minutes 0.0.0.0:9443->9443/tcp, [::]:9443->9443/tcp, 0.0.0.0:8443->8000/tcp, [::]:8443->8000/tcp portainer

ตรวจสอบ Image และ Version:
teee@NP ~ % docker inspect portainer –format ‘{{.Config.Image}}’
portainer/portainer-ce:latest

ตรวจสอบ Volume:
teee@NP ~ % docker inspect portainer –format ‘{{json .Mounts}}’
[{“Type”:”volume”,”Name”:”portainer_data”,”Source”:”/var/lib/docker/volumes/portainer_data/_data”,”Destination”:”/data”,”Driver”:”local”,”Mode”:”rw”,”RW”:true,”Propagation”:””},{“Type”:”bind”,”Source”:”/var/run/docker.sock”,”Destination”:”/var/run/docker.sock”,”Mode”:”rw”,”RW”:true,”Propagation”:”rprivate”}]

2. Backup ข้อมูลก่อนอัปเกรด
หยุด Container ก่อน:
teee@NP ~ % docker stop portainer
portainer

สำรอง Volume portainer_data:

teee@NP ~ % docker run –rm \
-v portainer_data:/data \
-v “$HOME”:/backup \
alpine \
tar czf /backup/portainer-backup-$(date +%F).tar.gz -C / data
Unable to find image ‘alpine:latest’ locally
latest: Pulling from library/alpine
d3531b7a4f21: Pull complete
Digest: sha256:be2656061b536c1883c4034790e21d0a09c5aaaf51968b89368a3c0371ea2c9a
Status: Downloaded newer image for alpine:latest

จากนั้นตรวจสอบไฟล์ Backup:
teee@NP ~ % ls -lh ~/portainer-backup-*.tar.gz
-rw-r–r– 1 teee staff 49K Nov 3 11:25 /Users/teee/portainer-backup-2026-11-03.tar.gz
teee@NP ~ % cd ~/Docker/Portainer.io/
teee@NP Portainer.io % ls
howto-install-portainer.io portainer-compose.yml

3. ตรวจสอบ Compose Configuration
teee@NP Portainer.io % docker compose -f portainer-compose.yml config

4. ดึง Image เวอร์ชันใหม่
ขณะนี้ Container เดิมถูก Stop อยู่แล้ว ให้รัน:
teee@NP Portainer.io % docker compose -f portainer-compose.yml pull portainer
[+] pull 8/8
✔ Image portainer/portainer-ce:latest Pulled

คำสั่งนี้จะดึง Image ล่าสุดตาม Tag latest โดยไม่แตะต้องข้อมูลใน Volume

5.เก็บ Image เดิมไว้สำหรับ Rollback
ก่อนสร้าง Container ใหม่ ให้บันทึก Image ID เดิม:

teee@NP Portainer.io % OLD_IMAGE=$(docker inspect portainer –format ‘{{.Image}}’)

echo “$OLD_IMAGE”
sha256:7a040d9261b025dcfa8d7f99490422e5025377f1d6ddcf472c1c171e87479cb1

ตั้งชื่อ Image เดิมไว้:
teee@NP Portainer.io % docker image tag “$OLD_IMAGE” portainer/portainer-ce:rollback

วิธีนี้ช่วยให้เรามี Image เดิมสำหรับย้อนกลับได้

6. สร้าง Container ใหม่
teee@NP Portainer.io % docker compose -f portainer-compose.yml up -d –force-recreate portainer
[+] up 1/1
✔ Container portainer Started

7. ตรวจสอบผลการอัปเกรด
teee@NP Portainer.io % docker ps –filter name=portainer
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
87ed559b6a22 portainer/portainer-ce:latest “/portainer” 11 seconds ago Up 10 seconds 0.0.0.0:9443->9443/tcp, [::]:9443->9443/tcp, 0.0.0.0:8443->8000/tcp, [::]:8443->8000/tcp portainer

ตรวจสอบ Log:
teee@NP Portainer.io % docker logs –tail 100 portainer
2026/11/03 04:31AM INF github.com/portainer/portainer/api/cmd/portainer/main.go:357 > encryption key file not present | filename=/run/secrets/portainer
2026/11/03 04:31AM INF github.com/portainer/portainer/api/cmd/portainer/main.go:395 > proceeding without encryption key |
2026/11/03 04:31AM INF github.com/portainer/portainer/api/database/boltdb/db.go:163 > loading PortainerDB | filename=portainer.db
2026/11/03 04:31AM INF github.com/portainer/portainer/api/database/boltdb/db.go:199 > closing PortainerDB |
2026/11/03 04:31AM INF github.com/portainer/portainer/api/datastore/backup.go:45 > Backing up database | from=/data/portainer.db to=/data/backups/portainer.db.bak
2026/11/03 04:31AM INF github.com/portainer/portainer/api/database/boltdb/db.go:163 > loading PortainerDB | filename=portainer.db
2026/11/03 04:31AM INF github.com/portainer/portainer/api/datastore/migrate_data.go:117 > migrating database from version 2.45.1 to 2.45.3 |
2026/11/03 04:31AM INF github.com/portainer/portainer/api/datastore/migrator/migrate_ce.go:76 > db migrated to 2.45.3 |
2026/11/03 04:31AM INF github.com/portainer/portainer/pkg/libhelm/cache/manager.go:30 > Helm registry cache initialized | user_session_timeout=8h
2026/11/03 04:31AM INF github.com/portainer/portainer/api/chisel/service.go:201 > found Chisel private key file on disk | private-key=/data/chisel/private-key.pem
2026/11/03 04:31:01 server: Reverse tunnelling enabled
2026/11/03 04:31:01 server: Fingerprint o6plckpkDx7qwMAfgE0R2/hsPJf0J7pK/Z/xeu/71yc=
2026/11/03 04:31:01 server: Listening on http://0.0.0.0:8000
2026/11/03 04:31AM INF github.com/portainer/portainer/api/datastore/postinit/migrate_post_init.go:141 > executing post init migration for environment | endpoint_id=3
2026/11/03 04:31AM INF github.com/portainer/portainer/api/cmd/portainer/main.go:705 > starting Portainer | build_number=41 go_version=go1.26.10 image_tag=2.45.3-linux-arm64 nodejs_version=v22.23.3 pnpm_version=10.27.0 version=2.45.3 webpack_version=5.107.2
2026/11/03 04:31AM INF github.com/portainer/portainer/api/http/server.go:371 > starting HTTPS server | bind_address=:9443
2026/11/03 04:31AM INF github.com/portainer/portainer/api/http/server.go:355 > starting HTTP server | bind_address=:9000

ตรวจสอบ Image:
teee@NP Portainer.io % docker inspect portainer –format ‘{{.Config.Image}}’
portainer/portainer-ce:latest

8. หากพบปัญหา ให้ Rollback
แก้ Image ใน portainer-compose.yml จาก:
image: portainer/portainer-ce:latest
เป็น
image: portainer/portainer-ce:rollback

แล้วสั่ง:
teee@NP Portainer.io % docker compose -f portainer-compose.yml up -d –force-recreate portainer

ข้อควรระวัง: Rollback Image ไม่ได้ย้อนการเปลี่ยนแปลงโครงสร้าง Database ที่ Version ใหม่อาจทำไปแล้ว ดังนั้นควรเก็บ Backup ไว้จนกว่าจะตรวจสอบระบบเรียบร้อย

Docker Virtualization Support

เปิด Docker Desktop แล้ว Error ตามรูป

อาการนี้คือ /dev/kvm ไม่มีอยู่บนเครื่อง แปลว่าโมดูล KVM ในเคอร์เนลไม่ถูกโหลด หรือ virtualization ถูกปิดอยู่ที่ระดับ BIOS/hypervisor สาเหตุเจอบ่อยสุดมี 3 อย่าง ไล่เช็กตามลำดับนี้

1.เช็กว่า CPU รองรับและเปิดอยู่ไหม
#egrep -c ‘(vmx|svm)’ /proc/cpuinfo
ผลลัพธ์ 0 = CPU ไม่รองรับ หรือปิดไว้ใน BIOS/UEFI ต้องเข้า BIOS ไปเปิด Intel VT-x (Intel Virtualization Technology) หรือ SVM Mode (AMD-V) แล้วบูตใหม่
ผลลัพธ์ > 0 = ไปข้อ 2

2. โหลดโมดูล KVM และทำให้ถาวร
# Intel
sudo modprobe kvm_intel
# AMD
sudo modprobe kvm_amd

#ls -l /dev/kvm
ถ้าเจอ /dev/kvm แล้ว ให้ตั้งให้โหลดทุกครั้งที่บูต:
# Intel
echo kvm_intel | sudo tee /etc/modules-load.d/kvm.conf
# AMD
echo kvm_amd | sudo tee /etc/modules-load.d/kvm.conf

ถ้า modprobe ฟ้อง error ให้ดูสาเหตุด้วย sudo dmesg | grep -i kvm ถ้าขึ้นว่า “disabled by bios” ก็กลับไปแก้ข้อ 1

3. ให้สิทธิ์ user เข้าถึง /dev/kvm

#sudo usermod -aG kvm $USER

จากนั้น logout แล้ว login ใหม่ (หรือรีบูต) แล้วเช็กด้วย groups ว่ามี kvm และ ls -l /dev/kvm ว่ากลุ่มเป็น kvm

ถ้าเครื่องนี้เป็น VM (เช่น รันบน WSL2, VMware, Proxmox, Hyper-V, cloud)
ต้องเปิด nested virtualization ที่ฝั่ง host ก่อน ไม่งั้น /dev/kvm จะไม่โผล่ในเครื่องลูก

> Proxmox: ตั้ง CPU type เป็น host แล้วเช็ก cat /sys/module/kvm_intel/parameters/nested ที่ host ให้เป็น Y
> VMware: ติ๊ก “Virtualize Intel VT-x/EPT or AMD-V/RVI” ใน VM settings
> Hyper-V: Set-VMProcessor -VMName <ชื่อ> -ExposeVirtualizationExtensions $true
> WSL2: ต้องใช้เคอร์เนล WSL ที่รองรับ และเพิ่ม nestedVirtualization=true ใน %UserProfile%\.wslconfig (Windows 11) แล้ว wsl –shutdown
> Cloud VM: ส่วนใหญ่ไม่รองรับ ต้องเลือก instance ที่รองรับ nested หรือ bare metal

ถ้ามี Docker Desktop for Linux

หลังแก้เสร็จ ลองรีสตาร์ต: # systemctl –user restart docker-desktop

ทั้งนี้ ถ้าเป็นเซิร์ฟเวอร์ที่ไม่จำเป็นต้องใช้ GUI ของ Docker Desktop จริง ๆ การใช้ Docker Engine ธรรมดา (docker-ce) จะไม่ต้องพึ่ง KVM เลย และเบากว่ามาก
หรือลง portainer.io เพื่อที่จะเข้าผ่านเว็บ

teee@NP Portainer.io % cat portainer-compose.yml
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: unless-stopped

ports:
– “8443:8000”
– “9443:9443”

volumes:
– /var/run/docker.sock:/var/run/docker.sock
– portainer_data:/data

volumes:
portainer_data:
name: portainer_data

เปิด Log Monitor เพื่อไปเอา setup_tokenไปกรอกตอนลงทะเบียนหน้าเว็บครั้งแรก
teee@NP Portainer.io % docker logs portainer –tail 50