Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ trim_trailing_whitespace = false

[*.{yml,yaml}]
indent_size = 2

[Caddyfile]
indent_style = tab
14 changes: 2 additions & 12 deletions .env.example
Original file line number Diff line number Diff line change
@@ -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"
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
5 changes: 3 additions & 2 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
13 changes: 7 additions & 6 deletions docker-compose.yaml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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/
Expand Down Expand Up @@ -89,5 +90,5 @@ volumes:

networks:
default:
name: "${APP_NAME}-net"
name: '${APP_NAME}-net'
driver: bridge
2 changes: 1 addition & 1 deletion frankenphp/Caddyfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
acme_dns cloudflare {$CLOUDFLARE_DNS_API_TOKEN}
acme_dns cloudflare {$CLOUDFLARE_DNS_API_TOKEN}

{$CADDY_GLOBAL_OPTIONS}

Expand Down
60 changes: 38 additions & 22 deletions frankenphp/Dockerfile
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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

Expand All @@ -44,24 +63,21 @@ 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/ \
--with github.com/caddy-dns/cloudflare;

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
Expand Down