Skip to content

Commit b2fe6af

Browse files
committed
feat: add ddev-cron configuration and Dockerfile, implement scheduled tasks for queued jobs and heartbeat
1 parent 006673e commit b2fe6af

8 files changed

Lines changed: 121 additions & 43 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: ddev-cron
2+
repository: ddev/ddev-cron
3+
version: 1.9.0
4+
install_date: "2026-06-16T22:17:06+02:00"
5+
project_files:
6+
- web-build/Dockerfile.ddev-cron
7+
- web-build/cron.conf
8+
- web-build/time.cron.example
9+
global_files: []
10+
removal_actions: []
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ddev-generated
2+
# Install cron package; this can be done in webimage_extra_packages, but put it here for now.
3+
RUN (apt-get update || true) && DEBIAN_FRONTEND=noninteractive apt-get install -y -o Dpkg::Options::="--force-confold" --no-install-recommends --no-install-suggests cron
4+
5+
# Copy our custom config
6+
COPY ./cron.conf /etc/supervisor/conf.d/cron.conf
7+
8+
# Make it so you can add to cron.d without root privileges
9+
RUN chmod 777 /etc/cron.d /var/run
10+
11+
# Copy over our custom jobs
12+
COPY ./*.cron /etc/cron.d/
13+
14+
# Give execution rights on the cron jobs
15+
RUN chmod -f 0644 /etc/cron.d/*.cron || true
16+
17+
# Concatenate files
18+
RUN { cat /etc/cron.d/*.cron; } | crontab -u ${username} -

.ddev/web-build/cron.conf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ddev-generated
2+
[program:cron]
3+
command=sudo /usr/sbin/cron -f -L7
4+
autorestart=true
5+
startretries=10
6+
stdout_logfile=/proc/self/fd/2
7+
stdout_logfile_maxbytes=0
8+
redirect_stderr=true

.ddev/web-build/local.cron

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# ddev exec service cron reload
2+
* * * * * cd /var/www/html && php artisan schedule:run >> /dev/null 2>&1

app/Providers/AppServiceProvider.php

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,11 @@
1111

1212
class AppServiceProvider extends ServiceProvider
1313
{
14-
/**
15-
* Register any application services.
16-
*/
1714
public function register(): void
1815
{
1916
//
2017
}
2118

22-
/**
23-
* Bootstrap any application services.
24-
*/
2519
public function boot(): void
2620
{
2721
if (app()->environment('production')) {
@@ -43,11 +37,6 @@ public function boot(): void
4337
$this->registerBladeDirectives();
4438
}
4539

46-
/**
47-
* Register custom Blade directives for settings.
48-
*
49-
* @return void
50-
*/
5140
private function registerBladeDirectives(): void
5241
{
5342
Blade::directive('settings', function (string $expression): string {

app/Providers/Filament/AdminPanelProvider.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ public function panel(Panel $panel): Panel
9191
$panel->plugin($votingPluginClass::make());
9292
}
9393

94+
$discordPluginClass = 'SilkPanel\\Discord\\DiscordPlugin';
95+
if (class_exists($discordPluginClass)) {
96+
$panel->plugin($discordPluginClass::make());
97+
}
98+
9499
return $panel;
95100
}
96101
}

composer.lock

Lines changed: 70 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

routes/console.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,11 @@
44
use Illuminate\Support\Facades\Schedule;
55

66
Schedule::command(ProcessReferrals::class)->hourly();
7+
8+
// Processes queued jobs (e.g. Discord webhooks) every minute and exits when the queue is empty.
9+
// This is an alternative to running a persistent queue:work daemon.
10+
// Requires the scheduler itself to be triggered via cron: * * * * * php artisan schedule:run
11+
Schedule::command('queue:work --stop-when-empty')->everyMinute()->withoutOverlapping();
12+
13+
// Writes a heartbeat timestamp to cache so the admin panel can detect whether the scheduler is running.
14+
Schedule::call(fn() => cache()->put('silkpanel_scheduler_last_run', now()->toIso8601String(), now()->addMinutes(10)))->everyMinute()->name('scheduler-heartbeat');

0 commit comments

Comments
 (0)