-
Notifications
You must be signed in to change notification settings - Fork 44
[Example] [WIP] Add Symfony Docker with FrankenPHP #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| **/*.log | ||
| **/*.md | ||
| **/*.php~ | ||
| **/*.dist.php | ||
| **/*.dist | ||
| **/*.cache | ||
| **/._* | ||
| **/.dockerignore | ||
| **/.DS_Store | ||
| **/.git/ | ||
| **/.gitattributes | ||
| **/.gitignore | ||
| **/.gitmodules | ||
| **/compose.*.yaml | ||
| **/compose.*.yml | ||
| **/compose.yaml | ||
| **/compose.yml | ||
| **/docker-compose.*.yaml | ||
| **/docker-compose.*.yml | ||
| **/docker-compose.yaml | ||
| **/docker-compose.yml | ||
| **/Dockerfile | ||
| **/Thumbs.db | ||
| .github/ | ||
| docs/ | ||
| public/bundles/ | ||
| tests/ | ||
| var/ | ||
| vendor/ | ||
| .editorconfig | ||
| .env.*.local | ||
| .env.local | ||
| .env.local.php | ||
| .env.test |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| #syntax=docker/dockerfile:1 | ||
|
|
||
| # Versions | ||
| FROM dunglas/frankenphp:1-php8.3 AS frankenphp_upstream | ||
|
|
||
| # The different stages of this Dockerfile are meant to be built into separate images | ||
| # https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage | ||
| # https://docs.docker.com/compose/compose-file/#target | ||
|
|
||
|
|
||
| # Base FrankenPHP image | ||
| FROM frankenphp_upstream AS frankenphp_base | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| VOLUME /app/var/ | ||
|
|
||
| # persistent / runtime deps | ||
| # hadolint ignore=DL3008 | ||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | ||
| acl \ | ||
| file \ | ||
| gettext \ | ||
| git \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| RUN set -eux; \ | ||
| install-php-extensions \ | ||
| @composer \ | ||
| apcu \ | ||
| intl \ | ||
| opcache \ | ||
| zip \ | ||
| ; | ||
|
|
||
| # additional sulu extensions | ||
| RUN set -eux; \ | ||
| install-php-extensions \ | ||
| gd \ | ||
| curl \ | ||
| dom \ | ||
| bz2 \ | ||
| ; | ||
|
|
||
| # https://getcomposer.org/doc/03-cli.md#composer-allow-superuser | ||
| ENV COMPOSER_ALLOW_SUPERUSER=1 | ||
|
|
||
| ENV PHP_INI_SCAN_DIR=":$PHP_INI_DIR/app.conf.d" | ||
|
|
||
| ###> recipes ### | ||
| ###> doctrine/doctrine-bundle ### | ||
| RUN install-php-extensions pdo_mysql | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is required by default postgres is here but demo comes with MySQL |
||
| ###< doctrine/doctrine-bundle ### | ||
| ###< recipes ### | ||
|
|
||
| COPY --link frankenphp/conf.d/10-app.ini $PHP_INI_DIR/app.conf.d/ | ||
| COPY --link --chmod=755 frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint | ||
| COPY --link frankenphp/Caddyfile /etc/caddy/Caddyfile | ||
|
|
||
| ENTRYPOINT ["docker-entrypoint"] | ||
|
|
||
| HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1 | ||
| CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile" ] | ||
|
|
||
| # Dev FrankenPHP image | ||
| FROM frankenphp_base AS frankenphp_dev | ||
|
|
||
| ENV APP_ENV=dev XDEBUG_MODE=off | ||
|
|
||
| RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" | ||
|
|
||
| RUN set -eux; \ | ||
| install-php-extensions \ | ||
| xdebug \ | ||
| ; | ||
|
|
||
| COPY --link frankenphp/conf.d/20-app.dev.ini $PHP_INI_DIR/app.conf.d/ | ||
|
|
||
| CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile", "--watch" ] | ||
|
|
||
| # Prod FrankenPHP image | ||
| FROM frankenphp_base AS frankenphp_prod | ||
|
|
||
| ENV APP_ENV=prod | ||
| ENV FRANKENPHP_CONFIG="import worker.Caddyfile" | ||
|
|
||
| RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" | ||
|
|
||
| COPY --link frankenphp/conf.d/20-app.prod.ini $PHP_INI_DIR/app.conf.d/ | ||
| COPY --link frankenphp/worker.Caddyfile /etc/caddy/worker.Caddyfile | ||
|
|
||
| # prevent the reinstallation of vendors at every changes in the source code | ||
| COPY --link composer.* symfony.* ./ | ||
| RUN set -eux; \ | ||
| composer install --no-cache --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress | ||
|
|
||
| # copy sources | ||
| COPY --link . ./ | ||
| RUN rm -Rf frankenphp/ | ||
|
|
||
| RUN set -eux; \ | ||
| mkdir -p var/cache var/log; \ | ||
| composer dump-autoload --classmap-authoritative --no-dev; \ | ||
| composer dump-env prod; \ | ||
| composer run-script --no-dev post-install-cmd; \ | ||
| chmod +x bin/console; sync; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Production environment override | ||
| services: | ||
| php: | ||
| build: | ||
| context: . | ||
| target: frankenphp_prod | ||
| environment: | ||
| APP_SECRET: ${APP_SECRET} | ||
| MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET} | ||
| MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,39 @@ | ||
| version: '3' | ||
|
|
||
| services: | ||
| php: | ||
| image: ${IMAGES_PREFIX:-}app-php | ||
| restart: unless-stopped | ||
| environment: | ||
| SERVER_NAME: ${SERVER_NAME:-localhost}, php:80 | ||
| MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!} | ||
| MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!} | ||
| # Run "composer require symfony/orm-pack" to install and configure Doctrine ORM | ||
| DATABASE_URL: mysql://${MYSQL_USER:-root}:${MYSQL_PASSWORD:-ChangeMe}@database:3306/${MYSQL_DATABASE:-su_demo}?serverVersion=${MYSQL_VERSION:-8}&charset=${MYSQL_CHARSET:-utf8mb4} | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is hardcoded to postgres in symfony docker we changed this to mysql |
||
| ELASTICSEARCH_HOST: elasticsearch:9200 | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the demo uses elasticsearch so we need point to elasticsearch container instead go over the IP |
||
| # Run "composer require symfony/mercure-bundle" to install and configure the Mercure integration | ||
| MERCURE_URL: ${CADDY_MERCURE_URL:-http://php/.well-known/mercure} | ||
| MERCURE_PUBLIC_URL: ${CADDY_MERCURE_PUBLIC_URL:-https://${SERVER_NAME:-localhost}:${HTTPS_PORT:-443}/.well-known/mercure} | ||
| MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!} | ||
| # The two next lines can be removed after initial installation | ||
| SYMFONY_VERSION: ${SYMFONY_VERSION:-} | ||
| STABILITY: ${STABILITY:-stable} | ||
| volumes: | ||
| - caddy_data:/data | ||
| - caddy_config:/config | ||
| ports: | ||
| # HTTP | ||
| - target: 80 | ||
| published: ${HTTP_PORT:-80} | ||
| protocol: tcp | ||
| # HTTPS | ||
| - target: 443 | ||
| published: ${HTTPS_PORT:-443} | ||
| protocol: tcp | ||
| # HTTP/3 | ||
| - target: 443 | ||
| published: ${HTTP3_PORT:-443} | ||
| protocol: udp | ||
| ###> doctrine/doctrine-bundle ### | ||
| database: | ||
| # arm compatible mysql docker image | ||
|
|
@@ -29,3 +62,5 @@ volumes: | |
| database-data: | ||
| ###< doctrine/doctrine-bundle ### | ||
| elasticsearch-data: | ||
| caddy_data: | ||
| caddy_config: | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| { | ||
| {$CADDY_GLOBAL_OPTIONS} | ||
|
|
||
| frankenphp { | ||
| {$FRANKENPHP_CONFIG} | ||
| } | ||
| } | ||
|
|
||
| {$CADDY_EXTRA_CONFIG} | ||
|
|
||
| {$SERVER_NAME:localhost} { | ||
| log { | ||
| {$CADDY_SERVER_LOG_OPTIONS} | ||
| # Redact the authorization query parameter that can be set by Mercure | ||
| format filter { | ||
| request>uri query { | ||
| replace authorization REDACTED | ||
| } | ||
| } | ||
| } | ||
|
|
||
| root /app/public | ||
| encode zstd br gzip | ||
|
|
||
| mercure { | ||
| # Transport to use (default to Bolt) | ||
| transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db} | ||
| # Publisher JWT key | ||
| publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG} | ||
| # Subscriber JWT key | ||
| subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG} | ||
| # Allow anonymous subscribers (double-check that it's what you want) | ||
| anonymous | ||
| # Enable the subscription API (double-check that it's what you want) | ||
| subscriptions | ||
| # Extra directives | ||
| {$MERCURE_EXTRA_DIRECTIVES} | ||
| } | ||
|
|
||
| vulcain | ||
|
|
||
| {$CADDY_SERVER_EXTRA_DIRECTIVES} | ||
|
|
||
| # Disable Topics tracking if not enabled explicitly: https://github.com/jkarlin/topics | ||
| header ?Permissions-Policy "browsing-topics=()" | ||
|
|
||
| @phpRoute { | ||
| not path /.well-known/mercure* | ||
| not file {path} | ||
| } | ||
| rewrite @phpRoute index.php | ||
|
|
||
| @frontController path index.php | ||
| php @frontController | ||
|
|
||
| file_server { | ||
| hide *.php | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| expose_php = 0 | ||
| date.timezone = UTC | ||
| apc.enable_cli = 1 | ||
| session.use_strict_mode = 1 | ||
| zend.detect_unicode = 0 | ||
|
|
||
| ; https://symfony.com/doc/current/performance.html | ||
| realpath_cache_size = 4096K | ||
| realpath_cache_ttl = 600 | ||
| opcache.interned_strings_buffer = 16 | ||
| opcache.max_accelerated_files = 20000 | ||
| opcache.memory_consumption = 256 | ||
| opcache.enable_file_override = 1 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| ; See https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host | ||
| ; See https://github.com/docker/for-linux/issues/264 | ||
| ; The `client_host` below may optionally be replaced with `discover_client_host=yes` | ||
| ; Add `start_with_request=yes` to start debug session on each request | ||
| xdebug.client_host = host.docker.internal |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| ; https://symfony.com/doc/current/performance.html#use-the-opcache-class-preloading | ||
| opcache.preload_user = root | ||
| opcache.preload = /app/config/preload.php | ||
| ; https://symfony.com/doc/current/performance.html#don-t-check-php-files-timestamps | ||
| opcache.validate_timestamps = 0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| #!/bin/sh | ||
| set -e | ||
|
|
||
| if [ "$1" = 'frankenphp' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then | ||
| # Install the project the first time PHP is started | ||
| # After the installation, the following block can be deleted | ||
| if [ ! -f composer.json ]; then | ||
| rm -Rf tmp/ | ||
| composer create-project "symfony/skeleton $SYMFONY_VERSION" tmp --stability="$STABILITY" --prefer-dist --no-progress --no-interaction --no-install | ||
|
|
||
| cd tmp | ||
| cp -Rp . .. | ||
| cd - | ||
| rm -Rf tmp/ | ||
|
|
||
| composer require "php:>=$PHP_VERSION" runtime/frankenphp-symfony | ||
| composer config --json extra.symfony.docker 'true' | ||
|
|
||
| if grep -q ^DATABASE_URL= .env; then | ||
| echo 'To finish the installation please press Ctrl+C to stop Docker Compose and run: docker compose up --build -d --wait' | ||
| sleep infinity | ||
| fi | ||
| fi | ||
|
|
||
| if [ -z "$(ls -A 'vendor/' 2>/dev/null)" ]; then | ||
| composer install --prefer-dist --no-progress --no-interaction | ||
| fi | ||
|
|
||
| # Display information about the current project | ||
| # Or about an error in project initialization | ||
| php bin/console -V | ||
|
|
||
| if grep -q ^DATABASE_URL= .env; then | ||
| echo 'Waiting for database to be ready...' | ||
| ATTEMPTS_LEFT_TO_REACH_DATABASE=60 | ||
| until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(php bin/console dbal:run-sql -q "SELECT 1" 2>&1); do | ||
| if [ $? -eq 255 ]; then | ||
| # If the Doctrine command exits with 255, an unrecoverable error occurred | ||
| ATTEMPTS_LEFT_TO_REACH_DATABASE=0 | ||
| break | ||
| fi | ||
| sleep 1 | ||
| ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1)) | ||
| echo "Still waiting for database to be ready... Or maybe the database is not reachable. $ATTEMPTS_LEFT_TO_REACH_DATABASE attempts left." | ||
| done | ||
|
|
||
| if [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ]; then | ||
| echo 'The database is not up or not reachable:' | ||
| echo "$DATABASE_ERROR" | ||
| exit 1 | ||
| else | ||
| echo 'The database is now ready and reachable' | ||
| fi | ||
|
|
||
| if [ "$( find ./migrations -iname '*.php' -print -quit )" ]; then | ||
| php bin/console doctrine:migrations:migrate --no-interaction --all-or-nothing | ||
| fi | ||
| fi | ||
|
|
||
| setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var | ||
| setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var | ||
|
|
||
| echo 'PHP app ready!' | ||
| fi | ||
|
|
||
| exec docker-php-entrypoint "$@" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| worker { | ||
| file ./public/index.php | ||
| # env APP_RUNTIME Runtime\FrankenPhpSymfony\Runtime | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a quick start without worker mode |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This we added additional atleast
gdis required to run Sulu. Alternative isimagickorffi(when using vips adapter)