如何使Docker容器在系统启动时自动启动?


111

假设我有一个要运行的Docker容器,那么我可以调用

$ docker run ...

一切都很好。如果系统崩溃并重新启动,是否有内置的方式来运行容器,使其能够自动重新启动?

如果是这样,那么在Docker Compose中也可以使用吗?

Answers:


133

是的,码头工人具有重启策略,例如docker run --restart=always可以处理此问题的策略。这也是在可用compose.yml配置文件作为restart: always


25
这是第一个被接受的答案,但是可能大多数搜索该功能的人确实希望将其容器作为服务运行。用作服务管理器@kon答案Systemd是为此目的的最佳解决方案之一,并且需要更多支持。
雷米·贝切拉斯(RémiBecheras)

1
这对我不起作用。我有一个名为“ crmpicco-mysql”的容器,然后运行docker run --restart=always crmpicco-mysql,但出现错误:Unable to find image 'crmpicco-mysql:latest' locally
crmpicco

2
您的错误无关。您可能要发布一个单独的问题,但看起来您在混淆Docker映像名称和Docker容器名称。该docker run命令需要一个可以通过列出的图像名称docker images
彼得·里昂斯

12
唯一的问题是,当由于错误而停止容器时,“总是”也会无限重启容器(请参阅文档)。应该有一个仅在守护程序启动时启动的策略
lostiniceland

4
我认为容器/泊坞窗的主要卖点之一是,我不需要在systemd中安装和管理我的每项服务(这很痛苦)。
Marc

140

如果即使没有用户执行登录,也要启动容器(例如,我仅启动而不希望每次都登录的VirtualBox VM)。这是我对Ubuntu 16.04 LTS执行的步骤。作为示例,我安装了一个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

并添加以下内容:

[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-compose做到这一点的用户,可以使用该docker命令替换上面的docker-compose命令,并使用该-f标志指定/usr/bin/docker-compose -f /path/to/docker-compose.yml up
docker

1
要添加到@ charlesreid1所说的内容中,如果您docker-compose.yml指定了.env文件,则--project-directory /path/to 除了显式指定您的docker compose文件外,还要使用。
whlteXbread

1
Docker有其日志系统和流程管理器。不幸的是,它没有正确的重启策略。
富兰克林于

知道如何在Windows Server 2012上执行此操作吗?除非登录,否则无法运行docker ...
Alex Lord Mordor

对于某些人来说,也可能有一个有趣的[Unit]指令,它可能很有趣Before=。特别是在启动诸如数据库管理系统之类的东西时,确保特定的其他服务之前启动它可能会有所帮助。
米查

92

默认情况下重新启动策略no

对于创建的容器,使用docker update更新重启策略。

docker update --restart=always 0576df221c0b

0576df221c0b 是容器ID。


并不是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

14

您可以使用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
考虑到文档中未提及,发现它真是太好了。对我来说是完美的解决方案。
卡梅隆·哈德森

关于使用失败的注意事项,如果您有一个容器依赖于另一个已经在运行的容器,则似乎没有“启动顺序”,因此一个容器可能会启动并立即失败,并且永远不会在操作系统启动时启动
ferr

12

1)首先,必须在启动时启用docker服务

$ sudo systemctl enable docker

2)然后,如果您添加了docker-compose .yml文件,restart: always或者您有docker容器,则添加restart = always像这样:

docker run --restart=always 并运行docker容器

确保

如果手动停止容器,则其重新启动策略将被忽略,直到Docker守护程序重新启动或手动重新启动容器为止。

在Docker官方页面上查看此重启策略

3)如果您要启动docker-compose,则在重新启动系统时所有服务都将运行,因此您只能在命令下方运行一次

$ docker-compose up -d

9

来自文档的更多“温和”模式:

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

2
不幸的是,当docker守护程序通过重启而停止时,该守护程序会“停止”容器,将其标记为已停止。然后,当系统启动时,它实际上并没有启动它们。真傻 错误是:github.com/docker/for-linux/issues/652
mlissner

restart=unless-stopped选项将在重新启动docker引擎时尝试启动容器。我所看到的例外是当docker引擎本身未配置为在重新启动时自动启动(检查systemctl status docker以确保已启用),并且在网络就绪之前引擎启动了容器,而我只有在使用重叠网络时才能看到。这些都将打破restart=always
BMitch

2

我想在Windows上实现启动时容器的启动。

因此,我只是创建了一个计划任务,该任务在系统启动时启动。该任务只是启动“ Docker for Windows.exe”(或Docker可执行文件的名称)。

然后,所有启动策略为“始终”的容器将启动。


2

这是crontab的用途:

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

通过访问用户crontabcrontab -e或在其中显示它,crontab -l或在以下位置编辑系统crontab/etc/crontab


什么是在
docker

1
@AkhilJalagam我不确定我是否理解您的问题。“ sleep 10”让crond有足够的时间启动,然后在系统引导/重新引导后启动容器。该方法不需要任何人在启动之前登录,并且避免了混乱,复杂的systemd服务单元。与我的示例相比,systemd服务单元方法感觉更棘手。
Travis Runyard

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守护程序:

$ systemctl enable docker

要查看重新启动策略的完整列表,请参阅:重新启动策略


1

我在运行Linux系统时遇到类似的问题。引导系统后,除非我输入以某种方式使用docker的命令(例如“ docker ps”),否则重启策略为“ unless-stopped”的容器将不会自动重启。我很惊讶,因为我期望该命令仅报告一些状态信息。接下来,我尝试了命令“ 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命令的情况下运行“ docker ps”的系统上,我得到了以下信息:

● 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命令。在容器所需的所有服务均已初始化之后,您可能会在一个systemd单元文件中运行“ docker ps”。我已经通过将名为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 =多用户目标

到目前为止(一项测试,启用了此服务),容器在启动计算机时启动。我没有尝试依赖docker.service,因为在运行docker命令之前docker.service不会启动。下一个测试将是禁用docker-onboot的功能(以查看WantedBy依赖项是否会自动启动它)。


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主页上查看更多

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.