feat(docker): add Dockerfiles + docker-compose.yml with healthchecks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
Boban Blaskovic 2026-05-22 00:19:01 +02:00
commit 57d14dc152
4 changed files with 195 additions and 0 deletions

121
docker-compose.yml Normal file
View File

@ -0,0 +1,121 @@
services:
app:
build:
context: .
dockerfile: docker/app/Dockerfile
volumes:
- .:/var/www/html
- app_storage:/var/www/html/storage/app
- app_public:/var/www/html/storage/app/public
env_file: .env
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks: [lernschiff_net]
nginx:
build:
context: ./docker/nginx
dockerfile: Dockerfile
ports:
- "127.0.0.1:8080:80"
volumes:
- .:/var/www/html:ro
- app_public:/var/www/html/storage/app/public:ro
depends_on: [app]
networks: [lernschiff_net]
queue:
build:
context: .
dockerfile: docker/app/Dockerfile
command: php artisan queue:work --sleep=3 --tries=3
volumes:
- .:/var/www/html
- app_storage:/var/www/html/storage/app
- app_public:/var/www/html/storage/app/public
env_file: .env
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks: [lernschiff_net]
scheduler:
build:
context: .
dockerfile: docker/app/Dockerfile
command: sh -c "while true; do php artisan schedule:run --verbose --no-interaction; sleep 60; done"
volumes:
- .:/var/www/html
- app_storage:/var/www/html/storage/app
- app_public:/var/www/html/storage/app/public
env_file: .env
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks: [lernschiff_net]
reverb:
build:
context: .
dockerfile: docker/app/Dockerfile
command: php artisan reverb:start --host=0.0.0.0 --port=8081
ports:
- "127.0.0.1:8081:8081"
volumes:
- .:/var/www/html
- app_storage:/var/www/html/storage/app
- app_public:/var/www/html/storage/app/public
env_file: .env
depends_on: [redis]
networks: [lernschiff_net]
mysql:
image: mysql:8
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_USER: ${DB_USERNAME}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "${DB_USERNAME}", "-p${DB_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 10
networks: [lernschiff_net]
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
networks: [lernschiff_net]
mailpit:
image: axllent/mailpit
ports:
- "127.0.0.1:8025:8025"
- "127.0.0.1:1025:1025"
networks: [lernschiff_net]
networks:
lernschiff_net:
driver: bridge
volumes:
mysql_data:
redis_data:
app_storage:
app_public:

17
docker/app/Dockerfile Normal file
View File

@ -0,0 +1,17 @@
FROM php:8.4-fpm
RUN apt-get update && apt-get install -y \
git curl zip unzip libpng-dev libonig-dev libxml2-dev libzip-dev libicu-dev \
&& docker-php-ext-install pdo_mysql gd zip pcntl intl bcmath exif \
&& pecl install redis && docker-php-ext-enable redis \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y nodejs
WORKDIR /var/www/html
COPY . .
RUN composer install --no-dev --optimize-autoloader \
&& chown -R www-data:www-data storage bootstrap/cache

2
docker/nginx/Dockerfile Normal file
View File

@ -0,0 +1,2 @@
FROM nginx:stable-alpine
COPY default.conf /etc/nginx/conf.d/default.conf

55
docker/nginx/default.conf Normal file
View File

@ -0,0 +1,55 @@
# app.dev.lernschiff.com — Livewire SPA + Vite assets
server {
listen 80;
server_name app.dev.lernschiff.com;
root /var/www/html/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location /storage {
alias /var/www/html/storage/app/public;
}
}
# api.dev.lernschiff.com — Laravel JSON API + CORS (Single-Source-of-Truth)
server {
listen 80;
server_name api.dev.lernschiff.com;
root /var/www/html/public;
index index.php;
# OPTIONS Preflight fast-path
location / {
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin "https://app.dev.lernschiff.com" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-XSRF-TOKEN, X-Requested-With" always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Max-Age 86400 always;
add_header Content-Length 0;
return 204;
}
add_header Access-Control-Allow-Origin "https://app.dev.lernschiff.com" always;
add_header Access-Control-Allow-Credentials "true" always;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}