Jak sprawić, aby kontener Docker był uruchamiany automatycznie podczas rozruchu systemu?

111

Przypuśćmy, że mam kontener Docker, który chcę uruchomić, i mogę zadzwonić

$ docker run ...

i wszystko w porządku. Czy istnieje wbudowany sposób uruchamiania kontenera w taki sposób, aby był on automatycznie restartowany, jeśli system ulegnie awarii i uruchomi się ponownie?

Jeśli tak, czy jest to również dostępne w Docker Compose?

Golo Roden
źródło

Odpowiedzi:

134

Tak, docker ma zasady ponownego uruchamiania, takie jak te, docker run --restart=alwaysktóre pozwolą sobie z tym poradzić. Jest to również dostępne w pliku konfiguracyjnym compose.yml jako restart: always.

Peter Lyons
źródło
25
Jest to pierwsza i akceptowana odpowiedź, jednak prawdopodobnie większość osób szukających tej funkcji naprawdę chce uruchomić swój kontener jako usługę. Odpowiedź @kon Systemdjako menedżera usług jest jednym z najlepszych rozwiązań do tego celu i wymaga więcej głosów.
Rémi Becheras
1
W moim przypadku to nie zadziałało. Mam kontenera o nazwie „crmpicco-mysql” i wpadłem docker run --restart=always crmpicco-mysqli mam błąd: Unable to find image 'crmpicco-mysql:latest' locally.
crmpicco
2
Twój błąd nie ma związku. Możesz zadać osobne pytanie, ale wygląda na to, że mylisz nazwy obrazów Dockera z nazwami kontenerów Dockera. docker runKomenda spodziewa nazwę obrazu, który możesz wymienić poprzez docker images.
Peter Lyons
12
Jedyny problem polega na tym, że „zawsze” spowoduje również nieskończone ponowne uruchomienie kontenera, gdy został zatrzymany z powodu błędu (patrz dokumentacja). Powinna istnieć polityka, która zaczyna się dopiero od uruchomienia demona
lostiniceland
4
Pomyślałem, że jednym z głównych punktów sprzedaży kontenerów / dockera jest to, że nie muszę instalować i zarządzać każdą z moich usług w systemd (co może być uciążliwe).
Marc
141

Jeśli chcesz, aby kontener był uruchamiany, nawet jeśli żaden użytkownik nie wykonał logowania (jak maszyna wirtualna VirtualBox, którą tylko uruchamiam i nie chcę się logować za każdym razem). Oto kroki, które wykonałem dla Ubuntu 16.04 LTS. Jako przykład zainstalowałem kontener db oracle:

$ 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

i dodaj następującą treść:

[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

i włącz usługę podczas uruchamiania

sudo systemctl enable docker-MYPROJECT-oracle_db.service

Więcej informacji: https://docs.docker.com/engine/admin/host_integration/

kon
źródło
9
Dla tych, którzy chcą to zrobić za pomocą docker-compose, możesz zamienić dockerpowyższe polecenie na docker-composepolecenie, używając -fflagi do określenia lokalizacji pliku /usr/bin/docker-compose -f /path/to/docker-compose.yml up
docker
1
Aby dodać do tego, co powiedział @ charlesreid1, jeśli twój docker-compose.ymlokreśla .envplik, użyj --project-directory /path/to oprócz jawnego określenia pliku redagowania docker.
whlteXbread
1
Docker ma swój system dziennika i menedżera procesów. Szkoda, że ​​nie ma odpowiednich zasad ponownego uruchamiania.
Franklin Yu
Masz pomysł, jak to zrobić w systemie Windows Server 2012? Nie mogę uruchomić dockera, dopóki się nie zaloguję ...
Alex Lord Mordor
Dla niektórych może być również interesujące, że istnieje pomocna [Unit]dyrektywa o nazwie Before=. Szczególnie przy uruchamianiu takich rzeczy, jak systemy zarządzania bazami danych, pomocne może być upewnienie się, że zostało uruchomione przed określonymi innymi usługami.
Micha
92

Domyślna polityka restart jest no.

W przypadku utworzonych kontenerów użyj docker updatedo aktualizacji zasad ponownego uruchamiania.

docker update --restart=always 0576df221c0b

0576df221c0b to identyfikator kontenera.

Edwarda Younga
źródło
Nie alwaysoznacza to, że pojemnik zostanie ponownie uruchomiony, nawet jeśli ja go zatrzymać? Z pewnością istnieje sposób na ponowne uruchomienie kontenera po ponownym uruchomieniu bez tego rodzaju ciągłego uruchamiania ...
Marc
4
@Marc: nie. Zobacz dokumentację :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

Możesz użyć docker update --restart=on-failure <container ID or name>.

Oprócz tego, co sugeruje nazwa, on-failurenie tylko zrestartuje kontener w przypadku awarii, ale także podczas rozruchu systemu.

Zgodnie z dokumentacją istnieje wiele opcji ponownego uruchomienia:

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.
SaeX
źródło
3
Wow, dobra robota przy odkrywaniu tego, biorąc pod uwagę, że nie ma o tym wzmianki w dokumentacji. Dla mnie idealne rozwiązanie.
Cameron Hudson
Jedna rzecz, na którą należy zwrócić uwagę przy używaniu w przypadku awarii, jeśli masz kontener, który zależy od innego już działającego, nie wydaje się, aby istniała „kolejność uruchamiania”, więc można uruchomić i natychmiast zawieść i nigdy nie uruchomić podczas rozruchu systemu operacyjnego
ferr
12

1) Przede wszystkim musisz włączyć usługę docker podczas rozruchu

$ sudo systemctl enable docker

2) Następnie, jeśli masz docker-compose .yml file add restart: alwayslub jeśli masz docker container add restart = zawsze w ten sposób:

docker run --restart=always i uruchom kontener Docker

Upewnić się

Jeśli ręcznie zatrzymasz kontener, jego zasada ponownego uruchamiania jest ignorowana do momentu ponownego uruchomienia demona platformy Docker lub ręcznego ponownego uruchomienia kontenera.

zobacz te zasady ponownego uruchamiania na oficjalnej stronie Dockera

3) Jeśli chcesz uruchomić docker-compose, wszystkie usługi działają po ponownym uruchomieniu systemu, więc uruchamiasz poniższe polecenie tylko raz

$ docker-compose up -d
Abdul Basit
źródło
9

Bardziej „delikatny” tryb z dokumentacji:

docker run -dit --restart unless-stopped <image_name>
Żebro47
źródło
2
Niestety, gdy demon dockera zostaje zatrzymany przez restart, demon „zatrzymuje” kontenery, oznaczając je jako zatrzymane. Następnie, gdy system się uruchamia, w rzeczywistości ich nie uruchamia. To głupie. Oto błąd: github.com/docker/for-linux/issues/652
mlissner
restart=unless-stoppedOpcja będzie próbował rozpocząć pojemników, gdy silnik doker zostaje wznowiona. Wyjątkami, które widziałem, są sytuacje, gdy sam silnik dokera nie jest skonfigurowany do automatycznego uruchamiania po ponownym uruchomieniu (sprawdź, systemctl status dockerczy jest włączony) i silnik uruchamia kontenery, zanim sieć jest gotowa, co widziałem tylko w przypadku sieci nakładkowej. Oba też by się zepsuły restart=always.
BMitch
3

Do tego służy crontab:

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

Uzyskaj dostęp do pliku crontab użytkownika, crontab -ewyświetl go za pomocą crontab -llub edytuj tabelę crontab systemu pod adresem/etc/crontab

Travis Runyard
źródło
Czym jest uruchomienie usługi cron przed usługą
dokera
1
@AkhilJalagam Nie jestem pewien, czy rozumiem Twój problem. „Uśpij 10” daje crond dużo czasu na uruchomienie, a następnie uruchamia kontener po uruchomieniu / ponownym uruchomieniu systemu. Ta metoda nie wymaga od nikogo logowania się przed rozpoczęciem i pozwala uniknąć niechlujnych, skomplikowanych jednostek usługowych systemd. Metoda jednostki usługowej systemd wydaje się jeszcze bardziej hakerska niż mój przykład.
Travis Runyard
2

Chciałem uzyskać uruchomienie kontenera podczas rozruchu w systemie Windows.

Dlatego właśnie utworzyłem zaplanowane zadanie, które uruchamia się podczas rozruchu systemu. To zadanie po prostu uruchamia „Docker for Windows.exe” (lub inną nazwę pliku wykonywalnego Dockera).

Następnie zostaną uruchomione wszystkie kontenery z zasadą ponownego uruchamiania „zawsze”.

TostMaster
źródło
2

Możesz uruchomić kontener, który zawsze restartuje się przez:

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

Jeśli chcesz zmienić konfiguracje działającego kontenera, powinieneś zaktualizować go przez:

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

A jeśli chcesz zobaczyć aktualną politykę kontenera, uruchom następujące polecenie przed powyższym w pierwszej kolejności:

docker inspect gateway | grep RestartPolicy -A 3

W końcu nie zapomnij włączyć zainstalowanego demona Dockera podczas rozruchu systemu przez:

$ systemctl enable docker

Aby zobaczyć pełną listę zasad ponownego uruchamiania, zobacz: Zasady ponownego uruchamiania

Mohsen Abasi
źródło
0

Mam podobny problem z systemami Linux. Po uruchomieniu systemu kontener z zasadą restartu „chyba, że ​​zatrzymano”, nie uruchomiłby się automatycznie, chyba że wpisałem polecenie używające dockera w jakiś sposób, na przykład „docker ps”. Byłem zaskoczony, ponieważ spodziewałem się, że to polecenie poda tylko informacje o stanie. Następnie wypróbowałem polecenie „systemctl status docker”. W systemie, w którym nie zostały uruchomione żadne polecenia Dockera, polecenie to zgłosiło następujące informacje:

● 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

W systemie, w którym „docker ps” został uruchomiony bez innych poleceń Dockera, otrzymałem następujące informacje:

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

Najbardziej prawdopodobnym wyjaśnieniem jest to, że Docker czeka na jakąś komendę Dockera przed pełną inicjalizacją i uruchomieniem kontenerów. Można przypuszczalnie uruchomić "docker ps" w pliku jednostki systemowej w momencie, gdy wszystkie usługi, których potrzebują twoje kontenery, zostały zainicjowane. Przetestowałem to, umieszczając plik o nazwie docker-onboot.service w katalogu / lib / systemd / system z następującą zawartością:

[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

Do tej pory (jeden test z włączoną tą usługą) kontener uruchamiał się podczas rozruchu komputera. Nie próbowałem zależności od docker.service, ponieważ docker.service nie uruchomi się, dopóki nie zostanie uruchomione polecenie docker. Następny test będzie wykonywany z wyłączonym docker-onboot (aby sprawdzić, czy zależność WantedBy uruchomi ją automatycznie).

Bill Zaumen
źródło
Byłoby o wiele łatwiej po prostu uruchomić docker.servicesię podczas rozruchu, systemctl enable docker.serviceniż utworzyć całą inną usługę tylko po to, aby pośrednio wyzwolić tę usługę przez jej gniazdo.
Lucas S.
0

Aby uruchomić kontener i ustawić go tak, aby uruchamiał się automatycznie po ponownym uruchomieniu systemu

docker run -d --restart unless-stopped ecstatic_ritchie

Gdzie ecstatic_ritchiejest przykładowa nazwa określająca kontener, który nas interesuje. Służy docker ps -ado wyświetlania wszystkich nazw kontenerów.

Aby określone uruchomione kontenery były uruchamiane automatycznie po ponownym uruchomieniu systemu

docker update --restart unless-stopped ecstatic_ritchie

Aby wszystkie uruchomione kontenery były uruchamiane automatycznie po ponownym uruchomieniu systemu

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

Zobacz więcej na stronie głównej Dockera

0xC0DEGURU
źródło