👋
LaravelにDockerファイルでcronを導入して定期的にメール送信する方法
dockerでcronを導入する方法が日本語では見つからなかったので書きました。
dockerファイルの書き方が全くわからない人は難しいです。
以下の例ではdocker内部ではprojectフォルダにソースを入れています。
あとdocker-composeでマウントする場合はCOPY . /project/が不要、 最後のRUN 以降で、chmod 0644 /etc/cron.d/cronとtouch /var/log/cron.log以外は不要です。
通常のLaravelで立ち上げるdockerファイルとは分けましょう。
app/docker/cron/dockerfile
FROM php:7-fpm
ENV DEBIAN_FRONTEND noninteractive
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN apt-get update && apt-get -y install git cron libicu-dev libonig-dev libzip-dev unzip &&\
apt-get clean && \
rm -rf /var/lib/apt/lists/* &&\
docker-php-ext-install pdo_mysql &&\
composer config -g process-timeout 3600 && \
mkdir -p /project
COPY . /project/
COPY ./docker/cron/php.ini /usr/local/etc/php/php.ini
COPY ./docker/cron/root /etc/cron.d/cron
WORKDIR /project
RUN composer install &&\
chmod -R a+w storage/ bootstrap/cache &&\
chmod 0644 /etc/cron.d/cron &&\
touch /var/log/cron.log &&\
php artisan cache:clear &&\
php artisan config:clear &&\
php artisan route:clear
CMD cron -f
project/docker/cron/root
* * * * * root /usr/local/bin/php -q -f /project/artisan schedule:run --no-ansi >> /dev/null 2>&1
project/app/Console/Kernel.phpで、
protected function schedule(Schedule $schedule)
{
$schedule->command('email:send')->hourly()->onOneServer();
}
コマンドは公式を参照しましょう。
php artisan make:command SendMailTest
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\User;
use App\Mail\SendMail;
use Illuminate\Support\Facades\Mail;
use Carbon\Carbon;
class SendMailTest extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'email:send';
/**
* The console command description.
*
* @var string
*/
protected $description = 'メールを定期的に配信する';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// 対象者を絞ったり
$user = User::find(対象者);
// 内容をDBから取り出しておいたり、
$contents = ~~~
Mail::to($user)->send(new SendMail($contents));
}
}
php artisan make:mail SendMail
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class SendMail extends Mailable
{
use Queueable, SerializesModels;
// 引数で受け取る変数
protected $user;
protected $contents;
// コンストラクタ設定
public function __construct($user,$contents)
{
// 引数で受け取ったデータを変数にセット
$this->user = $user;
$this->contents = $contents;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this
->subject('メールのタイトル')
->view('emails.content')
->with([
'user' => $this->user,
'contents' => $this->contents,
]);
}
}
resources/views/emailsディレクトリを作成し、content.blade.phpを作成します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<style type="text/css">
<!-- 何かしらの内容 -->
</style>
</head>
<body>
<!-- 何かしらの内容 -->
</body>
</html>
内容面は適宜カスタマイズしてください。
Discussion