From 0cc01331f2663d9f37001add6fc3d3fbe2ced27e Mon Sep 17 00:00:00 2001 From: PyRowMan Date: Tue, 17 Dec 2024 21:29:10 +0100 Subject: [PATCH] Add Docker setup with Dockerfile, docker-compose, and entrypoint This commit introduces a Dockerized environment for the application, including a Dockerfile, docker-compose.yml, and a custom entrypoint script. The setup supports multiple services like MariaDB, Redis, and Elasticsearch, with health checks and environment configurations. It also automates dependency installation, environment setup, and Laravel-specific tasks like caching and installation processes. --- .dockerignore | 3 +- Dockerfile | 73 +++++++++++++++++ docker-compose.yml | 188 +++++++++++++++++++++++++++++++++++++++++++ docker-entrypoint.sh | 60 ++++++++++++++ 4 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 docker-entrypoint.sh diff --git a/.dockerignore b/.dockerignore index 3b429b802..d43e4e08b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,5 +2,4 @@ vendor/ docker/mariadb-data docker/redis-data docker/manticore-data -storage -resources +.env diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..2780b8cbc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,73 @@ + +FROM composer:latest AS composer-base +#FROM php:8.3-fpm AS php-base +FROM dunglas/frankenphp:1-php8.3 +LABEL maintainer="Fossil01" +ENV SERVER_NAME=:80 +ARG MYSQL_CLIENT="mariadb-client" +ARG SEVENZIP_VERSION=2407 + +WORKDIR /app + + +COPY --from=node:21 /usr/local/ /usr/local/ +COPY --from=composer-base --link /usr/bin/composer /usr/bin/composer + +RUN apt update \ + && apt install -y --no-install-recommends \ + unrar-free 7zip lame libcap2-bin python3 \ + curl zip unzip git nano bash-completion sudo wget tmux time fonts-powerline \ + gnupg sqlite3 libpng-dev dnsutils jq htop iputils-ping net-tools ffmpeg \ + jpegoptim webp optipng pngquant libavif-bin watch iproute2 nmon \ + libonig-dev libxml2-dev libicu-dev libjpeg-dev libfreetype6-dev libxslt-dev $MYSQL_CLIENT libcurl4-openssl-dev \ + && wget https://mediaarea.net/repo/deb/repo-mediaarea_1.0-24_all.deb \ + && dpkg -i repo-mediaarea_1.0-24_all.deb \ + && apt update \ + && apt install -y libmediainfo0v5 mediainfo libzen0v5 \ + && docker-php-ext-install \ + bcmath \ + exif \ + gd \ + intl \ + pdo_mysql \ + sockets \ + pcntl \ + && pecl install redis \ + && docker-php-ext-enable redis \ + && apt clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +# Determine ARCH and download and extract the appropriate version of 7-Zip +RUN ARCH="$(dpkg --print-architecture)" && \ + if [ "$ARCH" = "amd64" ]; then \ + SZIP_URL="https://www.7-zip.org/a/7z$SEVENZIP_VERSION-linux-x64.tar.xz"; \ + fi && \ + if [ "$ARCH" = "arm64" ]; then \ + SZIP_URL="https://www.7-zip.org/a/7z$SEVENZIP_VERSION-linux-arm64.tar.xz"; \ + fi && \ + wget "$SZIP_URL" -O /tmp/7z.tar.xz && \ + tar -xf /tmp/7z.tar.xz -C /tmp/ && \ + mv /tmp/7zz /usr/bin/7zz && \ + rm -f /tmp/7z.tar.xz && rm -f /tmp/7zzs + +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + +RUN npm install -g bun pnpm + +COPY --chmod=755 ./docker-entrypoint.sh /usr/local/bin/docker-entrypoint +RUN chmod +x /usr/local/bin/docker-entrypoint + +COPY . /app + +RUN composer install + +RUN chmod -R 755 /app/vendor/ +RUN chmod -R 777 /app/storage/ +RUN chmod -R 777 /app/resources/ +RUN chmod -R 777 /app/public/ + +EXPOSE 80 + +CMD ["--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"] +ENTRYPOINT ["docker-entrypoint"] + + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..d1a065b28 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,188 @@ +services: + webapp: + build: + context: . + dockerfile: Dockerfile + image: sail-8.3/app + extra_hosts: + - 'host.docker.internal:host-gateway' + ports: + - '${APP_PORT:-80}:80' + environment: + TZ: ${APP_TIMEZONE} + COMPOSER_AUTH: ${COMPOSER_AUTH} + XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}' + XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}' + IGNITION_LOCAL_SITES_PATH: '${PWD}' + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:80" ] + interval: 10s + timeout: 5s + retries: 5 + env_file: + - .env + volumes: + - 'install:/app/_install' + - 'storage:/app/storage' +# - 'resources:/var/www/html/resources' + networks: + - sail + depends_on: + - mariadb + - redis + - mailpit + - elasticsearch + worker: + command: > + sh -c "php artisan tmux-ui:start & php artisan horizon" + image: sail-8.3/app + extra_hosts: + - 'host.docker.internal:host-gateway' + tty: true + environment: + TZ: ${APP_TIMEZONE} + COMPOSER_AUTH: ${COMPOSER_AUTH} + XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}' + XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}' + IGNITION_LOCAL_SITES_PATH: '${PWD}' + env_file: + - .env + volumes: + - 'install:/app/_install' + - 'storage:/app/storage' + networks: + - sail + depends_on: + webapp: + condition: service_healthy + scheduler: + image: sail-8.3/app + extra_hosts: + - 'host.docker.internal:host-gateway' + tty: true + env_file: + - .env + environment: + TZ: ${APP_TIMEZONE} + COMPOSER_AUTH: ${COMPOSER_AUTH} + XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}' + XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}' + IGNITION_LOCAL_SITES_PATH: '${PWD}' + volumes: + - 'install:/app/_install' + - 'storage:/app/storage' + networks: + - sail + depends_on: + webapp: + condition: service_healthy + command: > + sh -c "while [ true ]; do php artisan schedule:run; sleep 60; done" + mariadb: + image: 'mariadb:11' + ports: + - '${FORWARD_DB_PORT:-3306}:3306' + environment: + TZ: ${APP_TIMEZONE} + MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}' + MYSQL_ROOT_HOST: '%' + MYSQL_DATABASE: '${DB_DATABASE}' + MYSQL_USER: '${DB_USERNAME}' + MYSQL_PASSWORD: '${DB_PASSWORD}' + MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' + command: + --max_allowed_packet=128M + --group_concat_max_len=16384 + --max_connections=200 + volumes: + - 'sail-mariadb:/var/lib/mysql' + - './vendor/laravel/sail/database/mariadb/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh' + networks: + - sail + healthcheck: + test: + - CMD + - mysqladmin + - ping + - '-p${DB_PASSWORD}' + retries: 3 + timeout: 5s + redis: + image: 'redis:alpine' + ports: + - '${FORWARD_REDIS_PORT:-6379}:6379' + environment: + TZ: ${APP_TIMEZONE} + volumes: + - 'sail-redis:/data' + networks: + - sail + healthcheck: + test: + - CMD + - redis-cli + - ping + retries: 3 + timeout: 5s + mailpit: + image: 'axllent/mailpit:latest' + ports: + - '${FORWARD_MAILPIT_PORT:-1025}:1025' + - '${FORWARD_MAILPIT_DASHBOARD_PORT:-8025}:8025' + networks: + - sail +# manticore: +# image: manticoresearch/manticore +# environment: +# TZ: ${APP_TIMEZONE} +# EXTRA: 1 # Activates extra features +# restart: always +# ports: +# - 9306:9306 +# - 9308:9308 +# ulimits: +# nproc: 65535 +# nofile: +# soft: 65535 +# hard: 65535 +# memlock: +# soft: -1 +# hard: -1 +# volumes: +# - 'sail-manticore:/var/lib/manticore' +# - ./misc/manticoresearch/manticore.conf:/etc/manticoresearch/manticore.conf # uncomment if you use a custom config +# networks: +# - sail + elasticsearch: + image: docker.elastic.co/elasticsearch/elasticsearch:8.17.0 + environment: + - TZ=${APP_TIMEZONE} + - discovery.type=single-node + - xpack.security.enabled=false + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + ports: + - 9200:9200 + - 9300:9300 + volumes: + - sail-elasticsearch:/usr/share/elasticsearch/data + networks: + - sail + deploy: + resources: + limits: + memory: 1g +networks: + sail: + driver: bridge +volumes: + sail-mariadb: + driver: local + sail-redis: + driver: local + sail-manticore: + driver: local + sail-elasticsearch: + driver: local + storage: + resources: + install: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 000000000..545546c73 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,60 @@ +#!/bin/sh +set -e +if [ "$1" != 'php' ] && [ "$1" != 'sh' ]; then + # Install dependencies if not already installed + if [ ! -d 'vendor/' ]; then + echo "Installing dependencies via Composer..." + composer install --prefer-dist --no-progress --no-interaction + fi + + # Create .env file if it doesn't exist + if [ ! -f .env ]; then + echo "Creating .env file from environment variables..." + printenv >> .env + fi + + # Check and wait for the database to be ready + if grep -q ^DB_HOST= .env; then + echo "Waiting for the database to be ready..." + ATTEMPTS_LEFT_TO_REACH_DATABASE=60 + until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(php artisan db:show 2>&1); do + if [ $? -ne 0 ]; then + # Stop attempting in case of an error + ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1)) + echo "Database not ready yet. Attempts left: $ATTEMPTS_LEFT_TO_REACH_DATABASE." + sleep 1 + else + break + fi + done + + if [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ]; then + echo "Failed to connect to the database:" + echo "$DATABASE_ERROR" + exit 1 + else + echo "Database is now ready." + fi + fi + + echo "Clearing application cache..." + php artisan cache:clear + php artisan config:clear + php artisan route:clear + php artisan view:clear + + echo "Caching configuration and routes..." + php artisan config:cache + php artisan route:cache + + # Run Laravel-specific post-installation commands + echo "NNTmux installation..." + php artisan nntmux:install --yes + # Set permissions for storage and bootstrap/cache directories + echo "Setting permissions on storage and bootstrap/cache directories..." + chmod -R 775 storage bootstrap/cache + chown -R www-data:www-data storage bootstrap/cache +fi + +# Run the PHP entry point with arguments +exec docker-php-entrypoint "$@"