Установка Laravel Horizon в Docker
7 августа 2025

Конфигурация на базе предыдущей статьи про выкатку laravel в docker
План действий:
- 1 - В контейнер с php надо добавить redis
- 2 - В контейнер с deployer добавить pcntl
- 3 - Добавить enrypoint для horizon, чтобы при остановке сервиса он дожидался, пока завершатся текущие задачи
- 4 - Добавить контейнер в конфигурацию docker-compose.yml
- 5 - Добавить команды на остановку и запуск контейнера c horizon в deploy.php
1:
Для запуска в production my_app-php-fpm надо обновить, добавив в него redis:
my_app-php-fpm/Dockerfile
my_app-php-fpm/Dockerfile
FROM php:8.4-fpm RUN apt-get update && apt-get -y update && \ apt-get install -y libpng-dev libfreetype6-dev libjpeg62-turbo-dev libonig-dev libwebp-dev libicu-dev libzip-dev ffmpeg && \ docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp && \ docker-php-ext-install -j$(nproc) pdo pdo_mysql mbstring mysqli bcmath fileinfo gd intl zip pcntl #RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" # Install dependencies and Redis extension RUN apt-get install -y \ libssl-dev \ pkg-config \ build-essential \ && pecl channel-update pecl.php.net \ && pecl install redis-6.1.0 \ && docker-php-ext-enable redis \ && apt-get purge -y --auto-remove build-essential pkg-config \ && rm -rf /var/lib/apt/lists/* RUN groupadd -r -g 1002 user && useradd -rm -d /home/user -s /bin/bash -g 1002 -u 1002 user
2:
Также возникнет проблема во время выкатки. Для решения можно отключить проверку окружения или добавить pcntl
Внести изменения в образ deplyer
deployer-with-node/Dockerfile
Внести изменения в образ deplyer
deployer-with-node/Dockerfile
# Назвать deployer-with-node, именно это прописано в gitlab runner config.toml # Используется внутри gitlab runner для выкатки проекта # Собирать на машине, где будет выкатка # docker build -t deployer-with-node . FROM deployphp/deployer:v7 # Install dependencies for Node.js and build tools RUN apk add --no-cache \ curl \ python3 \ make \ g++ # Install Node.js 22 using Alpine's package manager (simple but may not be latest 22.x) RUN apk add --no-cache nodejs npm # OR for exact Node.js 22 version (better approach): RUN curl -fsSL https://unofficial-builds.nodejs.org/download/release/v22.17.1/node-v22.17.1-linux-x64-musl.tar.xz | tar -xJ -C /usr --strip-components=1 --no-same-owner RUN echo $(less /etc/apk/repositories) RUN apk add --no-cache docker docker-compose # Verify Docker Compose RUN docker compose version RUN apk add --no-cache mariadb-client RUN mysql --version RUN docker-php-ext-install pdo pdo_mysql mysqli RUN rm -rf /var/cache/apk/* # Verify installations RUN node --version && npm --version && docker --version RUN docker-php-ext-install pcntl
3:
docker/horison/entry_point.sh
#!/bin/sh # Start the Horizon process php /var/www/my_app/current/artisan horizon & # store the horizon process id HORIZON_PID=$! stop_horizon() { # Terminate the Horizon process php /var/www/my_app/current/artisan horizon:terminate # Wait for the Horizon process to exit wait $HORIZON_PID exit 0 } trap 'stop_horizon' TERM # This wait ensures the script itself does not exit until Horizon process is done wait $HORIZON_PID exit 0
4:
docker-compose.yml
my_app-php-horizon: container_name: my_app-php-horizon build: context: ./my_app-php-fpm # тот же, что и для основного приложения restart: unless-stopped entrypoint: ["/var/www/my_app/current/docker/horizon/entry_point.sh", ""] stop_grace_period: 5m # Даем скриптам до 5 минут. Тут возможны варианеты networks: - my_app depends_on: - redis volumes: # - type: bind # source: ./my_app-php-fpm/www.conf # target: /usr/local/etc/php-fpm.d/www.conf - type: bind source: ./my_app-php-fpm/php.ini target: /usr/local/etc/php/php.ini - /var/www:/var/www
5:
deploy.php, поменять task('reload', function () { ...
task('reload', function () { run('docker compose -f /home/user/my_app/deploy/docker-compose.yml stop my_app-php-horizon'); run('docker compose -f /home/user/my_app/deploy/docker-compose.yml restart my_app-php-fpm'); run('docker compose -f /home/user/my_app/deploy/docker-compose.yml restart nginx'); run('docker compose -f /home/user/my_app/deploy/docker-compose.yml start my_app-php-horizon'); });