From 46e6b1f09706d395b8a8a2b40d3322420c2c9c9e Mon Sep 17 00:00:00 2001 From: Curtis Delicata Date: Mon, 1 Jul 2024 01:37:09 +0000 Subject: [PATCH] Configure new Octane Docker --- .docker/octane/Swoole/supervisord.swoole.conf | 28 ++- .docker/start-container | 12 +- .docker/supervisord.conf | 14 ++ Dockerfile | 212 ++++++++++++------ 4 files changed, 190 insertions(+), 76 deletions(-) create mode 100644 .docker/supervisord.conf diff --git a/.docker/octane/Swoole/supervisord.swoole.conf b/.docker/octane/Swoole/supervisord.swoole.conf index 15db3ac..228e01e 100644 --- a/.docker/octane/Swoole/supervisord.swoole.conf +++ b/.docker/octane/Swoole/supervisord.swoole.conf @@ -1,12 +1,6 @@ -[supervisord] -nodaemon=true -user=%(ENV_USER)s -logfile=/var/log/supervisor/supervisord.log -pidfile=/var/run/supervisord.pid - [program:octane] process_name=%(program_name)s_%(process_num)02d -command=php %(ENV_ROOT)s/artisan octane:start --server=swoole --host=0.0.0.0 --port=80 +command=php %(ENV_ROOT)s/artisan octane:start --server=swoole --host=0.0.0.0 --port=8000 user=%(ENV_USER)s autostart=true autorestart=true @@ -22,7 +16,10 @@ command=php %(ENV_ROOT)s/artisan horizon user=%(ENV_USER)s autostart=%(ENV_WITH_HORIZON)s autorestart=true -stdout_logfile=%(ENV_ROOT)s/horizon.log +stdout_logfile=%(ENV_ROOT)s/storage/logs/horizon.log +stdout_logfile_maxbytes=200MB +stderr_logfile=%(ENV_ROOT)s/storage/logs/horizon.log +stderr_logfile_maxbytes=200MB stopwaitsecs=3600 [program:scheduler] @@ -31,7 +28,10 @@ command=supercronic -overlapping /etc/supercronic/laravel user=%(ENV_USER)s autostart=%(ENV_WITH_SCHEDULER)s autorestart=true -stdout_logfile=%(ENV_ROOT)s/scheduler.log +stdout_logfile=%(ENV_ROOT)s/storage/logs/scheduler.log +stdout_logfile_maxbytes=200MB +stderr_logfile=%(ENV_ROOT)s/storage/logs/scheduler.log +stderr_logfile_maxbytes=200MB [program:clear-scheduler-cache] process_name=%(program_name)s_%(process_num)02d @@ -39,4 +39,12 @@ command=php %(ENV_ROOT)s/artisan schedule:clear-cache user=%(ENV_USER)s autostart=%(ENV_WITH_SCHEDULER)s autorestart=false -stdout_logfile=%(ENV_ROOT)s/scheduler.log \ No newline at end of file +startsecs=0 +startretries=1 +stdout_logfile=%(ENV_ROOT)s/storage/logs/scheduler.log +stdout_logfile_maxbytes=200MB +stderr_logfile=%(ENV_ROOT)s/storage/logs/scheduler.log +stderr_logfile_maxbytes=200MB + +[include] +files=/etc/supervisor/supervisord.conf diff --git a/.docker/start-container b/.docker/start-container index 0bab02b..8816674 100644 --- a/.docker/start-container +++ b/.docker/start-container @@ -1,15 +1,23 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh set -e -container_mode=${CONTAINER_MODE:-http} +container_mode=${CONTAINER_MODE:-"http"} octane_server=${OCTANE_SERVER} +running_migrations_and_seeders=${RUNNING_MIGRATIONS_AND_SEEDERS:-"false"} + echo "Container mode: $container_mode" initialStuff() { + php artisan storage:link; \ php artisan optimize:clear; \ php artisan event:cache; \ php artisan config:cache; \ php artisan route:cache; + + if [ ${running_migrations_and_seeders} = "true" ]; then + echo "Running migrations and seeding database ..." + php artisan migrate --isolated --seed --force; + fi } if [ "$1" != "" ]; then diff --git a/.docker/supervisord.conf b/.docker/supervisord.conf new file mode 100644 index 0000000..83f9591 --- /dev/null +++ b/.docker/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +nodaemon=true +user=%(ENV_USER)s +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[unix_http_server] +file=/var/run/supervisor.sock + +[supervisorctl] +serverurl=unix:///var/run/supervisor.sock + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface diff --git a/Dockerfile b/Dockerfile index b72d24a..8ecea1b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,64 +1,148 @@ -ARG ALPINE_VERSION=3.19 -FROM alpine:${ALPINE_VERSION} -LABEL Maintainer="Tim de Pater " -LABEL Description="Lightweight container with Nginx 1.24 & PHP 8.3 based on Alpine Linux." -# Setup document root -WORKDIR /var/www/html - -# Install packages and remove default server definition -RUN apk add --no-cache \ - curl \ - nginx \ - php83 \ - php83-ctype \ - php83-curl \ - php83-dom \ - php83-fileinfo \ - php83-fpm \ - php83-gd \ - php83-intl \ - php83-mbstring \ - php83-mysqli \ - php83-opcache \ - php83-openssl \ - php83-phar \ - php83-session \ - php83-tokenizer \ - php83-xml \ - php83-xmlreader \ - php83-xmlwriter \ - supervisor - -# Configure nginx - http -COPY .docker/config/nginx.conf /etc/nginx/nginx.conf -# Configure nginx - default server -COPY .docker/config/conf.d /etc/nginx/conf.d/ - -# Configure PHP-FPM -ENV PHP_INI_DIR /etc/php83 -COPY .docker/config/fpm-pool.conf ${PHP_INI_DIR}/php-fpm.d/www.conf -COPY .docker/config/php.ini ${PHP_INI_DIR}/conf.d/custom.ini - -# Configure supervisord -COPY .docker/config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf - -# Make sure files/folders needed by the processes are accessable when they run under the nobody user -RUN chown -R nobody.nobody /var/www/html /run /var/lib/nginx /var/log/nginx - -# Create symlink for php -RUN ln -s /usr/bin/php83 /usr/bin/php - -# Switch to use a non-root user from here on -USER nobody - -# Add application -COPY --chown=nobody . /var/www/html/ - -# Expose the port nginx is reachable on -EXPOSE 80 - -# Let supervisord start nginx & php-fpm -CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] - -# Configure a healthcheck to validate that everything is up&running -HEALTHCHECK --timeout=10s CMD curl --silent --fail http://127.0.0.1:8080/fpm-ping || exit 1 +# Accepted values: 8.3 - 8.2 +ARG PHP_VERSION=8.3 + +ARG COMPOSER_VERSION=latest + +ARG NODE_VERSION=20-alpine + +########################################### + +FROM composer:${COMPOSER_VERSION} AS vendor + +FROM php:${PHP_VERSION}-cli-alpine + +LABEL maintainer="SMortexa " +LABEL org.opencontainers.image.title="Laravel Octane Dockerfile" +LABEL org.opencontainers.image.description="Production-ready Dockerfile for Laravel Octane" +LABEL org.opencontainers.image.source=https://github.com/exaco/laravel-octane-dockerfile +LABEL org.opencontainers.image.licenses=MIT + +ARG WWWUSER=1000 +ARG WWWGROUP=1000 +ARG TZ=UTC + +ENV TERM=xterm-color \ + WITH_HORIZON=false \ + WITH_SCHEDULER=false \ + OCTANE_SERVER=swoole \ + USER=octane \ + ROOT=/var/www/html \ + COMPOSER_FUND=0 \ + COMPOSER_MAX_PARALLEL_HTTP=24 + +WORKDIR ${ROOT} + +SHELL ["/bin/sh", "-eou", "pipefail", "-c"] + +RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime \ + && echo ${TZ} > /etc/timezone + +ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ + +RUN apk update; \ + apk upgrade; \ + apk add --no-cache \ + curl \ + wget \ + nano \ + ncdu \ + procps \ + ca-certificates \ + supervisor \ + libsodium-dev \ + # Install PHP extensions + && install-php-extensions \ + bz2 \ + pcntl \ + mbstring \ + bcmath \ + sockets \ + pgsql \ + pdo_pgsql \ + opcache \ + exif \ + pdo_mysql \ + zip \ + intl \ + gd \ + redis \ + rdkafka \ + memcached \ + igbinary \ + ldap \ + swoole \ + && docker-php-source delete \ + && rm -rf /var/cache/apk/* /tmp/* /var/tmp/* + +RUN arch="$(apk --print-arch)" \ + && case "$arch" in \ + armhf) _cronic_fname='supercronic-linux-arm' ;; \ + aarch64) _cronic_fname='supercronic-linux-arm64' ;; \ + x86_64) _cronic_fname='supercronic-linux-amd64' ;; \ + x86) _cronic_fname='supercronic-linux-386' ;; \ + *) echo >&2 "error: unsupported architecture: $arch"; exit 1 ;; \ + esac \ + && wget -q "https://github.com/aptible/supercronic/releases/download/v0.2.29/${_cronic_fname}" \ + -O /usr/bin/supercronic \ + && chmod +x /usr/bin/supercronic \ + && mkdir -p /etc/supercronic \ + && echo "*/1 * * * * php ${ROOT}/artisan schedule:run --no-interaction" > /etc/supercronic/laravel + +RUN addgroup -g ${WWWGROUP} ${USER} \ + && adduser -D -h ${ROOT} -G ${USER} -u ${WWWUSER} -s /bin/sh ${USER} + +RUN mkdir -p /var/log/supervisor /var/run/supervisor \ + && chown -R ${USER}:${USER} ${ROOT} /var/log /var/run \ + && chmod -R a+rw ${ROOT} /var/log /var/run + +RUN cp ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini + +USER ${USER} + +COPY --chown=${USER}:${USER} --from=vendor /usr/bin/composer /usr/bin/composer +COPY --chown=${USER}:${USER} composer.json composer.lock ./ + +RUN composer install \ + --no-dev \ + --no-interaction \ + --no-autoloader \ + --no-ansi \ + --no-scripts \ + --audit + +COPY --chown=${USER}:${USER} . . + +RUN mkdir -p \ + storage/framework/sessions \ + storage/framework/views \ + storage/framework/cache \ + storage/framework/testing \ + storage/logs \ + bootstrap/cache && chmod -R a+rw storage + +COPY --chown=${USER}:${USER} .docker/supervisord.conf /etc/supervisor/ +COPY --chown=${USER}:${USER} .docker/octane/Swoole/supervisord.swoole.conf /etc/supervisor/conf.d/ +COPY --chown=${USER}:${USER} .docker/supervisord.*.conf /etc/supervisor/conf.d/ +COPY --chown=${USER}:${USER} .docker/php.ini ${PHP_INI_DIR}/conf.d/99-octane.ini +COPY --chown=${USER}:${USER} .docker/start-container /usr/local/bin/start-container + +RUN composer install \ + --classmap-authoritative \ + --no-interaction \ + --no-ansi \ + --no-dev \ + && composer clear-cache + +COPY .env.example ./.env + +RUN php artisan key:generate + +RUN chmod +x /usr/local/bin/start-container + +RUN cat .docker/utilities.sh >> ~/.bashrc + +EXPOSE 8000 + +ENTRYPOINT ["start-container"] + +HEALTHCHECK --start-period=5s --interval=2s --timeout=5s --retries=8 CMD php artisan octane:status || exit 1