From 17a02310d519a38b14580c8bf90967fabf52fa6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 4 Aug 2022 14:47:59 +0200 Subject: [PATCH] feat: add native Xdebug support (#271) * feat: add native Xdebug support * cleanup * fix review * fix review * Improve docs * some more improvements * remove useless env var --- Dockerfile | 28 ++++++++-- docker-compose.override.yml | 18 ++++-- docker-compose.prod.yml | 1 - docker/php/conf.d/symfony.dev.ini | 18 ++---- docker/php/conf.d/symfony.ini | 13 +++++ docker/php/conf.d/symfony.prod.ini | 17 +----- docker/php/docker-entrypoint.sh | 7 +-- docs/xdebug.md | 90 +++++++----------------------- 8 files changed, 77 insertions(+), 115 deletions(-) create mode 100644 docker/php/conf.d/symfony.ini diff --git a/Dockerfile b/Dockerfile index cd532bb..b2e9946 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ ARG PHP_VERSION=8.1 ARG CADDY_VERSION=2 -# "php" stage +# Prod image FROM php:${PHP_VERSION}-fpm-alpine AS symfony_php # persistent / runtime deps @@ -19,7 +19,6 @@ RUN apk add --no-cache \ git \ ; -ARG APCU_VERSION=5.1.21 RUN set -eux; \ apk add --no-cache --virtual .build-deps \ $PHPIZE_DEPS \ @@ -35,7 +34,7 @@ RUN set -eux; \ zip \ ; \ pecl install \ - apcu-${APCU_VERSION} \ + apcu \ ; \ pecl clear-cache; \ docker-php-ext-enable \ @@ -59,7 +58,8 @@ RUN chmod +x /usr/local/bin/docker-healthcheck HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["docker-healthcheck"] RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" -COPY docker/php/conf.d/symfony.prod.ini $PHP_INI_DIR/conf.d/symfony.ini +COPY docker/php/conf.d/symfony.ini $PHP_INI_DIR/conf.d/symfony.ini +COPY docker/php/conf.d/symfony.prod.ini $PHP_INI_DIR/conf.d/symfony.prod.ini COPY docker/php/php-fpm.d/zz-docker.conf /usr/local/etc/php-fpm.d/zz-docker.conf @@ -110,6 +110,24 @@ VOLUME /srv/app/var ENTRYPOINT ["docker-entrypoint"] CMD ["php-fpm"] +# Dev image +FROM symfony_php AS symfony_php_dev + +RUN set -eux; \ + apk add --no-cache --virtual .build-deps $PHPIZE_DEPS; \ + pecl install xdebug; \ + docker-php-ext-enable xdebug; \ + apk del .build-deps + +RUN rm $PHP_INI_DIR/conf.d/symfony.prod.ini; \ + mv "$PHP_INI_DIR/php.ini" "$PHP_INI_DIR/php.ini-production"; \ + mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" + +COPY docker/php/conf.d/symfony.dev.ini $PHP_INI_DIR/conf.d/symfony.dev.ini + +RUN rm -f .env.local.php + +# Build Caddy with the Mercure and Vulcain modules FROM caddy:${CADDY_VERSION}-builder-alpine AS symfony_caddy_builder RUN xcaddy build \ @@ -118,11 +136,11 @@ RUN xcaddy build \ --with github.com/dunglas/vulcain \ --with github.com/dunglas/vulcain/caddy +# Caddy image FROM caddy:${CADDY_VERSION} AS symfony_caddy WORKDIR /srv/app -COPY --from=dunglas/mercure:v0.11 /srv/public /srv/mercure-assets/ COPY --from=symfony_caddy_builder /usr/bin/caddy /usr/bin/caddy COPY --from=symfony_php /srv/app/public public/ COPY docker/caddy/Caddyfile /etc/caddy/Caddyfile diff --git a/docker-compose.override.yml b/docker-compose.override.yml index e1154ac..0256f5a 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -3,20 +3,26 @@ version: "3.4" # Development environment override services: php: + build: + target: symfony_php_dev volumes: - ./:/srv/app - - ./docker/php/conf.d/symfony.dev.ini:/usr/local/etc/php/conf.d/symfony.ini + - ./docker/php/conf.d/symfony.dev.ini:/usr/local/etc/php/conf.d/symfony.dev.ini:ro # If you develop on Mac or Windows you can remove the var/ and vendor/ directories - # from the bind-mount for better performance by enabling the next 2 lines - # - /srv/app/var - # - /srv/app/vendor + # from the bind-mount for better performance by enabling the next 2 lines: + #- /srv/app/var + #- /srv/app/vendor environment: - APP_ENV: dev + # See https://xdebug.org/docs/all_settings#mode + XDEBUG_MODE: "${XDEBUG_MODE:-off}" + extra_hosts: + # Ensure that host.docker.internal is correctly defined on Linux + - host.docker.internal:host-gateway caddy: volumes: - - ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile:ro - ./public:/srv/app/public:ro + - ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile:ro ###> symfony/mercure-bundle ### ###< symfony/mercure-bundle ### diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 079c85d..8c33061 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -4,7 +4,6 @@ version: "3.4" services: php: environment: - APP_ENV: prod APP_SECRET: ${APP_SECRET} MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET} diff --git a/docker/php/conf.d/symfony.dev.ini b/docker/php/conf.d/symfony.dev.ini index 45e8afe..c1b6381 100644 --- a/docker/php/conf.d/symfony.dev.ini +++ b/docker/php/conf.d/symfony.dev.ini @@ -1,13 +1,5 @@ -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 +; 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' diff --git a/docker/php/conf.d/symfony.ini b/docker/php/conf.d/symfony.ini new file mode 100644 index 0000000..79a17dd --- /dev/null +++ b/docker/php/conf.d/symfony.ini @@ -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 diff --git a/docker/php/conf.d/symfony.prod.ini b/docker/php/conf.d/symfony.prod.ini index b4448f6..993d481 100644 --- a/docker/php/conf.d/symfony.prod.ini +++ b/docker/php/conf.d/symfony.prod.ini @@ -1,15 +1,2 @@ -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 -opcache.preload_user=www-data -opcache.preload=/srv/app/config/preload.php +opcache.preload_user = www-data +opcache.preload = /srv/app/config/preload.php diff --git a/docker/php/docker-entrypoint.sh b/docker/php/docker-entrypoint.sh index fb032cf..b63f34f 100755 --- a/docker/php/docker-entrypoint.sh +++ b/docker/php/docker-entrypoint.sh @@ -7,13 +7,9 @@ if [ "${1#-}" != "$1" ]; then fi if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then - if [ "$APP_ENV" != 'prod' ]; then - ln -sf "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" - fi - mkdir -p var/cache var/log - # The first time volumes are mounted, the project needs to be recreated + # The first time volumes are mounted, the project needs to be created if [ ! -f composer.json ]; then CREATION=1 composer create-project "$SKELETON $SYMFONY_VERSION" tmp --stability="$STABILITY" --prefer-dist --no-progress --no-interaction --no-install @@ -28,7 +24,6 @@ if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then fi if [ "$APP_ENV" != 'prod' ]; then - rm -f .env.local.php composer install --prefer-dist --no-progress --no-interaction fi diff --git a/docs/xdebug.md b/docs/xdebug.md index 08396dc..be3f307 100644 --- a/docs/xdebug.md +++ b/docs/xdebug.md @@ -1,89 +1,41 @@ -# Installing Xdebug +# Using Xdebug -The default Docker stack is shipped without [Xdebug](https://xdebug.org/), +The default development image is shipped with [Xdebug](https://xdebug.org/), a popular debugger and profiler for PHP. -It's easy, though, to add it to your project. -## Add a Debug Stage to the Dockerfile +Because it has a significant performance overhead, the step-by-step debugger is disabled by default. +It can be enabled by setting the `XDEBUG_MODE` environment variable to `debug`. -To avoid deploying Symfony Docker to production with an active Xdebug extension, -it's recommended to add a custom stage to the end of the `Dockerfile`. +On Linux and Mac: -```Dockerfile -# Dockerfile -FROM symfony_php AS symfony_php_debug - -ARG XDEBUG_VERSION=3.1.2 -RUN set -eux; \ - apk add --no-cache --virtual .build-deps $PHPIZE_DEPS; \ - pecl install xdebug-$XDEBUG_VERSION; \ - docker-php-ext-enable xdebug; \ - apk del .build-deps +``` +XDEBUG_MODE=debug docker compose up -d ``` -## Configure Xdebug with Docker Compose Override +On Windows: -Using an [override](https://docs.docker.com/compose/reference/overview/#specifying-multiple-compose-files) file named `docker-compose.debug.yml` ensures that the production -configuration remains untouched. - -As an example, an override could look like this: - -```yaml -# docker-compose.debug.yml -version: "3.4" - -services: - php: - build: - context: . - target: symfony_php_debug - environment: - # See https://docs.docker.com/docker-for-mac/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_CONFIG: >- - client_host=host.docker.internal - XDEBUG_MODE: debug - # This should correspond to the server declared in PHPStorm `Preferences | Languages & Frameworks | PHP | Servers` - # Then PHPStorm will use the corresponding path mappings - PHP_IDE_CONFIG: serverName=symfony - extra_hosts: - # Ensure that host.docker.internal is correctly defined on Linux - - host.docker.internal:host-gateway ``` - -Build your image with your fresh new XDebug configuration: - -```console -docker compose -f docker-compose.yml -f docker-compose.debug.yml build -``` - -Then run: - -```console -docker compose -f docker-compose.yml -f docker-compose.debug.yml up -d +set XDEBUG_MODE=debug&& docker compose up -d&set XDEBUG_MODE= ``` ## Debugging with Xdebug and PHPStorm -You can use the **Xdebug extension** for [Chrome](https://chrome.google.com/webstore/detail/xdebug-helper/eadndfjplgieldjbigjakmdgkmoaaaoc) or [Firefox](https://addons.mozilla.org/fr/firefox/addon/xdebug-helper-for-firefox/) if you want to debug on the browser (don't forget to configure it). +First, [create a PHP debug remote server configuration](https://www.jetbrains.com/help/phpstorm/creating-a-php-debug-server-configuration.html): -If you don't want to use it, add on your request this query param: `XDEBUG_SESSION=PHPSTORM`. +1. In the `Settings/Preferences` dialog, go to `PHP | Servers` +2. Create a new server: + * Host: `localhost` (or the one defined using the `SERVER_NAME` environment variable) + * Port: `443` + * Debugger: `Xdebug` + * Check `Use path mappings` + * Absolute path on the server: `/srv/app` -On PHPStorm, click on `Start Listening for PHP Debug Connections` in the `Run` menu. +You can now use the debugger! -Otherwise, you can create a [PHP Remote Debug](https://www.jetbrains.com/help/phpstorm/creating-a-php-debug-server-configuration.html) configuration with the following parameters: +1. In PHPStorm, open the `Run` menu and click on `Start Listening for PHP Debug Connections` +2. Add the `XDEBUG_SESSION=PHPSTORM` query parameter to the URL of the page you want to debug, or use [other available triggers](https://xdebug.org/docs/step_debug#activate_debugger) -* Server: - * Name: `symfony` (must be the same as defined in `PHP_IDE_CONFIG`) - * Host: `https://localhost` (or the one defined with `SERVER_NAME`) - * Port: `443` - * Debugger: `Xdebug` - * Absolute path on the server: `/srv/app` -* IDE key: `PHPSTORM` - -You can now use the debugger. +Alternatively, you can use [the **Xdebug extension**](https://xdebug.org/docs/step_debug#browser-extensions) for your preferred web browser. ## Troubleshooting