ฉันจะทำให้คอนเทนเนอร์ Docker เริ่มต้นโดยอัตโนมัติเมื่อบูตระบบได้อย่างไร


111

สมมติว่าฉันมีคอนเทนเนอร์ Docker ที่ฉันต้องการเรียกใช้ฉันสามารถโทรได้

$ docker run ...

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

ถ้าเป็นเช่นนั้นจะมีใน Docker Compose ด้วยหรือไม่

คำตอบ:


134

ใช่นักเทียบท่ามีนโยบายการรีสตาร์ทเช่นdocker run --restart=alwaysที่จะจัดการสิ่งนี้ นอกจากนี้ยังมีอยู่ในไฟล์ config compose.ymlเป็นไฟล์restart: always .


25
นี่เป็นคำตอบแรกและเป็นที่ยอมรับอย่างไรก็ตามคนส่วนใหญ่ที่ค้นหาคุณลักษณะนั้นต้องการเรียกใช้คอนเทนเนอร์ของตนเป็นบริการจริงๆ คำตอบ @kon 's ใช้Systemdเป็นผู้จัดการบริการเป็นหนึ่งในโซลูชั่นที่ดีที่สุดสำหรับวัตถุประสงค์ที่ต้องการและ upvotes เพิ่มเติม
Rémi Becheras

1
สิ่งนี้ไม่ได้ผลกับฉัน ฉันมีคอนเทนเนอร์ชื่อ "crmpicco-mysql" และฉันวิ่งdocker run --restart=always crmpicco-mysqlและได้รับข้อผิดพลาด: Unable to find image 'crmpicco-mysql:latest' locally.
crmpicco

2
ข้อผิดพลาดของคุณไม่เกี่ยวข้องกัน คุณอาจต้องการโพสต์คำถามแยกกัน แต่ดูเหมือนว่าคุณกำลังสับสนชื่ออิมเมจนักเทียบท่าและชื่อคอนเทนเนอร์นักเทียบท่า คำสั่งคาดว่าชื่อของภาพซึ่งคุณสามารถแสดงรายการผ่านทางนั้นdocker run docker images
Peter Lyons

12
ปัญหาเดียวของปัญหานี้คือ "always" จะรีสตาร์ทคอนเทนเนอร์อย่างไม่สิ้นสุดเมื่อหยุดทำงานเนื่องจากข้อผิดพลาด (ดูเอกสาร) ควรมีนโยบายที่เริ่มใน daemon-start เท่านั้น
lostiniceland

4
ฉันคิดว่าจุดขายที่สำคัญอย่างหนึ่งของคอนเทนเนอร์ / นักเทียบท่าคือฉันไม่จำเป็นต้องติดตั้งและจัดการแต่ละบริการของฉันใน systemd (ซึ่งอาจเป็นความเจ็บปวด)
Marc

141

หากคุณต้องการให้คอนเทนเนอร์เริ่มทำงานแม้ว่าจะไม่มีผู้ใช้ใดทำการเข้าสู่ระบบ (เช่น VirtualBox VM ที่ฉันเพิ่งเริ่มต้นและไม่ต้องการเข้าสู่ระบบทุกครั้ง) นี่คือขั้นตอนที่ฉันทำสำหรับ Ubuntu 16.04 LTS ตัวอย่างเช่นฉันติดตั้ง oracle db container:

$ docker pull alexeiled/docker-oracle-xe-11g
$ docker run -d --name=MYPROJECT_oracle_db --shm-size=2g -p 1521:1521 -p 8080:8080 alexeiled/docker-oracle-xe-11g
$ vim /etc/systemd/system/docker-MYPROJECT-oracle_db.service

และเพิ่มเนื้อหาต่อไปนี้:

[Unit]
Description=Redis container
Requires=docker.service
After=docker.service

[Service]
Restart=always
ExecStart=/usr/bin/docker start -a MYPROJECT_oracle_db
ExecStop=/usr/bin/docker stop -t 2 MYPROJECT_oracle_db

[Install]
WantedBy=default.target

และเปิดใช้งานบริการเมื่อเริ่มต้น

sudo systemctl enable docker-MYPROJECT-oracle_db.service

สำหรับข้อมูลเพิ่มเติมhttps://docs.docker.com/engine/admin/host_integration/


9
สำหรับผู้ที่ต้องการทำสิ่งนี้ด้วยนักเทียบท่าคุณสามารถแทนที่dockerคำสั่งด้านบนด้วยdocker-composeคำสั่งโดยใช้-fแฟล็กเพื่อระบุตำแหน่งของไฟล์นักเทียบท่า:/usr/bin/docker-compose -f /path/to/docker-compose.yml up
charlesreid1

1
หากต้องการเพิ่มสิ่งที่ @ charlesreid1 กล่าวหากคุณdocker-compose.ymlระบุ.envไฟล์ให้ใช้--project-directory /path/to นอกเหนือจากการระบุไฟล์เขียนนักเทียบท่าของคุณอย่างชัดเจน
whlteXbread

1
Docker มีระบบบันทึกและตัวจัดการกระบวนการ โชคไม่ดีที่ไม่มีนโยบายการรีสตาร์ทที่ถูกต้อง
Franklin Yu

มีความคิดอย่างไรกับ Windows Server 2012 ฉันไม่สามารถเรียกใช้นักเทียบท่าได้เว้นแต่ฉันจะเข้าสู่ระบบ ...
Alex Lord Mordor

นอกจากนี้ยังอาจจะสนใจบางอย่างที่มีประโยชน์คำสั่งที่เรียกว่า[Unit] Before=โดยเฉพาะอย่างยิ่งเมื่อเริ่มต้นสิ่งต่างๆเช่นระบบการจัดการฐานข้อมูลการตรวจสอบให้แน่ใจว่าระบบเริ่มต้นก่อนบริการอื่น ๆอาจเป็นประโยชน์
ปาสเตอร์

92

นโยบายการรีสตาร์ทเริ่มต้นnoคือ

สำหรับคอนเทนเนอร์ที่สร้างขึ้นใช้docker updateเพื่ออัปเดตนโยบายการรีสตาร์ท

docker update --restart=always 0576df221c0b

0576df221c0b คือรหัสคอนเทนเนอร์


ไม่ได้alwaysหมายความว่าคอนเทนเนอร์จะรีสตาร์ทแม้ว่าฉันจะหยุดมัน? แน่นอนว่ามีวิธีการรีสตาร์ทคอนเทนเนอร์ในการรีบูตโดยไม่ต้องเริ่มต้นอย่างต่อเนื่อง ...
Marc

4
@ มาร์ค: ไม่นะ ดูเอกสารประกอบ :If you manually stop a container, its restart policy is ignored until the Docker daemon restarts or the container is manually restarted. This is another attempt to prevent a restart loop.
SaeX

15

คุณสามารถใช้docker update --restart=on-failure <container ID or name>.

นอกเหนือจากสิ่งที่ชื่อแนะนำon-failureจะไม่เพียงรีสตาร์ทคอนเทนเนอร์เมื่อเกิดความล้มเหลว แต่ยังเมื่อบูตระบบด้วย

ตามเอกสารประกอบมีตัวเลือกการรีสตาร์ทหลายตัว:

Flag            Description
no              Do not automatically restart the container. (the default)
on-failure      Restart the container if it exits due to an error, which manifests as a non-zero exit code.
always          Always restart the container if it stops. If it is manually stopped, it is restarted only when Docker daemon restarts or the container itself is manually restarted. (See the second bullet listed in restart policy details)
unless-stopped  Similar to always, except that when the container is stopped (manually or otherwise), it is not restarted even after Docker daemon restarts.

3
ว้าวเป็นงานที่ดีเมื่อพบสิ่งนี้เนื่องจากไม่ได้ระบุไว้ในเอกสาร ทางออกที่สมบูรณ์แบบสำหรับฉัน
Cameron Hudson

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

12

1) ก่อนอื่นคุณต้องเปิดใช้งานบริการนักเทียบท่าในการบูต

$ sudo systemctl enable docker

2) จากนั้นหากคุณมีไฟล์. yml ที่เขียนนักเทียบท่าเพิ่มrestart: alwaysหรือถ้าคุณมีคอนเทนเนอร์นักเทียบท่าให้เพิ่มรีสตาร์ท = เสมอแบบนี้ :

docker run --restart=always และเรียกใช้ Docker container

ตรวจสอบให้แน่ใจ

หากคุณหยุดคอนเทนเนอร์ด้วยตนเองนโยบายการรีสตาร์ทจะถูกละเว้นจนกว่า Docker daemon จะรีสตาร์ทหรือรีสตาร์ทคอนเทนเนอร์ด้วยตนเอง

ดูนโยบายการรีสตาร์ทนี้ในหน้าอย่างเป็นทางการของ Docker

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

$ docker-compose up -d

9

โหมด "อ่อนโยน" เพิ่มเติมจากเอกสาร:

docker run -dit --restart unless-stopped <image_name>

2
น่าเสียดายที่เมื่อ docker daemon หยุดโดยการรีบูต daemon "หยุด" คอนเทนเนอร์โดยทำเครื่องหมายว่าหยุด จากนั้นเมื่อระบบบู๊ตมันจะไม่เริ่มสิ่งเหล่านี้ มันเป็นใบ้ นี่คือข้อบกพร่อง: github.com/docker/for-linux/issues/652
mlissner

restart=unless-stoppedตัวเลือกที่จะพยายามที่จะเริ่มต้นเมื่อเครื่องยนต์ภาชนะนักเทียบท่าจะเริ่มต้นใหม่ ข้อยกเว้นที่ฉันเคยเห็นคือเมื่อเครื่องยนต์นักเทียบท่าไม่ได้รับการกำหนดค่าให้เริ่มการรีบูตโดยอัตโนมัติ (ตรวจสอบsystemctl status dockerให้แน่ใจว่าเปิดใช้งานอยู่) และคอนเทนเนอร์สตาร์ทเครื่องยนต์ก่อนที่เครือข่ายจะพร้อมที่ฉันเห็นเฉพาะกับเครือข่ายซ้อนทับเท่านั้น ทั้งสองอย่างนี้ก็จะแตกrestart=alwaysเช่นกัน
BMitch

3

นี่คือสิ่งที่ crontab มีไว้สำหรับ:

@reboot sleep 10 ; docker start <container name> 2>&1 | /usr/bin/logger -t 'docker start'

เข้าถึง crontab ผู้ใช้ของคุณโดยcrontab -eหรือแสดงด้วยcrontab -lหรือแก้ไข crontab ระบบของคุณที่/etc/crontab


บริการ cron คืออะไรเริ่มก่อนบริการเทียบท่า ... สิ่งนี้จะล้มเหลวในกรณีนี้ ...
Akhil Jalagam

1
@AkhilJalagam ฉันไม่แน่ใจว่าฉันเข้าใจปัญหาของคุณ "สลีป 10" ให้เวลาในการเริ่มต้นมากพอสมควรจากนั้นจึงเริ่มคอนเทนเนอร์หลังจากบู๊ต / รีบูตระบบ วิธีนี้ไม่จำเป็นต้องให้ใครเข้าสู่ระบบก่อนที่จะเริ่มและหลีกเลี่ยงหน่วยบริการ systemd ที่ยุ่งเหยิงและซับซ้อน วิธีการของหน่วยบริการ systemd ให้ความรู้สึกแฮ็คมากกว่าตัวอย่างของฉัน
Travis Runyard

2

ฉันต้องการบรรลุการเริ่มต้นคอนเทนเนอร์บนบูตบน Windows

ดังนั้นฉันเพิ่งสร้างงานตามกำหนดเวลาซึ่งเปิดใช้งานเมื่อบูตระบบ งานนั้นเพียงแค่เริ่ม "Docker for Windows.exe" (หรืออะไรก็ตามที่เป็นชื่อปฏิบัติการของนักเทียบท่าของคุณ)

จากนั้นคอนเทนเนอร์ทั้งหมดที่มีนโยบายการรีสตาร์ท "always" จะเริ่มทำงาน


2

คุณสามารถ เรียกใช้คอนเทนเนอร์ที่รีสตาร์ทเสมอโดย:

$ docker run -dit --restart unless-stopped <image name OR image hash>

หากคุณต้องการเปลี่ยนการกำหนดค่าของคอนเทนเนอร์ที่กำลังทำงานอยู่คุณควร อัปเดตโดย:

$ docker update --restart=<options> <container ID OR name>

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

docker inspect gateway | grep RestartPolicy -A 3

ท้ายที่สุดอย่าลืมติดตั้ง Docker daemon เปิดใช้งานเมื่อบูตระบบโดย:

$ systemctl enable docker

หากต้องการดูรายการนโยบายการรีสตาร์ททั้งหมดโปรดดูที่: รีสตาร์ทนโยบาย


0

ฉันมีปัญหาคล้ายกันในการใช้ระบบ Linux หลังจากบูตระบบแล้วคอนเทนเนอร์ที่มีนโยบายการรีสตาร์ทเป็น "เว้นแต่หยุด" จะไม่รีสตาร์ทโดยอัตโนมัติเว้นแต่ฉันจะพิมพ์คำสั่งที่ใช้นักเทียบท่าในทางใดทางหนึ่งเช่น "นักเทียบท่า ps" ฉันรู้สึกประหลาดใจเพราะฉันคาดว่าคำสั่งนั้นจะรายงานข้อมูลสถานะบางอย่างเท่านั้น ต่อไปฉันลองใช้คำสั่ง "systemctl status docker" บนระบบที่ไม่มีการรันคำสั่ง docker คำสั่งนี้รายงานสิ่งต่อไปนี้:

● docker.service - Docker Application Container Engine

   Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled)

     Active: inactive (dead)    TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com

ในระบบที่เรียกใช้ "docker ps" โดยไม่มีคำสั่ง Docker อื่น ๆ ฉันได้รับสิ่งต่อไปนี้:

● docker.service - Docker Application Container Engine
    Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled)

    Active: active (running) since Sun 2020-11-22 08:33:23 PST; 1h 25min ago

TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com

   Main PID: 3135 (dockerd)
      Tasks: 13

    Memory: 116.9M
     CGroup: /system.slice/docker.service
             └─3135 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
 ... [various messages not shown ]

คำอธิบายที่เป็นไปได้มากที่สุดคือ Docker รอคำสั่ง docker ก่อนที่จะเริ่มต้นและเริ่มคอนเทนเนอร์อย่างสมบูรณ์ คุณสามารถเรียกใช้ "docker ps" ในไฟล์ systemd unit ได้ทีละจุดหลังจากเริ่มต้นบริการทั้งหมดที่คอนเทนเนอร์ของคุณต้องการแล้ว ฉันได้ทดสอบสิ่งนี้โดยใส่ไฟล์ชื่อ docker-onboot.service ในไดเร็กทอรี / lib / systemd / system พร้อมเนื้อหาต่อไปนี้:

[Unit]
# This service is provided to force Docker containers
# that should automatically restart to restart when the system
# is booted. While the Docker daemon will start automatically,
# it will not be fully initialized until some Docker command
# is actually run.  This unit merely runs "docker ps": any
# Docker command will result in the Docker daemon completing
# its initialization, at which point all containers that can be
# automatically restarted after booting will be restarted.
#
Description=Docker-Container Startup on Boot
Requires=docker.socket
After=docker.socket network-online.target containerd.service

[Service]
Type=oneshot
ExecStart=/usr/bin/docker ps

[Install]

WantedBy = multi-user.target

จนถึงตอนนี้ (การทดสอบหนึ่งครั้งโดยเปิดใช้บริการนี้) คอนเทนเนอร์เริ่มต้นเมื่อคอมพิวเตอร์บูต ฉันไม่ได้ลองพึ่งพา docker.service เนื่องจาก docker.service จะไม่เริ่มทำงานจนกว่าจะมีการเรียกใช้คำสั่ง docker การทดสอบครั้งต่อไปจะเป็นการปิดการใช้งาน docker-onboot (เพื่อดูว่าการพึ่งพา WantedBy จะเริ่มโดยอัตโนมัติหรือไม่)


มันจะง่ายกว่ามากที่จะเริ่มต้นdocker.serviceด้วยตัวเองในการบูตsystemctl enable docker.serviceมากกว่าการสร้างบริการอื่น ๆ ทั้งหมดเพียงเพื่อเรียกใช้บริการนั้นทางอ้อมผ่านซ็อกเก็ต
Lucas S.

0

ในการเริ่มต้นคอนเทนเนอร์และตั้งค่าให้รีสตาร์ทโดยอัตโนมัติเมื่อใช้การรีบูตระบบ

docker run -d --restart unless-stopped ecstatic_ritchie

ในกรณีที่ecstatic_ritchieเป็นชื่อของตัวอย่างที่ระบุในภาชนะที่น่าสนใจ ใช้docker ps -aแสดงรายชื่อคอนเทนเนอร์ทั้งหมด

เพื่อให้คอนเทนเนอร์ที่กำลังทำงานอยู่เริ่มต้นโดยอัตโนมัติเมื่อรีบูตระบบ

docker update --restart unless-stopped ecstatic_ritchie

เพื่อให้คอนเทนเนอร์ที่ทำงานอยู่ทั้งหมดเริ่มทำงานโดยอัตโนมัติเมื่อรีบูตระบบ

docker update --restart unless-stopped $(docker ps -q)

ดูเพิ่มเติมในหน้าแรกของ Docker

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.