如何在系统启动时运行docker-compose up -d?


114

为了让容器在启动时自动启动,我尝试添加以下命令:

cd directory_has_docker-compose.yml && docker-compose up -d 在/etc/rc.local中。

但是在我重新启动机器后,这些容器不起作用。

docker-compose up -d系统启动时如何运行?


3
在docker-compose.yml中使用--restart alwaysor --restart unless-stoppedrestart: always-> Ref。但是也许不能在某些容器上工作!
本雅明·贾法里

Answers:


130

当使用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

WorkingDirectory使用您的dockerized项目路径更改参数。并启用该服务以自动启动:

systemctl enable docker-compose-app

有没有一种简单的方法可以测试它是否有效而无需重新启动树莓派?
dmigo

2
这是国际海事组织最优雅的答案
库赞

2
@dmigo systemctl start docker-compose-appsystemctl status docker-compose-app这就是我想要的。
HectorJ

当我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
Benyamin Jafari

1
@dmigo:使用以下命令测试服务的启动:service docker-compose-app start,状态为service docker-compose-app status,停止为service docker-compose-app stop
BarryPye

96

您应该能够添加:

restart: always 

到您要在docker-compose.yml文件中重新启动的每个服务


6
请记住,重新启动时它们必须处于运行状态,因此请勿在重新启动之前手动停止它们。
汤姆

某些服务(例如Nginx)甚至都不以该选项开头。
Benyamin Jafari

15
这是对问题的正确答案。有一种重新设计容器的设计方法,为什么要进行cron作业以及其他方法来重新发明轮子。
塔哈·雷曼·西迪基

这是正确的答案。当您开始使用Kubernetes代替cron时,您会很高兴使用它。
pferrel

9
@TahaRehmanSiddiqui请注意,这里restart: always有一些严重的错误:例如,重新启动时不会挂载主机座。我认为,如果现有的车轮是方形的,则最好重新设计车轮。
okdewit

73

如果您docker.service在系统启动时启用

$ sudo systemctl enable docker

而您所docker-compose.yml拥有的服务

restart: always

如果仅在命令下方运行一次,则所有服务都会在重新引导系统时运行

docker-compose up -d

2
这应该是最优雅的解决方案
张学友

34

我试过了restart: always,它可以在某些容器(例如php-fpm)上工作,但是我遇到的问题是某些容器(例如nginx)在重新启动后仍无法重新启动。

解决了问题。

crontab -e

@reboot (sleep 30s ; cd directory_has_dockercomposeyml ; /usr/local/bin/docker-compose up -d )&

2
为什么对这个答案不满意?答案没有用吗?从任何意义上说错了吗?让评论者和其他人知道出了什么问题是很有用的。
Ayushya

5
你应该suspicuous裸睡觉,因为他们引入不确定性的行为:martinfowler.com/articles/...
giorgiosironi

在这种情况下,@ giorgiosironi的睡眠很好。无论如何,容器启动必须能够处理不确定性行为。
z0r

4
它还引入了可能不需要的长达30秒的延迟。
giorgiosironi

@ z0r睡眠不好!睡眠可能“起作用”,但是任何启动顺序都应是确定性的。Linux服务使用依赖项来确保诸如网络之类的事物在启动之前可用。您应该做同样的事情。
colm.anseo,

25

使用重启:始终在您的docker compose文件中。

Docker-compose up -d将再次从图像启动容器。使用docker-compose start启动停止容器,它永远不会启动从图像中新的容器。

nginx:   
    restart: always   
    image: nginx   
    ports:
      - "80:80"
      - "443:443"   links:
      - other_container:other_container

您也可以将代码写在docker文件中,以便在具有其他容器依赖性的情况下首先创建代码。


1
您可能不想使用always,但是也许unless-stopped。其他选项是on-failureno。这称为重启策略
保罗

5

除了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上起作用。我crontab -e以用户pi的身份运行,而pi是组
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.