diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..01b5668
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,4 @@
+export COMPOSE_PROJECT_NAME=docker-example-drupal
+export COMPOSE_PROFILES=web,php,database
+
+export DOCKER_WEB_VOLUME=.:/app
diff --git a/.gitignore b/.gitignore
index 94e2ede..2df2c1c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
/.editorconfig
+/.env
/.gitattributes
/vendor/
/web/.csslintrc
@@ -13,6 +14,7 @@
/web/example.gitignore
/web/index.php
/web/modules/README.txt
+/web/modules/contrib/
/web/profiles/README.txt
/web/robots.txt
/web/sites/*/files/
@@ -27,5 +29,6 @@
/web/sites/example.sites.php
/web/sites/simpletest/
/web/themes/README.txt
+/web/themes/contrib/
/web/update.php
/web/web.config
diff --git a/Dockerfile b/Dockerfile
index 98c7b78..fb10f5d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,52 +1,50 @@
-ARG PHP_VERSION=8.1
+FROM php:8.1-fpm-bullseye AS base
-FROM php:${PHP_VERSION}-fpm-bullseye AS base
+COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
+RUN which composer && composer -V
-###
+WORKDIR /app
+
+ENV PATH="${PATH}:/app/vendor/bin"
+
+COPY composer.* ./
+
+################################################################################
FROM base AS build
-ENV PATH=${PATH}:/var/www/html/vendor/bin
+RUN apt-get update -yqq \
+ && apt-get install -yqq --no-install-recommends \
+ git libpng-dev libzip-dev mariadb-client unzip
-COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
+RUN docker-php-ext-install gd pdo_mysql zip
-WORKDIR /var/www/html
-RUN useradd --create-home app \
- && chown app:app -R /var/www/html \
- && apt-get update -yqq \
- && apt-get install -yqq \
- git \
- libpng-dev \
- mariadb-client \
- unzip \
- && rm -fr /var/lib/apt/lists/* \
- && pecl install xdebug \
- && docker-php-ext-install \
- gd \
- opcache \
- pdo_mysql \
- && docker-php-ext-enable \
- xdebug
+RUN composer validate
+RUN composer install
COPY tools/docker/images/php/root /
-COPY --chown=app:app composer.* ./
+ENTRYPOINT ["/usr/local/bin/docker-entrypoint-php"]
+CMD ["php-fpm"]
-USER app
-RUN composer install --no-dev --prefer-dist --optimize-autoloader
+################################################################################
-COPY --chown=app:app . .
+FROM base AS test
-###
+COPY . .
-FROM build AS test
+RUN parallel-lint src --no-progress \
+ && phpcs -vv \
+ && phpstan \
+ && phpunit --testdox
-# RUN composer install \
-# && phpunit
+################################################################################
-###
+FROM nginx:1 as web
-FROM build AS production
+EXPOSE 8080
-RUN composer install --no-dev --prefer-dist --optimize-autoloader
+WORKDIR /app
+
+COPY tools/docker/images/web/root /
diff --git a/build.yaml b/build.yaml
new file mode 100644
index 0000000..51b80d6
--- /dev/null
+++ b/build.yaml
@@ -0,0 +1,52 @@
+name: docker-example-drupal
+language: php
+type: drupal-project
+
+web:
+ type: nginx
+
+database:
+ type: mariadb
+ version: 10
+
+php:
+ version: 8.1-fpm-bullseye
+ phpcs:
+ standard: Drupal,DrupalPractice
+ phpstan:
+ level: max
+
+docker-compose:
+ services:
+ database: ~
+ php:
+ build:
+ target: build
+
+dockerfile:
+ stages:
+ build:
+ extends: base
+ packages:
+ - git
+ - libpng-dev
+ - libzip-dev
+ - mariadb-client
+ - unzip
+ extensions:
+ install:
+ - gd
+ - pdo_mysql
+ - zip
+ commands:
+ - composer validate
+ - composer install
+
+ test:
+ extends: base
+ commands:
+ - parallel-lint src --no-progress
+ - phpcs -vv
+ - phpstan
+ - phpunit --testdox
+
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 960ae7e..4c51799 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -1,30 +1,70 @@
+x-app: &default-app
+ volumes:
+ - "${DOCKER_WEB_VOLUME:-./web:/app/web}"
+ env_file:
+ - .env
+ restart: "${DOCKER_RESTART_POLICY:-unless-stopped}"
+ networks:
+ - default
+ deploy:
+ resources:
+ limits:
+ cpus: "${DOCKER_MYSQL_CPUS:-0}"
+ memory: "${DOCKER_MYSQL_MEMORY:-0}"
+ labels:
+ - "traefik.enabled=false"
+ tty: true
+
services:
web:
- image: caddy
- volumes:
- - ./Caddyfile:/etc/caddy/Caddyfile
- - .:/var/www/html
- ports:
- - "${DOCKER_WEB_PORT:-127.0.0.1:80}:80"
- environment:
- SERVER_NAME: "${SERVER_NAME:-:80}"
-
- php-fpm:
- image: "ghcr.io/opdavies/docker-drupal-example-php-fpm:${DOCKER_TAG:-latest}"
+ <<: *default-app
build:
context: .
- volumes:
- - .:/var/www/html
+ target: web
+ depends_on:
+ - php
+ networks:
+ - default
+ - web
+ labels:
+ - "traefik.docker.network=traefik_proxy"
+ - "traefik.http.routers.${COMPOSE_PROJECT_NAME}.rule=Host(
+ `${COMPOSE_PROJECT_NAME}.localhost`,
+ )"
+ profiles: [web]
- mysql:
+ php:
+ <<: *default-app
+ build:
+ context: .
+ target: build
+ depends_on:
+ - database
+ profiles: [php]
+
+ database:
image: mariadb:10
+ deploy:
+ resources:
+ limits:
+ cpus: "${DOCKER_MYSQL_CPUS:-0}"
+ memory: "${DOCKER_MYSQL_MEMORY:-0}"
volumes:
- db-data:/var/lib/mysql
+ env_file:
+ - .env
+ labels:
+ - "traefik.enabled=false"
environment:
+ MYSQL_RANDOM_ROOT_PASSWORD: true
MYSQL_DATABASE: drupal
- MYSQL_RANDOM_ROOT_PASSWORD: 'true'
MYSQL_PASSWORD: drupal
MYSQL_USER: drupal
+ profiles: [database]
volumes:
db-data: {}
+
+networks:
+ web:
+ name: traefik_proxy
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
new file mode 100644
index 0000000..4fcef96
--- /dev/null
+++ b/phpcs.xml.dist
@@ -0,0 +1,7 @@
+
+
+ PHPCS configuration file for docker-example-drupal.
+ src
+
+
+
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 0000000..76bd437
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,5 @@
+parameters:
+ level: max
+ paths:
+ - src
+
\ No newline at end of file
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..76faa41
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,20 @@
+
+
+
+
+ tests
+
+
+
diff --git a/run b/run
index 1f2c7f8..5650997 100755
--- a/run
+++ b/run
@@ -3,7 +3,7 @@
set -e
function cmd {
- _dc php-fpm "${@}"
+ _dc php "${@}"
}
function composer {
@@ -23,7 +23,7 @@ function help {
}
function _dc {
- docker-compose run --rm "${@}"
+ docker compose run --rm "${@}"
}
eval "${@:-help}"
diff --git a/tools/docker/images/nginx/root/etc/nginx/conf.d/default.conf b/tools/docker/images/nginx/root/etc/nginx/conf.d/default.conf
new file mode 100644
index 0000000..b032e23
--- /dev/null
+++ b/tools/docker/images/nginx/root/etc/nginx/conf.d/default.conf
@@ -0,0 +1,20 @@
+server {
+ server_name _;
+
+ root /app/web;
+
+ location / {
+ try_files $uri /index.php?$query_string;
+ }
+
+ location ~ \.php(/|$) {
+ fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
+ try_files $fastcgi_script_name =404;
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param PATH_INFO $fastcgi_path_info;
+ fastcgi_param QUERY_STRING $query_string;
+ fastcgi_intercept_errors on;
+ fastcgi_pass php:9000;
+ }
+}
diff --git a/tools/docker/images/php/root/usr/local/bin/docker-entrypoint-php b/tools/docker/images/php/root/usr/local/bin/docker-entrypoint-php
new file mode 100755
index 0000000..564778b
--- /dev/null
+++ b/tools/docker/images/php/root/usr/local/bin/docker-entrypoint-php
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+[[ -f composer.json && ! -d vendor ]] && composer install
+
+eval "$@"
diff --git a/tools/docker/images/web/root/etc/nginx/conf.d/default.conf b/tools/docker/images/web/root/etc/nginx/conf.d/default.conf
new file mode 100644
index 0000000..f941f8c
--- /dev/null
+++ b/tools/docker/images/web/root/etc/nginx/conf.d/default.conf
@@ -0,0 +1,20 @@
+server {
+ server_name _;
+
+ root /app/docroot;
+
+ location / {
+ try_files $uri /index.php?$query_string;
+ }
+
+ location ~ \.php(/|$) {
+ fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
+ try_files $fastcgi_script_name =404;
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param PATH_INFO $fastcgi_path_info;
+ fastcgi_param QUERY_STRING $query_string;
+ fastcgi_intercept_errors on;
+ fastcgi_pass php:9000;
+ }
+}