如何在系统启动时运行 docker-compose up -d?
Posted
技术标签:
【中文标题】如何在系统启动时运行 docker-compose up -d?【英文标题】:How to run docker-compose up -d at system start up? 【发布时间】:2017-09-26 01:22:46 【问题描述】:为了让容器在启动点自动启动,我尝试添加命令:
cd directory_has_docker-compose.yml && docker-compose up -d
在 /etc/rc.local 中。
但是在我重新启动机器后,容器无法工作。
如何在系统启动时运行docker-compose up -d
?
【问题讨论】:
使用--restart always
或--restart unless-stopped
或在docker-compose.yml 中使用restart: always
--> Ref。但可能不适用于某些容器!
【参考方案1】:
当我们使用crontab
或已弃用的/etc/rc.local
文件时,我们需要延迟(例如sleep 10
,取决于机器)以确保系统服务可用。通常,systemd
(或upstart
)用于管理系统启动时启动哪些服务。您可以尝试使用类似的配置:
# /etc/systemd/system/docker-compose-app.service
[Unit]
Description=Docker Compose Application Service
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/srv/docker
ExecStart=/usr/local/bin/docker-compose up -d
ExecStop=/usr/local/bin/docker-compose down
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target
或者,如果您想在没有 -d
标志的情况下运行:
# /etc/systemd/system/docker-compose-app.service
[Unit]
Description=Docker Compose Application Service
Requires=docker.service
After=docker.service
[Service]
WorkingDirectory=/srv/docker
ExecStart=/usr/local/bin/docker-compose up
ExecStop=/usr/local/bin/docker-compose down
TimeoutStartSec=0
Restart=on-failure
StartLimitIntervalSec=60
StartLimitBurst=3
[Install]
WantedBy=multi-user.target
使用您的 dockerized 项目路径更改 WorkingDirectory
参数。并让服务自动启动:
systemctl enable docker-compose-app
【讨论】:
有没有一种简单的方法来测试它是否可以在不重新启动树莓派的情况下工作? 这是 IMO 最优雅的答案 我认为 @dmigosystemctl start docker-compose-app
和 systemctl status docker-compose-app
是你要找的东西。
不适合我,当我运行systemctl start docker-compose-app
时遇到了这个:Job for docker-compose-app.service failed because the control process exited with error code. See "systemctl status docker-compose-app.service" and "journalctl -xe" for details
@dmigo:使用service docker-compose-app start
测试服务的启动,service docker-compose-app status
的状态,service docker-compose-app stop
的停止【参考方案2】:
你应该可以添加:
restart: always
docker-compose.yml
文件中要重新启动的每个服务。
见:https://github.com/compose-spec/compose-spec/blob/master/spec.md#restart
【讨论】:
请记住,它们必须在重新启动时运行,所以不要在重新启动之前手动停止它们。 有些服务比如 nginx 甚至没有这个选项启动。 这是问题的正确答案。有一种重新启动容器的设计方法,为什么要进入 cron 作业和其他重新发明***的方法。 @TahaRehmanSiddiqui 请注意,restart: always
有一些严重的错误:例如,重新启动时不会附加主机挂载。在我看来,如果现有的***是方形的,最好重新发明***。
为什么“重启:总是”而不是“重启:除非停止”?两者都应该做我想说的工作【参考方案3】:
如果您的docker.service
在系统启动时启用
$ sudo systemctl enable docker
并且您在docker-compose.yml
中的服务有
restart: always
如果您只运行一次以下命令,则所有服务都会在您重新启动系统时运行
docker-compose up -d
【讨论】:
这应该是最优雅的解决方案 为什么“重启:总是”而不是“重启:除非停止”?两者都应该做我想说的工作 @rastov 两者相似,但在容器停止(手动或其他方式)时除非停止,即使在 Docker 守护进程重新启动后也不会重新启动。 "如果 you 在命令下只运行一次" - 但是,像 systemd 或 init.d 这样的进程管理器的目的是消除循环中的人。为了让人类离开,需要@oleg-belostotsky 的策略。【参考方案4】:我试过restart: always
,它适用于某些容器(如php-fpm),但我遇到了一些容器(如nginx)在重启后仍然没有重启的问题。
解决了这个问题。
crontab -e
@reboot (sleep 30s ; cd directory_has_dockercomposeyml ; /usr/local/bin/docker-compose up -d )&
【讨论】:
你应该怀疑裸睡,因为它们会引入非确定性行为:martinfowler.com/articles/… @giorgiosironi sleep 在这种情况下很好。无论如何,容器启动必须能够处理不确定的行为。 它还引入了可能不需要的长达 30 秒的延迟。 @z0r 睡眠不好!睡眠可能“工作”,但任何启动顺序都应该是确定性的。 Linux 服务在启动之前使用依赖关系来确保网络可用等。你也应该这样做。【参考方案5】:在您的 docker compose 文件中使用 restart: always。
Docker-compose up -d
将再次从镜像启动容器。使用docker-compose start
启动停止的容器,它永远不会从镜像启动新容器。
nginx:
restart: always
image: nginx
ports:
- "80:80"
- "443:443" links:
- other_container:other_container
如果它有其他容器的依赖项,你也可以将代码写在 docker 文件中,以便首先创建它。
【讨论】:
你可能不想使用always
,但也许是unless-stopped
。其他选项是on-failure
和no
。这被称为restart policy。
只添加该行应该可以吗?是否有关于如何启用整个解决方案的教程?谢谢!【参考方案6】:
作为user39544
答案的补充,crontab -e
的另一种语法类型:
@reboot sleep 60 && /usr/local/bin/docker-compose -f /path_to_your_project/docker-compose.yml up -d
【讨论】:
这在 2018 年 3 月在运行 Raspian 的 RPi3 上为我工作。我以用户 pi 的身份运行crontab -e
,其中 pi 是 docker 组的成员...【参考方案7】:
restart: unless-stopped
docker-compose.yml
【讨论】:
以上是关于如何在系统启动时运行 docker-compose up -d?的主要内容,如果未能解决你的问题,请参考以下文章
使用 docker-compose 时如何在容器内使用主机用户修改卷文件