Add Docker Compose setup for local development

PHP 8.3/Apache + MariaDB 11.4 with the repo bind-mounted as web root.
Apache denies dotfiles (.env, .git), the docker files and /install-dev
(installation runs via CLI as www-data, see docker-compose.yml).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
DanielS
2026-11-11 00:20:03 +01:00
parent ec79686a7d
commit e32cd8f6ed
6 changed files with 93 additions and 1 deletions

10
.env.example Normal file
View File

@@ -0,0 +1,10 @@
# Copy to .env for local development. Local test values only, never use in production.
APP_PORT=8080
DB_NAME=qloapps
DB_USER=qloapps
DB_PASSWORD=qlo_local_dev
DB_ROOT_PASSWORD=qlo_local_root
# Local admin created by the CLI installer (test values only)
ADMIN_EMAIL=admin@hotel.test
ADMIN_PASSWORD=change-me

2
.gitignore vendored
View File

@@ -256,3 +256,5 @@ admin/themes/default/css/screen.css
**sitemap.xml
robots.txt
# Local docker environment
.env

42
docker-compose.yml Normal file
View File

@@ -0,0 +1,42 @@
# Local development setup for QloApps.
# Start: docker compose up -d --build
# Shop: http://localhost:8080
# Admin: http://localhost:8080/admin-dev (login: ADMIN_EMAIL / ADMIN_PASSWORD from .env)
# Values come from .env (copy .env.example to .env).
#
# Install (once, as www-data so file permissions stay correct; the web installer is blocked):
# docker compose exec -u www-data app php install-dev/index_cli.php --language=de --country=de \
# --timezone=Europe/Berlin --domain=localhost:8080 --db_server=db --db_user=qloapps \
# --db_password=<DB_PASSWORD> --db_name=qloapps --email=<ADMIN_EMAIL> --password=<ADMIN_PASSWORD> \
# --newsletter=0
services:
app:
build: ./docker
ports:
- "${APP_PORT:-8080}:80"
volumes:
- ./:/var/www/html
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: mariadb:11.4
environment:
MARIADB_DATABASE: ${DB_NAME:-qloapps}
MARIADB_USER: ${DB_USER:-qloapps}
MARIADB_PASSWORD: ${DB_PASSWORD:?set DB_PASSWORD in .env}
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:?set DB_ROOT_PASSWORD in .env}
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 5s
timeout: 5s
retries: 20
restart: unless-stopped
volumes:
db_data:

19
docker/Dockerfile Normal file
View File

@@ -0,0 +1,19 @@
FROM php:8.3-apache
# PHP extensions required by QloApps (see README "Requirements")
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libfreetype6-dev libjpeg62-turbo-dev libpng-dev libwebp-dev \
libzip-dev libxml2-dev libicu-dev unzip \
&& docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp \
&& docker-php-ext-install -j"$(nproc)" pdo_mysql mysqli gd zip soap intl opcache \
&& a2enmod rewrite headers \
&& rm -rf /var/lib/apt/lists/*
COPY php.ini /usr/local/etc/php/conf.d/qloapps.ini
COPY apache-hardening.conf /etc/apache2/conf-enabled/zz-hardening.conf
# QloApps' .htaccess files need AllowOverride
RUN sed -ri 's!AllowOverride None!AllowOverride All!g' /etc/apache2/apache2.conf
WORKDIR /var/www/html

View File

@@ -0,0 +1,7 @@
# The repo is bind-mounted as web root: never serve dotfiles (.env, .git, ...) or docker files.
RedirectMatch 404 "/\.(?!well-known/)"
RedirectMatch 404 "^/(docker/|docker-compose\.yml)"
# Installation is done via CLI (see docker-compose.yml); a web re-install would wipe the database.
RedirectMatch 404 "^/install-dev"
ServerTokens Prod
ServerSignature Off

12
docker/php.ini Normal file
View File

@@ -0,0 +1,12 @@
memory_limit = 256M
upload_max_filesize = 16M
post_max_size = 20M
max_execution_time = 500
max_input_vars = 5000
allow_url_fopen = On
date.timezone = Europe/Berlin
expose_php = Off
; Development: re-read changed PHP files immediately
opcache.validate_timestamps = 1
opcache.revalidate_freq = 0