https://learnku.com/articles/7022/using ... -in-docker
在 Docker 中部署 Laravel 应用,难免会用到 Laravel 本身的任务调度系统 (Schedule),而 Schedule 需要用到 cron,在 Docker 中使用 cron,有以下三种方案:
使用独立的 cron 容器。❎ 如果有多个不同的容器应用需要依赖 cron 时,那么这是一种很完美的解决方案,但是我们只用到 Laravel 的任务调度,因此独立的 cron 容器显得多余,所以不能采用此方案。
直接使用宿主机的 cron。❎ 如果直接使用宿主机的 cron,那么「定时任务」这个功能就不属于容器的一部分了。以后在应用迁移与快速部署时,cron 需要单独配置,这违背了我们使用 Docker 的初衷,我们的初衷是希望用 docker-compose up 这一个命令就能快速构建出一个线上应用。并且,在宿主机上使用 cron,使用 Laravel schedule 任务调度时不能和 MySQL 或 Redis 进行通信,所以这个方案需要被否决。
在 PHP 容器中设置 cron。✅ 这才是最佳解决方案。Laravel 只需要在 cron 中配置一个 Laravel Task Scheduler,使用此容器中的 PHP 执行文件可以直接执行 Laravel 的任务调度。
在 PHP 容器中使用 cron
我们直接使用基于 Ubuntu 的 php:7.1.11-fpm 的 Docker Hub 的官方镜像,然后需要在 Dockerfile 文件中安装 cron.
RUN apt-get install cron -y
然后在 Dockerfile 文件所在目录下创建 crontab 文件,内容为:
* * * * * /usr/local/bin/php /your_laravel_app_path/artisan schedule:run >> /dev/null 2>&1
其中 your_laravel_app_path 为 Laravel 应用在容器中的实际路径。
其实上面这一步我是踩了坑的,之前我一直按照官方手册的以下写法来配置的:
* * * * * php /your_laravel_app_path/artisan schedule:run >> /dev/null 2>&1
打了日志之后我才发现,容器内无法直接找到 PHP 的执行文件,所以要写全 PHP 执行文件的完整路径,例如 /usr/local/bin/php。当然,PHP 执行文件的路径可能会有所不同,如果不清楚,需要到 PHP 容器中查看一下。
然后继续写 Dockerfile,将 crontab 文件映射到容器目录中,赋予其读写权限:
COPY ./crontab /var/spool/cron/crontabs/root
RUN chmod 0644 /var/spool/cron/crontabs/root
RUN crontab /var/spool/cron/crontabs/root
至于第三行的命令,这么做是为了使 crontab 配置生效,我参考了 这篇文章,具体原因没有深究。
注意:如果容器文件系统是 Debian,cron 的配置路径是有所不同的,本文不赘述,这里只讨论 Ubuntu 的镜像
运行 cron
一开始我直接在 Dockerfile 中写了 CMD ["cron"],发现 PHP-FPM 服务不启动了,是因为 Dockerfile 中只会执行一次 CMD 命令,多条 CMD 只执行最后一条,CMD ["cron"] 把 CMD ["php-fpm"] 覆盖了。
因此我们需要一个 bash 脚本来启动 cron,在 Dockerfile 文件所在目录下创建 entrypoint.sh,文件内容为:
#!/bin/bash
set -e
cron
exec "$@"
然后使用 ENTRYPOINT 命令添加到 Dockerfile 就好。
完整的 Dockerfile 文件应该是这个样子:
######
# See: https://hub.docker.com/_/php/
######
FROM php:7.1.11-fpm
RUN apt-get update && apt-get install -y cron
RUN rm -rf /var/lib/apt/lists
COPY ./crontab /var/spool/cron/crontabs/root
RUN chmod 0644 /var/spool/cron/crontabs/root
RUN crontab /var/spool/cron/crontabs/root
COPY ./entrypoint.sh /usr/local/bin/
ENTRYPOINT ["entrypoint.sh"]
CMD ["php-fpm"]
重点结论
要在容器中使用 cron,需要在 Dockerfile 中安装 cron,并将 crontab 配置信息映射到容器内。
crontab 配置 Laravel-scheduler 时,要填写 PHP 的执行文件路径,不然可能无法正确执行。
要写单独的脚本启动 cron,否则会覆盖掉 PHP 容器的 PHP-FPM 服务。
在 Docker 中使用 Laravel schedule
前往
- Software
- ↳ CodeCharge Studio
- ↳ CodeCharge
- ↳ DemoCharge
- ↳ SuperPDF
- ↳ 551einv
- ↳ E3進銷存
- 程式語言
- ↳ PHP
- ↳ CodeLobster PHP Edition
- ↳ Yii
- ↳ CodeIgniter
- ↳ Phalcon
- ↳ Symfony
- ↳ FuelPHP
- ↳ Zend Framework 2
- ↳ laravel
- ↳ WordPress
- ↳ ASP.NET/C#
- ↳ ASP/VBScript
- ↳ JSP
- ↳ Java Servlets
- ↳ ColdFusion
- ↳ Perl
- ↳ Java Script
- ↳ jQuery
- ↳ HTML + CSS
- ↳ jQuery
- ↳ nodejs
- ↳ VB6
- ↳ Git
- ↳ App Inventor 2
- ↳ bash
- ↳ C++/ VC/ OpenCV
- ↳ OpenCV
- ↳ go
- ↳ cordova
- ↳ python
- ↳ Xamarin
- ↳ Assembly
- 資料庫
- ↳ MySQL
- ↳ PostgreSQL
- ↳ ORACLE
- ↳ Access
- ↳ SQL Server
- ↳ SQLite
- ↳ MariaDB
- ↳ Mongodb
- 作業系統
- ↳ Linux
- ↳ Ubuntu
- ↳ CentOS
- ↳ Mint
- ↳ Mandriva
- ↳ Debian
- ↳ Red Hat Enterprise Linux
- ↳ Oracle Linux
- ↳ Fedora
- ↳ Kali Linux
- ↳ OpenSUSE
- ↳ Elementary OS
- ↳ Microsoft
- ↳ Server 2008 R2
- ↳ Server 2012 R2
- ↳ Server 2012
- ↳ 8
- ↳ 10
- ↳ System Center 2016
- ↳ NOVELL
- ↳ FreeBSD
- ↳ VMware
- ↳ VirtualBox
- ↳ Mac OS X
- ↳ Solaris
- ↳ iOS
- ↳ Android
- ↳ Cloud
- ↳ OpenStack
- ↳ Docker
- ↳ Proxmox VE
- ↳ CloudReady
- ↳ chrome
- 網頁伺服器
- ↳ apache
- ↳ tomcat
- ↳ nginx
- ↳ IIS
- ↳ JBoss
- ↳ weblogic
- ↳ WebHosting
- 硬體
- ↳ 硬體及週邊
- ↳ RouterOS
- ↳ LEGO NXT
- ↳ Arduino
- ↳ MSP430
- ↳ Raspberry Pi
- ↳ OpenERP
- ↳ Storage
- ↳ Server
- ↳ Brocade
- ↳ MODELS
- ↳ FortiGate
- 軟體
- ↳ sublime
- ↳ LibreNMS