Laradock 에서 cron 스케쥴러 및 Laravel Horizon 설치

Cron scheduler 와 queue 를 사용하는 로직을 로컬에서 구현하기 위해서는 local 피씨에도 해당 인프라를 만들어 놓는 것이 필요한데, Laradock 의 기본 설정은 내가 원하는 설정 부분이 빠져있거나, 사소한 오류로 인하여, Out of box 동작이 되지 않았기 때문에, 이를 위한 로컬 셋팅 작업을 한 뒤, 이 글을 빌어 그 기록을 남겨둔다.

cron 스케쥴러

크론 스케쥴러는 workspace 컨테이너에서 동작하며, 아래와 같이 workspace/crontab/laradock 에 내용을 아래 샘플과 같이 수정한 뒤 컨테이너 빌드를 다시하면 동작했다. * * * * * laradock php /var/www/backend/artisan schedule:run >> /dev/null 2>&1 컨테이너 리빌드는 아래 명령을 사용하면 된다. docker-compose up -d --force-recreate --build workspace

Laravel Horizon

Laravel 다양한 queue 옵션들 중에, 이번 설정에서는 Redis 큐를 사용했다.
  1. Laravel Horizon 설치
공식 문서의 설명대로 아래 일련의 명령들을 사용하면 패키지 설정과 DB 설정이 마무리된다.
composer require laravel/horizon
php artisan horizon:install
php artisan queue:failed-table
php artisan migrate
  1. Laravel codebase 내의 설정
Redis connection 등의 구체적인 설정내용을 명시하는 아래의 설정 파일들을 수정해야 하는데, 그 내용은 공식 문서내에 설명이 상세하게 되어 있으므로 구체적 내용은 생략한다.
config/horizon.php
config/database.php
config/queue.php
.env
  1. Laradock 설정
php-worker 컨테이너에 관련한 디렉토리내의 모든 파일들을 수정했었어야만 했는데, 어느 부분을 어떻게 수정했는지를 일일이 설명하는 것이 오히려 한눈에 변경사항을 알아보기가 어려울 듯 해서, 현재 로컬 피씨 해당 디렉토리내의 working example 을 그대로 리스팅하였다. 3.1. Dockerfile
#
#--------------------------------------------------------------------------
# Image Setup
#--------------------------------------------------------------------------
#

ARG PHP_VERSION=${PHP_VERSION}
FROM php:${PHP_VERSION}-alpine

LABEL maintainer="Mahmoud Zalt <[email protected]>"

RUN apk --update add wget \
  curl \
  git \
  build-base \
  libmemcached-dev \
  libmcrypt-dev \
  libxml2-dev \
  zlib-dev \
  autoconf \
  cyrus-sasl-dev \
  libgsasl-dev \
  supervisor

RUN docker-php-ext-install mysqli mbstring pdo pdo_mysql tokenizer xml pcntl
RUN pecl channel-update pecl.php.net && pecl install memcached mcrypt-1.0.1 && docker-php-ext-enable memcached

# Install PostgreSQL drivers:
ARG INSTALL_PGSQL=false
RUN if [ ${INSTALL_PGSQL} = true ]; then \
    apk --update add postgresql-dev \
        && docker-php-ext-install pdo_pgsql \
;fi

# Install Redis
ARG INSTALL_PHPREDIS=false

RUN if [ ${INSTALL_PHPREDIS} = true ]; then \
    # Install Php Redis Extension
    printf "\n" | pecl install -o -f redis \
    &&  rm -rf /tmp/pear \
    &&  docker-php-ext-enable redis \
;fi

RUN rm /var/cache/apk/* \
    && mkdir -p /var/www

#
#--------------------------------------------------------------------------
# Optional Supervisord Configuration
#--------------------------------------------------------------------------
#
# Modify the ./supervisor.conf file to match your App's requirements.
# Make sure you rebuild your container with every change.
#

COPY supervisord.conf /etc/supervisord.conf

ENTRYPOINT ["/usr/bin/supervisord", "-n", "-c",  "/etc/supervisord.conf"]

#
#--------------------------------------------------------------------------
# Optional Software's Installation
#--------------------------------------------------------------------------
#
# If you need to modify this image, feel free to do it right here.
#
    # -- Your awesome modifications go here -- #

#
#--------------------------------------------------------------------------
# Check PHP version
#--------------------------------------------------------------------------
#

RUN php -v | head -n 1 | grep -q "PHP ${PHP_VERSION}."

#
#--------------------------------------------------------------------------
# Final Touch
#--------------------------------------------------------------------------
#

WORKDIR /etc/supervisor/conf.d
3.2. supervisord.conf
[supervisord]
nodaemon=true
[supervisorctl]
[inet_http_server]
port = 127.0.0.1:9001
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[include]
files = /etc/supervisor/conf.d/*.conf
3.3. supervisord.d/laravel-worker.conf
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/backend/artisan queue:work redis --sleep=3 --tries=3
autostart=true
autorestart=true
numprocs=4
redirect_stderr=true
3.4. supervisord.d/horizon.conf
[program:horizon]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/backend/artisan horizon
autostart=true
autorestart=true
;user=laradock
numprocs=1
redirect_stderr=true
;stdout_logfile=/etc/supervisor/conf.d/horizon.log
  1. docker-compose.yml
마지막으로 상위 폴더에 있는 docker-compose.yml 파일도 PHP Worker 관련 설정이 아래와 같이 수정되었다.
### PHP Worker ############################################
    php-worker:
      build:
        context: ./php-worker
        args:
          - PHP_VERSION=${PHP_VERSION}
          - INSTALL_PHPREDIS=${PHP_WORKER_INSTALL_PHPREDIS}
          - INSTALL_PGSQL=${PHP_WORKER_INSTALL_PGSQL}
      volumes:
        - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
        - ./php-worker/supervisord.d:/etc/supervisor/conf.d
      depends_on:
        - workspace
      extra_hosts:
        - "dockerhost:${DOCKER_HOST_IP}"
        - "demo.test:${HOST_IP_ADDRESS}"
        - "backend.test:${HOST_IP_ADDRESS}"
      networks:
        - backend
위 Cron 스케쥴러때와 마찬가지로 아래와 같은 컨테이너 리빌딩이 필요하다. docker-compose up -d --force-recreate --build php-worker 리빌딩이 끝나면 정상적으로 동작 하겠지만, 혹시나 supervisor 설정을 변경했을 경우, 아래의 명령으로 커맨드라인 접속 후 docker-compose exec php-worker ash supervisor 의 새로운 설정내용을 반영하도록 한다.
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*
이제 backend.test/horizon 에 접속하면, 위의 dashboard 가 출력되는 것을 확인할 수 있다. Yay!

Further readings

https://laravel.com/docs/5.7/queues https://laravel.com/docs/5.7/horizon
Laravel Queues & Horizon Dashboard

Leave a Reply