SSD Nodes Learn Hosting plans →
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-10-20

วิธีตั้งค่า Docker Compose ให้รันอัตโนมัติหลัง Reboot

เรียนรู้วิธีตั้งค่า Docker Compose ให้เริ่มทำงานเองหลังรีบูตเครื่องด้วย restart policy รวมถึงข้อแตกต่างระหว่างการใช้ unless-stopped กับการเขียน systemd unit เพื่อจัดการลำดับการทำงาน

คำตอบโดยย่อ

บริการ Docker Compose จะเริ่มทำงานเมื่อบูตเครื่องเมื่อเงื่อนไขสองประการเกิดขึ้นพร้อมกัน ประการแรก Docker daemon ต้องถูกเปิดใช้งานเป็น system service และประการที่สอง แต่ละบริการในไฟล์ต้องมีนโยบายการรีสตาร์ทเป็น unless-stopped หรือ always ให้เพิ่ม restart: unless-stopped ลงในทุกบริการและรันคำสั่ง docker compose up -d หนึ่งครั้ง คอนเทนเนอร์จะกลับมาทำงานเองโดยอัตโนมัติหลังจากรีบูตเครื่อง สำหรับกรณีทั่วไปไม่จำเป็นต้องตั้งค่าอื่นเพิ่มเติม

คุณจำเป็นต้องใช้ systemd unit ก็ต่อเมื่อลำดับการทำงานมีความสำคัญ เช่น stack ที่ต้องพึ่งพา disk ที่ mount ไว้, VPN interface หรือ network share ที่ยังไม่พร้อมใช้งานในขณะที่ Docker daemon เริ่มทำงาน กรณีนี้เป็นปัญหาที่เกิดขึ้นจริง และเนื้อหาในส่วนที่สองของคู่มือนี้จะครอบคลุมวิธีจัดการ หากคุณยังอยู่ในช่วงเริ่มต้นทำความเข้าใจเกี่ยวกับการกำหนดค่าบริการและ volume ให้เริ่มจาก พื้นฐานของ Docker Compose บน VPS แล้วค่อยกลับมาอ่านส่วนนี้อีกครั้ง

กำหนดนโยบายการรีสตาร์ทใน compose.yaml

นโยบายนี้กำหนดได้หนึ่งบรรทัดต่อหนึ่งบริการ ไม่มีสวิตช์ส่วนกลาง ดังนั้นบริการที่คุณลืมกำหนดค่าจะหยุดทำงานหลังรีบูต ในขณะที่บริการอื่นใน stack จะเริ่มทำงานตามปกติ

services:
  app:
    image: nginx:1.27
    restart: unless-stopped
    ports:
      - "8080:80"
  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: change-me
    volumes:
      - dbdata:/var/lib/postgresql/data

volumes:
  dbdata:

ใช้การตั้งค่านี้แล้วตรวจสอบนโยบายจากคอนเทนเนอร์ที่กำลังทำงานอยู่:

docker compose up -d
docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' $(docker compose ps -q app)

คำสั่งนี้จะแสดงผลเป็น unless-stopped หากแสดงผลเป็น no แสดงว่ามีการแก้ไขไฟล์แล้วแต่คอนเทนเนอร์ยังไม่ได้ถูกสร้างใหม่

นี่คือสาเหตุความล้มเหลวที่พบบ่อยที่สุด นโยบายการรีสตาร์ทจะถูกเก็บไว้ที่ตัว container ไม่ใช่ในไฟล์ YAML การแก้ไข compose.yaml จะไม่มีผลใดๆ กับคอนเทนเนอร์ที่มีอยู่เดิม ส่วน docker compose restart ก็ไม่ช่วยเช่นกัน เพราะเป็นการหยุดและเริ่มคอนเทนเนอร์ตัวเดิมโดยไม่ได้แตะต้องค่าคอนฟิกูเรชัน มีเพียง docker compose up -d เท่านั้นที่จะเปรียบเทียบไฟล์กับคอนเทนเนอร์ที่ทำงานอยู่ ตรวจพบว่านโยบายมีการเปลี่ยนแปลง และทำการสร้างคอนเทนเนอร์ใหม่ให้

สำหรับคอนเทนเนอร์ที่คุณยังไม่ต้องการสร้างใหม่ในขณะนี้ ให้เปลี่ยนนโยบายโดยตรงที่ตัวคอนเทนเนอร์:

docker update --restart unless-stopped my-container

อย่างไรก็ตาม คุณยังต้องแก้ไขไฟล์ YAML ควบคู่ไปด้วย เพราะ docker update จะเปลี่ยนค่าในคอนเทนเนอร์ที่ทำงานอยู่เท่านั้น และการใช้ docker compose up -d ในครั้งถัดไปจะอ่านค่าจากไฟล์และนำค่านโยบายเดิมกลับมาเขียนทับอีกครั้ง

การทำงานของค่า restart แต่ละแบบ

Docker กำหนดค่าไว้ 4 รูปแบบ ซึ่งความแตกต่างจะปรากฏให้เห็นเมื่อเครื่องรีบูตหรือเมื่อ Docker daemon เริ่มทำงานใหม่เท่านั้น

  • no เป็นค่าเริ่มต้น คอนเทนเนอร์จะไม่ถูกรีสตาร์ทโดยอัตโนมัติไม่ว่าในกรณีใดก็ตาม
  • always จะรีสตาร์ทคอนเทนเนอร์ทุกครั้งที่หยุดทำงาน หากคุณหยุดคอนเทนเนอร์ด้วยตนเอง มันจะกลับมาทำงานอีกครั้งเมื่อ Docker daemon เริ่มทำงานใหม่ ซึ่งมักจะสร้างความประหลาดใจได้ เพราะคอนเทนเนอร์ที่คุณตั้งใจหยุดไปเมื่อสัปดาห์ก่อนจะกลับมาทำงานอีกครั้งหลังรีบูต
  • unless-stopped มีการทำงานคล้ายกับ always แต่มีข้อแตกต่างคือ หากคอนเทนเนอร์ถูกหยุดด้วยตนเอง มันจะยังคงหยุดทำงานอยู่แม้จะมีการรีสตาร์ท daemon นี่คือค่าที่เหมาะสมสำหรับบริการที่คุณต้องการหยุดเพื่อบำรุงรักษาเป็นครั้งคราว
  • on-failure จะรีสตาร์ทคอนเทนเนอร์เฉพาะเมื่อมีการออกจากโปรแกรม (exit) ด้วย exit code ที่ไม่ใช่ 0 เท่านั้น คุณสามารถจำกัดจำนวนครั้งที่พยายามรีสตาร์ทได้ ดังเช่นใน restart: on-failure:3

สำหรับ stack ที่ควรจะทำงานอยู่เสมอเมื่อเซิร์ฟเวอร์เปิดใช้งาน unless-stopped คือค่าเริ่มต้นที่เหมาะสมที่สุด ให้เลือกใช้ always เฉพาะในกรณีที่คุณต้องการคอนเทนเนอร์ที่ไม่ยอมหยุดทำงานแม้จะถูกสั่งปิดไปแล้วก็ตาม

เหตุผลที่ restart: on-failure ไม่ทำงานหลังการรีบูต

หลายคนเลือกใช้ on-failure เพราะดูเหมือนเป็นตัวเลือกที่ปลอดภัย แต่กลับพบว่าคอนเทนเนอร์ทั้งหมดหยุดทำงานหลังจากรีบูตครั้งแรก สาเหตุอยู่ในนิยามของมัน on-failure จะตอบสนองต่อกรณีเดียวเท่านั้น คือเมื่อกระบวนการของคอนเทนเนอร์จบการทำงานด้วยรหัสข้อผิดพลาด (error code)

การรีบูตไม่ใช่ข้อผิดพลาด เมื่อโฮสต์ปิดตัวลง systemd จะหยุด docker.service และ daemon จะสั่งหยุดคอนเทนเนอร์แต่ละตัวอย่างตั้งใจ คอนเทนเนอร์ไม่ได้ล้มเหลว นโยบายนี้จึงไม่มีเหตุให้ต้องทำงาน ในขณะที่ระบบเริ่มทำงานใหม่ daemon จะตรวจสอบคอนเทนเนอร์ที่จำเป็นต้องเรียกคืน แต่คอนเทนเนอร์แบบ on-failure ที่ถูกหยุดอย่างถูกต้องจะไม่ถูกรวมอยู่ในนั้น มันจึงค้างอยู่ในสถานะ exited

คุณสามารถตรวจสอบได้โดยตรง กำหนด restart: on-failure ให้กับ service รัน docker compose up -d แล้วรีบูต จากนั้นรัน:

docker compose ps -a

Service จะแสดงสถานะเป็น Exited และมีสถานะเหมือน Exited (0) 2 minutes ago ไม่มีสิ่งใดเสียหายและไม่มีการบันทึกข้อผิดพลาด ซึ่งเป็นสาเหตุที่ทำให้วินิจฉัยปัญหานี้ได้ยาก นโยบายนี้ทำงานตรงตามที่ระบุไว้ทุกประการ

on-failure ยังคงมีประโยชน์ มันเหมาะสำหรับคอนเทนเนอร์ที่รันงานและอาจเกิดการ crash ได้ โดยตัวมันเอง restart: on-failure ไม่มีการจำกัดจำนวนครั้งและจะพยายามรีสตาร์ทงานที่ล้มเหลวซ้ำๆ ต่อไปเรื่อยๆ ดังนั้นควรเพิ่มขีดจำกัด เช่น restart: on-failure:3 เมื่อคุณต้องการจำกัดจำนวนครั้งในการลองใหม่และป้องกันไม่ให้เกิดลูปการรีสตาร์ท แต่นี่เป็นเครื่องมือที่ไม่เหมาะสมสำหรับการรักษา service ที่รันต่อเนื่องให้ทำงานอยู่ตลอดหลังการรีบูต

นโยบายการรีสตาร์ทจะทำงานก็ต่อเมื่อ Docker service เริ่มทำงานตอนบูตเครื่องเท่านั้น

นโยบายการรีสตาร์ทถูกบังคับใช้โดย Docker daemon หาก daemon ไม่เริ่มทำงาน ก็จะไม่มีสิ่งใดบังคับใช้นโยบายเหล่านี้ได้ ให้ตรวจสอบดังนี้:

systemctl is-enabled docker
systemctl is-enabled containerd

ทั้งสองคำสั่งควรแสดงผลเป็น enabled แพ็กเกจจาก repository อย่างเป็นทางการของ Docker จะเปิดใช้งานสิ่งเหล่านี้ไว้ตั้งแต่ตอนติดตั้ง ดังนั้นบนเซิร์ฟเวอร์ที่ติดตั้งใหม่มักจะผ่านการตรวจสอบนี้ หากคำสั่งใดแสดงผลเป็น disabled ให้แก้ไขดังนี้:

sudo systemctl enable --now docker containerd

มีกับดักที่ควรทำความเข้าใจอยู่จุดหนึ่ง Ubuntu มี docker.socket มาให้ด้วย ซึ่งจะเริ่ม daemon ตามความต้องการในครั้งแรกที่มีการเรียกใช้งาน Docker API ผู้ใช้งานมักเห็นว่า docker.socket ถูกเปิดใช้งานอยู่ จึงเข้าใจไปว่า daemon ได้รับการจัดการเรียบร้อยแล้ว และทำการปิด docker.service เพื่อประหยัดหน่วยความจำ ในขณะบูตเครื่องจะไม่มีการเรียกใช้งาน API ดังนั้น socket จึงไม่ถูกเรียกใช้ daemon จึงไม่เริ่มทำงาน และจะไม่มี container ใดขึ้นมาจนกว่าคุณจะพิมพ์คำสั่ง docker ครั้งแรก การทำ socket activation ไม่สามารถใช้แทนการเปิดใช้งาน docker.service ได้

เมื่อ systemd unit เป็นทางเลือกที่ดีกว่า

นโยบายการ restart ไม่มีกลไกในการจัดการลำดับการทำงานเมื่อเทียบกับส่วนอื่นของระบบ เมื่อ daemon เริ่มทำงาน มันจะพยายามนำ container ของคุณขึ้นมาทันทีที่ทำได้ หาก stack ของคุณมีการ bind-mount ไดเรกทอรีจาก volume แยก, NFS (network file system) share หรือดิสก์ที่เข้ารหัสไว้ container อาจเริ่มทำงานก่อนที่ path ดังกล่าวจะพร้อมใช้งาน Docker จะสร้างไดเรกทอรีว่างที่จุด mount นั้นและเริ่ม container โดยอัตโนมัติ ส่งผลให้ฐานข้อมูลของคุณเริ่มทำงานโดยไม่มีข้อมูล

ให้เขียน systemd unit เมื่อเข้าเงื่อนไขใดเงื่อนไขหนึ่งต่อไปนี้: stack ต้องการ mount, VPN interface หรือ unit อื่นให้พร้อมใช้งานก่อน คุณต้องการให้ systemctl stop myapp และ systemctl start myapp ทำงานเหมือนกับ service อื่นๆ บนเครื่อง หรือคุณต้องการให้ stack ถูกปิดอย่างถูกต้องในระหว่างการ shutdown แทนที่จะถูก kill ไปพร้อมกับ daemon หากคุณยังไม่คุ้นเคยกับ systemd unit เนื้อหาใน การเขียน systemd service และ timer จะอธิบายรูปแบบไฟล์ไว้อย่างละเอียด

การเขียน systemd unit

วาง stack ไว้ใน path ที่กำหนดไว้นอก home directory /srv/myapp เป็นตัวเลือกที่ดี เพราะ unit ที่รันก่อนที่ผู้ใช้จะล็อกอินไม่ควรเข้าถึง /home

สร้าง /etc/systemd/system/myapp.service:

[Unit]
Description=myapp docker compose stack
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target
RequiresMountsFor=/srv/myapp/data

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/srv/myapp
ExecStart=/usr/bin/docker compose up -d --remove-orphans
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target

เปิดใช้งานและเริ่มการทำงาน:

sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service
systemctl status myapp.service

Unit ที่ทำงานปกติจะแสดงสถานะ Active: active (exited) ซึ่งอาจดูไม่ถูกต้องในครั้งแรกที่คุณเห็น แต่นี่คือสิ่งที่ถูกต้อง: Type=oneshot พร้อมด้วย RemainAfterExit=yes หมายความว่า unit ได้รันคำสั่งแล้ว คำสั่งเสร็จสิ้น และ systemd ยังคงทำเครื่องหมาย unit ว่า active เพื่อให้ ExecStop ทำงานตอนปิดระบบ

ทุกบรรทัดมีความสำคัญ Requires=docker.service หมายความว่า unit จะล้มเหลวทันทีแทนที่จะรัน docker compose กับ socket ที่ตายแล้ว After= กำหนดลำดับการทำงาน เพราะ Requires= เพียงอย่างเดียวไม่ได้กำหนดลำดับไว้ RequiresMountsFor= ทำให้ systemd ดึง mount unit สำหรับ path นั้นมาใช้งานและรอจนกว่าจะพร้อม ซึ่งเป็นเหตุผลหลักที่ต้องใช้ unit แทนการพึ่งพานโยบายการรีสตาร์ทเพียงอย่างเดียว TimeoutStartSec=0 ป้องกันไม่ให้ systemd สั่งยกเลิกงาน start ในขณะที่กำลังดึง image ขนาดใหญ่

ข้อควรทราบเกี่ยวกับการใช้กลไกทั้งสองร่วมกัน เอกสารของ Docker แนะนำไม่ให้ใช้ restart policies ร่วมกับ process manager ระดับโฮสต์ โดยระบุว่าจะทำให้เกิดความขัดแย้ง ความขัดแย้งเกิดจาก process manager ที่คอยดูแลกระบวนการของคอนเทนเนอร์โดยตรงและพยายามรีสตาร์ทในขณะที่ daemon ก็พยายามทำเช่นเดียวกัน Unit แบบ Type=oneshot ไม่ได้ดูแลกระบวนการใดๆ ดังนั้นการคง restart: unless-stopped ไว้ในไฟล์ compose ควบคู่ไปกับ unit นี้จึงไม่มีปัญหาและเป็นสิ่งที่ควรทำ systemd จะจัดการลำดับการทำงานตอนบูต ส่วน daemon จะจัดการคอนเทนเนอร์ที่เกิด crash ในช่วงเวลาอื่น

Unit จะมีลักษณะแตกต่างออกไปเมื่อสิ่งที่คุณต้องการรักษาให้ทำงานอยู่เป็นกระบวนการที่รันต่อเนื่องทั่วไป (long-running process) ไม่ใช่ stack เพราะจะไม่มี daemon อยู่เบื้องหลัง และ Restart= ของ systemd เองจะต้องทำหน้าที่ดูแลกระบวนการนั้น การรัน dsh แบบ headless หลัง systemd เป็นตัวอย่างการใช้งานในรูปแบบดังกล่าว รวมถึงการกำหนดผู้ใช้เฉพาะและการจัดการ journal

ตรวจสอบด้วยการรีบูตจริง

ไม่มีสิ่งใดทดแทนการทดสอบจริงได้ systemctl restart docker ไม่ได้ทดสอบลำดับการ mount และ docker compose down ตามด้วย docker compose up -d ไม่ได้ทดสอบกระบวนการบูตแต่อย่างใด

sudo reboot

รอให้ระบบกลับมา เชื่อมต่อใหม่ และตรวจสอบตามลำดับดังนี้:

uptime
systemctl is-active docker
docker compose ps

uptime ยืนยันว่าคุณกำลังตรวจสอบเครื่องที่รีบูตจริง docker compose ps ซึ่งรันจากไดเรกทอรีของ stack ควรแสดงรายการทุกบริการเป็น running โดยมีค่า uptime ใกล้เคียงกับของเครื่อง บริการที่แสดงสถานะ Exited คือจุดที่ต้องตรวจสอบ

หากมีบางอย่างไม่ทำงาน ให้ดู log ของ daemon ในช่วงเวลาที่บูต:

journalctl -u docker.service -b --no-pager | tail -50

สำหรับ stack ที่จัดการด้วย unit นั้น journalctl -u myapp.service -b --no-pager จะแสดงผลลัพธ์ docker compose ที่เกิดขึ้นจริงตั้งแต่ตอนบูต รวมถึงกรณีที่ดึง image ล้มเหลวหรือไฟล์ .env หายไป การรีบูตที่คุณกำหนดเวลาไว้คือสิ่งที่คุณต้องเฝ้าดู ดังนั้นให้ unit แจ้งเตือนคุณเกี่ยวกับสิ่งที่ไม่ได้เป็นไปตามแผน โดยการใช้บรรทัด OnFailure= ชี้ไปยัง เซิร์ฟเวอร์ ntfy ที่โฮสต์เอง จะเปลี่ยน stack ที่ไม่สามารถกลับมาทำงานได้ให้กลายเป็นการแจ้งเตือนแบบ push แทนที่จะเป็นปัญหาที่คุณเพิ่งมาพบในอีกหลายวันให้หลัง

สาเหตุที่ทำให้การเริ่มทำงานอัตโนมัติล้มเหลวโดยไม่แจ้งเตือน

คอนเทนเนอร์ที่สร้างด้วย docker compose run จะไม่ได้รับนโยบายการรีสตาร์ทจากไฟล์ Compose จะมองว่าคอนเทนเนอร์เหล่านั้นเป็นแบบใช้ครั้งเดียว หากบริการดูเหมือนจะเพิกเฉยต่อนโยบายของคุณ ให้ตรวจสอบว่าบริการนั้นถูกเริ่มด้วย run แทนที่จะเป็น up หรือไม่

พาธแบบสัมพัทธ์ (relative path) ใน volume หรือในรายการ env_file จะถูกอ้างอิงจากไดเรกทอรีของไฟล์ compose ซึ่งทำงานได้ปกติเมื่อรันจาก shell และทำงานได้จาก unit ที่ตั้งค่า WorkingDirectory ไว้ แต่จะล้มเหลวหาก unit นั้นไม่มีการตั้งค่าดังกล่าว เพราะไดเรกทอรีทำงาน (working directory) จะกลายเป็น / แทน

Rootless Docker เป็นกรณีเฉพาะ เนื่องจาก daemon ทำงานในฐานะ user service และ user service จะหยุดทำงานเมื่อ session สุดท้ายของผู้ใช้นั้นสิ้นสุดลง ให้เปิดใช้งานสำหรับผู้ใช้และอนุญาตให้ทำงานต่อไปได้แม้ไม่มีใครล็อกอินอยู่:

systemctl --user enable docker
sudo loginctl enable-linger $USER

หากไม่มี enable-linger ตัว rootless daemon จะปิดตัวลงเมื่อคุณล็อกเอาต์และคอนเทนเนอร์ทั้งหมดจะหยุดทำงานตามไปด้วย ซึ่งดูเหมือนกับนโยบายการรีสตาร์ทมีปัญหา

สิ่งสุดท้ายคือ การอัปเดตความปลอดภัยอัตโนมัติอาจรีบูตเซิร์ฟเวอร์ตามเวลาที่กำหนด ซึ่งจะเป็นเรื่องดีก็ต่อเมื่อ stack ของคุณสามารถกลับมาทำงานได้เอง การตั้งค่าส่วนนี้ควรทำพร้อมกับงานอื่นๆ ในชั่วโมงแรกของการติดตั้งใน สิบนาทีแรกบน VPS เครื่องใหม่

FAQ

restart: always กับ restart: unless-stopped ต่างกันอย่างไร

ทั้งสองคำสั่งจะเริ่ม container ใหม่เมื่อหยุดทำงานเองโดยอัตโนมัติ แต่จะมีความแตกต่างเมื่อคุณหยุด container ด้วยตนเอง หากใช้ always ตัว container จะเริ่มทำงานใหม่ในครั้งถัดไปที่ Docker daemon เริ่มทำงาน ดังนั้นการรีบูตเครื่องจะทำให้สถานะการหยุดด้วยตนเองของคุณถูกยกเลิก แต่หากใช้ unless-stopped ตัว daemon จะจดจำว่า container ถูกหยุดโดยเจตนาและจะไม่ไปยุ่งกับมัน ให้ใช้ unless-stopped เว้นแต่ว่าคุณต้องการให้ container นั้นทำงานตลอดเวลาโดยไม่ยอมหยุด

ฉันเพิ่ม restart: unless-stopped แล้ว แต่ container ยังไม่เริ่มทำงานหลังรีบูต เพราะอะไร

นโยบายนี้จะผูกอยู่กับตัว container ไม่ใช่ที่ไฟล์ config และ container ที่สร้างไปแล้วจะไม่ถูกอัปเดตเพียงแค่การแก้ไขไฟล์ YAML ให้รันคำสั่ง docker compose up -d เพื่อให้ Compose สร้าง container ขึ้นมาใหม่ จากนั้นตรวจสอบด้วย docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' $(docker compose ps -q app) หากผลลัพธ์แสดง no แสดงว่า container นั้นถูกสร้างขึ้นก่อนที่คุณจะแก้ไขไฟล์ สาเหตุทั่วไปอีกประการหนึ่งคือ docker.service ไม่ได้ถูกเปิดใช้งาน ซึ่งคุณสามารถตรวจสอบได้ด้วย systemctl is-enabled docker

ฉันจำเป็นต้องใช้ systemd unit หรือไม่หากใช้นโยบาย restart อยู่แล้ว

โดยปกติแล้วไม่จำเป็น นโยบาย restart เพียงพอสำหรับ stack ที่ต้องการเพียงแค่เครือข่าย ซึ่งเป็นกรณีส่วนใหญ่ ให้เพิ่ม unit เข้าไปก็ต่อเมื่อ container มีความจำเป็นต้องพึ่งพาสิ่งที่ยังไม่พร้อมในขณะที่ Docker daemon เริ่มทำงาน เช่น ดิสก์ภายนอก, encrypted volume, NFS share หรือ VPN interface ตัว unit จะช่วยให้คุณกำหนดลำดับการทำงานผ่าน After= และ RequiresMountsFor= ซึ่งนโยบาย restart ไม่สามารถทำได้

ฉันจะหยุด stack อย่างถาวรไม่ให้กลับมาทำงานใหม่หลังรีบูตได้อย่างไร

หากใช้ unless-stopped การใช้คำสั่ง docker compose stop ก็เพียงพอแล้ว เพราะ container ที่ถูกหยุดด้วยตนเองจะไม่ถูกเริ่มใหม่เมื่อ daemon เริ่มทำงาน แต่หากใช้ always การหยุดเพียงอย่างเดียวไม่เพียงพอและ container จะกลับมาทำงานใหม่หลังรีบูต ให้รัน docker compose down เพื่อลบ container ทิ้ง หรือเปลี่ยนนโยบายก่อนด้วย docker update --restart no my-container หากมี systemd unit คอยจัดการ stack อยู่ ให้รัน sudo systemctl disable myapp.service ด้วย มิฉะนั้น unit จะสั่งให้มันเริ่มทำงานใหม่อีกครั้ง

บทความนี้มีประโยชน์หรือไม่