diff --git a/.editorconfig b/.editorconfig index 876ec2a..f7a762d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,3 +14,6 @@ trim_trailing_whitespace = false [*.{yml,yaml}] indent_size = 2 + +[Caddyfile] +indent_style = tab diff --git a/.env.example b/.env.example index d254c6a..006e3b2 100644 --- a/.env.example +++ b/.env.example @@ -1,14 +1,4 @@ -# these variables should be declared in the project root directory -APP_NAME="docker-base" -USER="jordy" -PUID=1000 -PGID=1000 - -PHP_XDEBUG_MODE="develop,debug" -PHP_XDEBUG_CONFIG="client_host=host.docker.internal output_dir=/tmp/xdebug profiler_output_name=cachegrind.out.%R.%u" - -DB_PASSWORD="secret" -DB_USERNAME="default" -DB_DATABASE=${APP_NAME} +# these variables should be declared in your application root .env +APP_NAME="docker-php" CLOUDFLARE_DNS_API_TOKEN="SECRETAPITOKENGOESHERE" diff --git a/README.md b/README.md index e7b6b46..51b2000 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,26 @@ # docker-php -Docker PHP is a collection of services and containers intended to be pulled into a project as a submodule or subtree. It contains all the services necessary to serve a modern Laravel application for development purposes. It's very similar to what Laravel Sail provides but is further configured to suit my personal needs and preferences. +Docker PHP is a collection of services and containers intended to be pulled into a project as a submodule or subtree. It contains all the services necessary to serve a modern Laravel app for development purposes. It's similar to what Laravel Sail provides but is further configured to suit my personal needs and preferences. -Additionally, this repository contains a production ready FrankenPHP container that is preconfigured to automatically request SSL certificates using a Cloudflare DNS challenge when built for production. See the `frankenphp/` subdirectory. +Additionally, this repository contains a production ready FrankenPHP container that's pre-configured to automatically request SSL certificates using a Cloudflare DNS challenge when built for production. See the `frankenphp/` subdirectory. -## Configuration +## How to use -1. Run `git submodule add https://github.com/99linesofcode/docker-php.git docker` from your application root; -1. Copy the `docker-compose.yaml.dist` to the application root; -1. Configure the environment variables defined in the `.env.example` file in your `.env` in the application root; +1. Change to your project root directory (for example: `cd ./laravel-starter`); +1. `git submodule add https://github.com/99linesofcode/docker-php.git docker`; +1. `cp docker/docker-compose.yaml.dist ./docker-compose.yaml`; +1. Configure the environment variables defined in `docker/.env.example` file in your `./.env`; 1. Run `docker compose up -d` to spin up your development environment. Almost all the relevant configuration is done in/from the `docker-compose.yaml` file. Optional services are disabled by default. You can enable these by uncommenting their respective service blocks. ## Production -There are several ways to run Docker PHP in production. Using `docker compose -d` similarly to how you run it in development or by manually building and packaging the application up into a docker image and pushing it to and pulling it from a container registry. +There are several ways to run Docker PHP in production. Using `docker compose -d` similarly to how you run it in development or by manually building and packaging the app up into a docker image and pushing it to and pulling it from a container registry. -The FrankenPHP container uses the multi-stage build process and can be further optimized for production. If you intend to use `docker compose` you will have to change the `services.frankenphp.build.target` to `production`. +The FrankenPHP container uses the multi-stage build process and can be further optimized for production. If you intend to use `docker compose` in production you will have to change the `services.frankenphp.build.target` to `production`. -If you choose to package your application and serve it differently, make sure to pass the `--target production` flag to your `docker build` command like so: `docker build --target production -t frankenphp:production -f ./frankenphp/Dockerfile .`. +If you choose to package your app and serve it differently, make sure to pass the `--target production` flag to your `docker build` command like so: `docker build --target production -t frankenphp:production -f ./frankenphp/Dockerfile .`. ## Contributing diff --git a/docker-compose.yaml b/docker-compose.yaml index cfdba83..cf48612 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -7,7 +7,7 @@ services: mailpit: container_name: ${APP_NAME}-mailpit healthcheck: - test: ["CMD", "curl", "-Ss", "http://localhost:8025/livez"] + test: ['CMD', 'curl', '-Ss', 'http://localhost:8025/livez'] retries: 3 timeout: 5s image: axllent/mailpit:latest @@ -36,10 +36,11 @@ services: - XDEBUG_MODE=${PHP_XDEBUG_MODE:-off} - XDEBUG_CONFIG=${PHP_XDEBUG_CONFIG:-client_host=host.docker.internal output_dir=/tmp/xdebug profiler_output_name=cachegrind.out.%R.%u} extra_hosts: - - "host.docker.internal:host-gateway" # for accessing the host from inside the container + - 'host.docker.internal:host-gateway' # for accessing the host from inside the container ports: - ${FORWARD_PHP_HTTP_PORT:-80}:80 - ${FORWARD_PHP_HTTPS_PORT:-443}:443 + - ${FORWARD_PHP_HTTPS_PORT:-443}:443/udp restart: unless-stopped working_dir: /app diff --git a/docker-compose.yaml.dist b/docker-compose.yaml.dist index fcff6b9..aecc532 100644 --- a/docker-compose.yaml.dist +++ b/docker-compose.yaml.dist @@ -21,6 +21,7 @@ services: # service: meilisearch # volumes: # - meilisearch:/meili_data + mysql: extends: # see: https://docs.docker.com/compose/how-tos/multiple-compose-files/extends/ file: ./docker/docker-compose.yaml @@ -42,13 +43,13 @@ services: - XDEBUG_MODE=${PHP_XDEBUG_MODE:-off} - XDEBUG_CONFIG=${PHP_XDEBUG_CONFIG:-client_host=host.docker.internal output_dir=/tmp/xdebug profiler_output_name=cachegrind.out.%R.%u} depends_on: - # - meilisearch - - mysql - - redis - # - soketi + # - meilisearch + # - mysql + # - redis + # - soketi volumes: - .:/app - # - $HOME/Development/profiling/${APP_NAME}:/tmp/xdebug # mount xdebug and cachegrind output for profiling analysis on host machine + # - $HOME/Development/profiling/${APP_NAME}:/tmp/xdebug # mount xdebug and cachegrind output for profiling analysis on host machine phpmyadmin: extends: # see: https://docs.docker.com/compose/how-tos/multiple-compose-files/extends/ @@ -89,5 +90,5 @@ volumes: networks: default: - name: "${APP_NAME}-net" + name: '${APP_NAME}-net' driver: bridge diff --git a/frankenphp/Caddyfile b/frankenphp/Caddyfile index 9d95689..f017c25 100644 --- a/frankenphp/Caddyfile +++ b/frankenphp/Caddyfile @@ -1,5 +1,5 @@ { - acme_dns cloudflare {$CLOUDFLARE_DNS_API_TOKEN} + acme_dns cloudflare {$CLOUDFLARE_DNS_API_TOKEN} {$CADDY_GLOBAL_OPTIONS} diff --git a/frankenphp/Dockerfile b/frankenphp/Dockerfile index 37b5051..e1059fc 100644 --- a/frankenphp/Dockerfile +++ b/frankenphp/Dockerfile @@ -1,20 +1,40 @@ # syntax=docker/dockerfile:1 -ARG PHP_VERSION="8.4" -ARG BASE_IMAGE="dunglas/frankenphp:php${PHP_VERSION}-alpine" +ARG VERSION="8.5" +ARG BASE_IMAGE="dunglas/frankenphp:php${VERSION}-alpine" FROM ${BASE_IMAGE} AS base LABEL org.opencontainers.image.authors="99linesofcode@gmail.com" -RUN set -eux; \ - install-php-extensions \ - bcmath \ - pdo_mysql \ - pdo_pgsql \ - intl \ - zip \ - redis; +ARG VERSION + +RUN apk add --no-cache \ + php${VERSION/./}-bcmath \ + php${VERSION/./}-ctype \ + php${VERSION/./}-curl \ + php${VERSION/./}-dom \ + php${VERSION/./}-fileinfo \ + php${VERSION/./}-fpm \ + php${VERSION/./}-iconv \ + php${VERSION/./}-intl \ + php${VERSION/./}-json \ + php${VERSION/./}-mbstring \ + php${VERSION/./}-opcache \ + php${VERSION/./}-openssl \ + php${VERSION/./}-pcntl \ + php${VERSION/./}-phar \ + php${VERSION/./}-pdo_mysql \ + php${VERSION/./}-pdo_pgsql \ + php${VERSION/./}-pdo_sqlite \ + php${VERSION/./}-session \ + php${VERSION/./}-simplexml \ + php${VERSION/./}-tokenizer \ + php${VERSION/./}-xml \ + php${VERSION/./}-xmlwriter \ + php${VERSION/./}-zlib \ + php${VERSION/./}-zip \ + php${VERSION/./}-pecl-redis; WORKDIR /app @@ -24,10 +44,9 @@ WORKDIR /app FROM base AS development -RUN set -eux; \ - install-php-extensions \ - @composer \ - xdebug; +RUN apk add --no-cache \ + composer \ + php${VERSION/./}-pecl-xdebug; COPY --link ./frankenphp/php.ini-development ${PHP_INI_DIR}/php.ini @@ -44,8 +63,7 @@ ENV CGO_ENABLED=1 \ XCADDY_SETCAP=1 \ XCADDY_GO_BUILD_FLAGS="-ldflags='-w -s' -tags=nobadger,nomysql,nopgx" -RUN set -eux; \ - xcaddy build \ +RUN xcaddy build \ --output /usr/local/bin/frankenphp \ --with github.com/dunglas/frankenphp=./ \ --with github.com/dunglas/frankenphp/caddy=./caddy/ \ @@ -53,15 +71,13 @@ RUN set -eux; \ FROM base AS composer-builder -RUN set -eux; \ - install-php-extensions \ - @composer \ - && composer install -n --no-cache --prefer-dist --no-dev --no-scripts -o -a; +RUN apk add --no-cache \ + composer && \ + composer install -n --no-cache --prefer-dist --no-dev --no-scripts -o -a; FROM base AS production -RUN set -eux; \ - mv ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini; +RUN mv ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini; # Replace the official binary by the one containing our custom modules COPY --from=caddy-builder /usr/local/bin/frankenphp /usr/local/bin/frankenphp