Stan's blog

Docker Linux Laravel

Установка Laravel Horizon в Docker

7 августа 2025
AI generation by qwen

Конфигурация на базе предыдущей статьи про выкатку laravel в docker

План действий:
  1. 1 - В контейнер с php надо добавить redis
  2. 2 - В контейнер с deployer добавить pcntl
  3. 3 - Добавить enrypoint для horizon, чтобы при остановке сервиса он дожидался, пока завершатся текущие задачи
  4. 4 - Добавить контейнер в конфигурацию docker-compose.yml
  5. 5 - Добавить команды на остановку и запуск контейнера c horizon в deploy.php

1:

Для запуска в production my_app-php-fpm надо обновить, добавив в него redis:
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
# Назвать 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');
});

ссылки:
Laravel Horizon в Docker