Bagaimana cara membuat container Docker dimulai secara otomatis saat boot sistem?


111

Misalkan saya memiliki kontainer Docker yang ingin saya jalankan, maka saya dapat memanggil

$ docker run ...

dan semuanya baik-baik saja. Apakah ada cara bawaan untuk menjalankan penampung dengan cara yang akan dimulai ulang secara otomatis, jika sistem mogok dan melakukan boot ulang?

Jika ya, apakah ini juga tersedia di Docker Compose?

Jawaban:


133

Ya, buruh pelabuhan memiliki kebijakan restart seperti docker run --restart=alwaysyang akan menangani ini. Ini juga tersedia di file konfigurasi compose.yml sebagai restart: always.


25
Ini adalah jawaban pertama dan yang diterima, namun mungkin sebagian besar orang yang menelusuri fitur tersebut benar-benar ingin menjalankan penampung mereka sebagai layanan. Jawaban @kon yang digunakan Systemdsebagai manajer layanan adalah salah satu solusi terbaik untuk tujuan itu dan membutuhkan lebih banyak suara positif.
Rémi Becheras

1
Ini tidak berhasil dari saya. Saya memiliki sebuah wadah yang disebut "crmpicco-mysql" dan aku berlari docker run --restart=always crmpicco-mysqldan aku kesalahan: Unable to find image 'crmpicco-mysql:latest' locally.
crmpicco

2
Kesalahan Anda tidak terkait. Anda mungkin ingin memposting pertanyaan terpisah tetapi sepertinya Anda membingungkan nama gambar buruh pelabuhan dan nama kontainer buruh pelabuhan. The docker runperintah mengharapkan nama dari suatu gambar yang dapat Anda daftar melalui docker images.
Peter Lyons

12
Satu-satunya masalah dengan ini adalah bahwa "selalu" juga akan memulai ulang penampung tanpa batas ketika dihentikan karena kesalahan (lihat dokumen). Harus ada kebijakan yang hanya dimulai pada daemon-start
lostiniceland

4
Saya pikir salah satu nilai jual utama kontainer / buruh pelabuhan adalah bahwa saya tidak perlu menginstal dan mengelola setiap layanan saya di systemd (yang bisa merepotkan).
Marc

140

Jika Anda ingin penampung dimulai meskipun tidak ada pengguna yang melakukan login (seperti VM VirtualBox yang saya hanya mulai dan tidak ingin login setiap kali). Berikut adalah langkah-langkah yang saya lakukan untuk Ubuntu 16.04 LTS. Sebagai contoh, saya memasang wadah oracle db:

$ 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

dan tambahkan konten berikut:

[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

dan aktifkan layanan saat memulai

sudo systemctl enable docker-MYPROJECT-oracle_db.service

Untuk informasi lebih lanjut https://docs.docker.com/engine/admin/host_integration/


9
Bagi mereka yang ingin melakukan ini dengan docker-compose, Anda dapat mengganti dockerperintah di atas dengan docker-composeperintah, menggunakan -fflag untuk menentukan lokasi file docker-compose:/usr/bin/docker-compose -f /path/to/docker-compose.yml up
charlesreid1

1
Untuk menambahkan apa yang dikatakan @ charlesreid1, jika Anda docker-compose.ymlmenentukan sebuah .envfile, gunakan --project-directory /path/to sebagai tambahan untuk secara eksplisit menentukan file penulisan buruh pelabuhan Anda.
whlteXbread

1
Docker memiliki sistem log dan manajer prosesnya. Sayangnya tidak ada kebijakan restart yang benar.
Franklin Yu

Ada ide bagaimana melakukan ini di Windows Server 2012? Aku tidak bisa menjalankan buruh pelabuhan kecuali aku login ...
Alex Lord Mordor

Mungkin juga menarik bagi beberapa orang bahwa ada [Unit]petunjuk berguna yang disebut Before=. Terutama ketika memulai hal-hal seperti sistem manajemen database, akan sangat membantu untuk memastikannya dimulai sebelum layanan tertentu lainnya.
Micha

92

The kebijakan Restart standar adalah no.

Untuk wadah yang dibuat, gunakan docker updateuntuk memperbarui kebijakan restart.

docker update --restart=always 0576df221c0b

0576df221c0b adalah id penampung.


Bukankah alwaysberarti penampung akan memulai ulang meskipun saya menghentikannya? Tentunya ada cara untuk me-restart wadah di reboot tanpa semacam ini terus-menerus awal ...
Marc

4
@Marc: tidak. Lihat dokumentasi :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

14

Anda bisa menggunakan docker update --restart=on-failure <container ID or name>.

Di atas apa yang disarankan oleh namanya, on-failuretidak hanya akan me-restart container jika gagal, tetapi juga saat boot sistem.

Berdasarkan dokumentasi , ada beberapa opsi restart:

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
Wow, kerja bagus menemukan ini, mengingat tidak disebutkan dalam dokumentasi. Solusi sempurna untuk saya.
Cameron Hudson

Satu hal yang perlu diperhatikan tentang penggunaan saat gagal, jika Anda memiliki wadah yang bergantung pada wadah lain yang sudah berjalan, sepertinya tidak ada "urutan awal", jadi salah satu mungkin mulai dan langsung gagal dan tidak pernah memulai pada boot OS
ferr

12

1) Pertama-tama, Anda harus mengaktifkan layanan buruh pelabuhan saat boot

$ sudo systemctl enable docker

2) Kemudian jika Anda memiliki file docker-compose .yml add restart: alwaysatau jika Anda memiliki docker container tambahkan restart = selalu seperti ini:

docker run --restart=always dan menjalankan kontainer buruh pelabuhan

Yakinkan

Jika Anda menghentikan container secara manual, kebijakan mulai ulangnya diabaikan hingga daemon Docker dimulai ulang atau container dimulai ulang secara manual.

lihat kebijakan restart ini di halaman resmi Docker

3) Jika Anda ingin memulai docker-compose, semua layanan berjalan saat Anda me-reboot sistem Anda Jadi Anda menjalankan perintah di bawah ini hanya sekali

$ docker-compose up -d

9

Lebih banyak mode "lembut" dari dokumentasi:

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

2
Sayangnya, ketika daemon buruh pelabuhan dihentikan oleh reboot, daemon tersebut "menghentikan" kontainer, menandainya sebagai berhenti. Kemudian ketika sistem melakukan boot, itu tidak benar-benar memulai ini. Itu bodoh. Berikut bugnya
mlissner

The restart=unless-stoppedpilihan akan mencoba untuk memulai kontainer ketika mesin buruh pelabuhan-restart. Pengecualian yang saya lihat adalah ketika mesin buruh pelabuhan itu sendiri tidak dikonfigurasi untuk memulai secara otomatis saat reboot (periksa systemctl status dockeruntuk memastikan sudah diaktifkan) dan mesin mulai kontainer sebelum jaringan siap yang saya hanya melihat dengan jaringan overlay. Keduanya akan rusak restart=alwaysjuga.
BMitch

2

Saya ingin mencapai startup kontainer saat boot di Windows.

Oleh karena itu, saya baru saja membuat Tugas terjadwal yang diluncurkan saat boot sistem. Tugas itu hanya memulai "Docker untuk Windows.exe" (atau apa pun nama docker Anda yang dapat dieksekusi).

Kemudian, semua penampung dengan kebijakan mulai ulang "selalu" akan mulai.


2

Inilah kegunaan crontab:

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

Akses crontab pengguna Anda dengan crontab -eatau tampilkan dengan crontab -latau edit crontab sistem Anda di/etc/crontab


Apa layanan cron dimulai sebelum layanan buruh pelabuhan ... ini akan gagal dalam kasus ini ...
Akhil Jalagam

1
@AkhilJalagam Saya tidak yakin bahwa saya memahami masalah Anda. "Tidur 10" memberi crond banyak waktu untuk memulai, kemudian memulai penampung setelah boot / boot ulang sistem. Metode ini tidak memerlukan siapa pun untuk masuk sebelum memulai dan menghindari unit layanan systemd yang berantakan dan rumit. Metode unit layanan systemd terasa lebih hacky daripada contoh saya.
Travis Runyard

2

Anda dapat menjalankan penampung yang selalu dimulai ulang dengan:

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

Jika Anda ingin mengubah konfigurasi penampung yang sedang berjalan, Anda harus memperbaruinya dengan:

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

Dan jika Anda ingin melihat kebijakan container saat ini, jalankan perintah berikut sebelum di atas di tempat pertama:

docker inspect gateway | grep RestartPolicy -A 3

Lagi pula, Jangan lupa untuk mengaktifkan daemon docker yang terinstal saat sistem boot dengan:

$ systemctl enable docker

Untuk melihat daftar lengkap kebijakan mulai ulang, lihat: Kebijakan Mulai Ulang


1

Saya memiliki masalah serupa saat menjalankan sistem Linux. Setelah sistem di-boot, wadah dengan kebijakan restart "kecuali-dihentikan" tidak akan restart secara otomatis kecuali saya mengetik perintah yang menggunakan buruh pelabuhan dalam beberapa cara seperti "buruh pelabuhan ps". Saya terkejut karena saya mengharapkan perintah itu hanya melaporkan beberapa informasi status. Selanjutnya saya mencoba perintah "systemctl status docker". Pada sistem yang tidak menjalankan perintah buruh pelabuhan, perintah ini melaporkan hal berikut:

● 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

Pada sistem di mana "docker ps" telah dijalankan tanpa perintah Docker lain, saya mendapatkan yang berikut:

● 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 ]

Penjelasan yang paling mungkin adalah bahwa Docker menunggu beberapa perintah buruh pelabuhan sebelum sepenuhnya menginisialisasi dan memulai kontainer. Anda mungkin dapat menjalankan "docker ps" dalam file unit systemd pada satu titik setelah semua layanan yang dibutuhkan container Anda telah diinisialisasi. Saya telah menguji ini dengan meletakkan file bernama docker-onboot.service di direktori / lib / systemd / system dengan konten berikut:

[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

Sejauh ini (satu tes, dengan layanan ini diaktifkan), kontainer dimulai saat komputer di-boot. Saya tidak mencoba ketergantungan pada docker.service karena docker.service tidak akan mulai sampai perintah docker dijalankan. Tes selanjutnya adalah dengan docker-onboot dinonaktifkan (untuk melihat apakah ketergantungan WantedBy akan secara otomatis memulainya).


0

Untuk memulai wadah dan mengaturnya untuk memulai ulang secara otomatis pada penggunaan boot ulang sistem

docker run -d --restart unless-stopped ecstatic_ritchie

Di mana ecstatic_ritchieadalah nama contoh yang menentukan wadah yang diminati. Gunakan docker ps -auntuk mencantumkan semua nama wadah.

Untuk membuat container berjalan tertentu mulai secara otomatis saat boot ulang sistem

docker update --restart unless-stopped ecstatic_ritchie

Untuk membuat semua kontainer yang berjalan dimulai secara otomatis saat boot ulang sistem

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

Lihat lebih lanjut di beranda Docker

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.