diff --git a/.spellcheckwordlist.txt b/.spellcheckwordlist.txt index 3f597bc58ee..3f2f9966749 100644 --- a/.spellcheckwordlist.txt +++ b/.spellcheckwordlist.txt @@ -134,6 +134,7 @@ bashrc bcmath be belonging +blackfire breakpoint browser busybox diff --git a/cmd/ddev/cmd/global_dotddev_assets/commands/web/blackfire b/cmd/ddev/cmd/global_dotddev_assets/commands/web/blackfire new file mode 100755 index 00000000000..8828fec2473 --- /dev/null +++ b/cmd/ddev/cmd/global_dotddev_assets/commands/web/blackfire @@ -0,0 +1,60 @@ +#!/bin/bash + +#ddev-generated: Remove this line to take over this script +## Description: Enable or disable blackfire.io profiling +## Usage: blackfire start|stop|on|off|enable|disable|true|false|status +## Example: "ddev blackfire" (default is "on"), "ddev blackfire off", "ddev blackfire on", "ddev blackfire status" + +function enable { + if [ -z ${BLACKFIRE_SERVER_ID} ] || [ -z ${BLACKFIRE_SERVER_TOKEN} ]; then + echo "BLACKFIRE_SERVER_ID and BLACKFIRE_SERVER_TOKEN environment variables must be set" >&2 + echo "See docs for how to set in global or project config" >&2 + echo "For example, ddev config global --web-env=BLACKFIRE_SERVER_ID=,BLACKFIRE_SERVER_TOKEN=" + exit 1 + fi + phpenmod blackfire + killall -HUP php-fpm + killall blackfire-agent 2>/dev/null + nohup blackfire-agent --log-level=4 >/tmp/blackfire_nohup.out 2>&1 & + sleep 1 + echo "Enabled blackfire PHP extension and started blackfire-agent" + exit +} +function disable { + phpdismod blackfire + killall -HUP php-fpm + killall blackfire-agent 2>/dev/null + echo "Disabled blackfire PHP extension and stopped blackfire-agent" + exit +} + + +if [ $# -eq 0 ] ; then + enable +fi + +case $1 in + on|true|enable|start) + disable_xdebug + enable + ;; + off|false|disable|stop) + disable + ;; + status) + php --version | grep "with blackfire" >/dev/null 2>&1 + phpstatus=$? + killall -0 blackfire-agent 2>/dev/null + agentstatus=$? + if [ ${phpstatus} -eq 0 ]; then echo "blackfire PHP extension enabled"; else echo "blackfire PHP extension disabled"; fi + if [ ${agentstatus} -eq 0 ]; then echo "blackfire agent running"; else echo "blackfire agent not running"; fi + + if [ ${phpstatus} -eq 0 ]; then printf "probe version %s\n" "$(php -v | awk -F '[ ,\~]+' '/blackfire/{ print $4; }')"; fi + printf "agent version %s\n" "$(blackfire-agent -v | awk '{print $2;}')" + printf "cli version %s\n" "$(blackfire version | awk '{print $2;}')" + ;; + + *) + echo "Invalid argument: $1" + ;; +esac diff --git a/cmd/ddev/cmd/packrd/packed-packr.go b/cmd/ddev/cmd/packrd/packed-packr.go index bc528346a51..2507203ad30 100644 --- a/cmd/ddev/cmd/packrd/packed-packr.go +++ b/cmd/ddev/cmd/packrd/packed-packr.go @@ -49,6 +49,7 @@ var _ = func() error { "e0a7c313cc6cfebdd1c68244f696aea1": "1f8b08000000000000ff9492df6bdb3e14c5dffd579caf5cbe65258edbbc0c5cf2b02e1e29b44b56671b834250ac1b47604b99ae1c276cfddf87f2abec61b0bdd9ba1f9d7baece8dff4b17daa40bc9ab288a63c44ad126a9c890939e5486fb2576b645278d87b720a53da451b09d815f69c652d7d483a3c66ee870526b43fd2036222e9d5e7b6d4d86a7d6604c5ae9e2d3036425b5618fb2758e8c875a04fe33cb8a32ac02c5dfeb70946f65b3ae298308c6ce25116a9362b65b1367e8b451b6e35ec7f52014c696fd9d36d2edf2ad66cf1944da189f96e9d4d9cac9061f744d9c9eeca427d93e6da9f73e7bfe0d7b3e61878f2326a248baaa6dc8781e8a245959f6c39bc1dbfe75ffba7f8324595be787173f46a3fccb7c3c2966f3d1dd7c3a799abd20495a263774d6fac049e6ce3a75fa57af8f76ba5edccff28fef1ef3171145a564c2c5a4987d9be6d0260244a7cd95b8c24f8886772caede440070f977e35e425c9c0711f87f7ff7f63602e21064bb4d2ad3421fc3de77d70c6bea1dbe160f034806534da52715a86326900bbba160eeac210eb6e2d725d08c475d3acb76e9f78a3d2c5a8f8ecedbc65e3a0fedb174b6d9f7db6bfc439ae20fe311cb32fa150000ffffb92696dafd020000", "e0cd29906a22fdca23ce152b565b2412": "1f8b08000000000000ff8ccc3d4e2c311004e0dca728e9052f5a7306124e408e7aec02b7f0748fdccd2c7b7bb401120101e9573fff7ae77979a37149b297279d0ca8a1de8387e13ba5774d750b5c754e6c44f343d9a1968e1cc4951b9a5b8a1ad7ffc07d85ae8b2d7ddd6a298f067eca7e4c6293182f32558251bf5103c7f2533b3b06172b9e1dbbbc133934f0aa9390967a1237ff40130335075729edf8fdb2fed4e20bd37089bf74bf020000ffff76526b0213010000", "e28fdb901662d2de6aeffe41ce3c4ebd": "1f8b08000000000000ff74cd3d8e83301086e1dea798c5db023dc56a8be408a910858d27c692b1cd8cc90fcae123a70952946aa4771ee9933fad76a1d58a2721a404690c5e6a8b01496534251d90477229bb183aa035c07ce7c59b754ee0025c51c31843562e20157e6265b1dba1feec95e5017a459687428e3735278f1d54656d478dae20d2478e7942faf2331a1e603797e0cfe88617dfd8ad12e20dea9562cc50a7d7f9fd17cf000000ffffd1f447b9f3000000", + "ea7eab1d4a3f18cc92988ebe4fb5f639": "1f8b08000000000000ffac544d73db3610bde357bc52aa15b766147b72922275da5a9e78d2693d4ed34be2f140e4924205012800d29e8aea6fef80d09763d9eea137cef2e1edee7bbbdbf9a63f15aa3fe56ec65827cfa94e4b5264b9a77c806b5ae89ae067c2410a45f01a9ecf09ba261bc32eb3c278d6e9e09ce2b7d06a8089e25349d016b970ede754f26c5e084baf8586b1ba1052a8323cfce47849831d00ce73eb1be7b569b46a745134d4d2356baec6db8a9a824b478df3dc572ed04ceef9c2481a20096dece812bccaa9e095f4100e8956c9f1c9d718e8a2480e44d58160cc983056542a0bdd22568725034481cf48ff4677f9d32f3ffefce1e2f27a72fb7172fdc7e4faf6f27c851b34cd9380df7ffb30f975859b21fc8c140300ca661ac9012a7095e3300348d5c26ab520e551732b42710e8bca794c098e7c82f1d1d91eff4722e43a7328b4c54cdf059b1d79088552ea2997c14763f59f9479645a15a2fc9ae2425b5034e004ad6011b72148d33b9aa6a4ead1816646ef443e3e39dccde89dd77352e32426bb171ea70c280403cccc905ae87c670e03e6424a2e25d2f79fae02222dcc622fbc85a6bc0c029d8dfb39d57d5549c900a5679579844953a9cb54524d72f416e3be5f98fe1673dbbe79adabc075748a2306384964da3aa33a711bf6eac4d5fb2bd0bd27e5c2000533dba1dfc7c4e4a1efd0355bede66db352cba8412edcff2a42acf93c2679a9686dccb34533d6ae44b78394fec21bdc603bde716d582118cbb823744f21425cabb8e0eba56f85396eed5f377e7b9fd3b42ae3444492f0391c86c745b1be0c9b63116a7cf07c078eab1c7f9a99419ad664dbe61a94960c923be167fba7642754ebf6e665241a757f68035bf5dfbca034d0461fbe8e7a2db7acab8d7251b8b53d4fb912f5c89321483a7a01bc1624a0db85da26df2beba5f4b12f5b292554f954da08527a1f187cff2ffd1a2b942f9018aba7848d41dfba2f2a41d27dd5fa56a301bf9b03e9057a9f71f2e59f9bef7be8edb6b4bf8c3ce8be1d62d53bde75bca18f253ea27f740b36a97acb35e1d930f03de0caa4788609bb217b8a68380cda7c77bc77612f55cda5c8c16d5985d33e40f7740b26c733f66f000000ffff1511d3bccc070000", "ef4b402bf593682c6c4a55ffbce4978a": "1f8b08000000000000ff3c8e314fc4300c46f7fc8a8f2b23e5f66e483d892d150556e426e61244132bf10115e2bfa3dcd0cd7acf965f77735c623a2e5483315d87ce7bfeeacf9cb890b26f68e4ea4a148d390db0c209d3e3346b2e2bbea3066860b84b299c1452f2073b6d672f95ce3c4082d4b6dbd0e98756f9e40187f665570763768758b192b3735f855d7c8fee0ecb45c1543768067912bd0e69839d4d6e3d3ded49f72482dbdf713cbdbe3d4cd393b5cf7fe63f0000ffff18fb6254e5000000", }) if err != nil { @@ -91,6 +92,7 @@ var _ = func() error { b.SetResolver("commands/host/tableplus", packr.Pointer{ForwardBox: gk, ForwardPath: "0181c02796835f56ef961c530e6d9ea0"}) b.SetResolver("commands/web/README.txt", packr.Pointer{ForwardBox: gk, ForwardPath: "980540b4eafc1b28426dd9c06ca8db82"}) b.SetResolver("commands/web/artisan", packr.Pointer{ForwardBox: gk, ForwardPath: "565cdeaa206a2e0b08f664b571332b02"}) + b.SetResolver("commands/web/blackfire", packr.Pointer{ForwardBox: gk, ForwardPath: "ea7eab1d4a3f18cc92988ebe4fb5f639"}) b.SetResolver("commands/web/drush", packr.Pointer{ForwardBox: gk, ForwardPath: "a8e701da77f72bae5c78ab8145fd51e9"}) b.SetResolver("commands/web/magento", packr.Pointer{ForwardBox: gk, ForwardPath: "7b12f0fa2b5500e80bcf6b6c591bf919"}) b.SetResolver("commands/web/reload-nginx.example", packr.Pointer{ForwardBox: gk, ForwardPath: "3d17d9b1e811ea02f7f3f998dccb0eaf"}) diff --git a/containers/ddev-webserver/Dockerfile b/containers/ddev-webserver/Dockerfile index f15887203ec..3efa660764c 100644 --- a/containers/ddev-webserver/Dockerfile +++ b/containers/ddev-webserver/Dockerfile @@ -68,11 +68,9 @@ RUN mkdir /tmp/ddev && \ MAILHOG_ARCH="linux_amd64"' > /tmp/ddev/vars; \ fi -# blackfire-php is not available for arm64 (yet) -RUN if [[ $TARGETPLATFORM != "linux/arm64" ]]; then \ - DEBIAN_FRONTEND=noninteractive apt-get -qq install -o Dpkg::Options::="--force-confold" blackfire-php -y --allow-unauthenticated; \ - fi RUN DEBIAN_FRONTEND=noninteractive apt-get -qq install -o Dpkg::Options::="--force-confold" --no-install-recommends --no-install-suggests -y \ + blackfire-agent \ + blackfire-php \ fontconfig \ gettext \ git \ @@ -121,7 +119,7 @@ RUN mkdir -p /etc/nginx/sites-enabled /var/log/apache2 /var/run/apache2 /var/lib RUN chmod -R 777 /var/log # we need to create the /var/cache/linux and /var/lib/nginx manually for the arm64 image and chmod them, please don't remove them! -RUN mkdir -p /mnt/ddev-global-cache/mkcert /run/php /var/cache/nginx /var/lib/nginx && chmod -R ugo+rw /mnt/ddev-global-cache/ +RUN mkdir -p /mnt/ddev-global-cache/mkcert /run/{php,blackfire} /var/cache/nginx /var/lib/nginx && chmod -R ugo+rw /mnt/ddev-global-cache/ RUN chmod -R ugo+w /usr/sbin /usr/bin /etc/nginx /var/cache/nginx /var/lib/nginx /run /var/www /etc/php/*/*/conf.d/ /var/lib/php/modules /etc/alternatives /usr/lib/node_modules /etc/php /etc/apache2 /var/log/apache2/ /var/run/apache2 /var/lib/apache2 /mnt/ddev-global-cache/* @@ -133,6 +131,8 @@ RUN touch /var/log/nginx/error.log /var/log/nginx/access.log /var/log/php-fpm.lo RUN a2dismod mpm_event RUN a2enmod ssl headers expires +RUN phpdismod blackfire + # scripts added last because they're most likely place to make changes, speeds up build ADD ddev-webserver-base-scripts / RUN chmod ugo+x /start.sh /healthcheck.sh diff --git a/containers/ddev-webserver/README.md b/containers/ddev-webserver/README.md index 22852e7741a..00d27fbb0de 100644 --- a/containers/ddev-webserver/README.md +++ b/containers/ddev-webserver/README.md @@ -9,6 +9,7 @@ This is a Dockerfile to build a container image for ddev's web container. * [Composer](https://getcomposer.org/) (from the production container) * [Drush](http://www.drush.org) (from the production container) * [WP-CLI](http://www.wp-cli.org) (from the production container) +* [Blackfire CLI](https://blackfire.io/docs/cookbooks/profiling-http-via-cli) * [Mailhog](https://github.com/mailhog/MailHog) * npm * yarn diff --git a/docs/users/blackfire-profiling.md b/docs/users/blackfire-profiling.md new file mode 100644 index 00000000000..96852d1a319 --- /dev/null +++ b/docs/users/blackfire-profiling.md @@ -0,0 +1,26 @@ +## Profiling with Blackfire.io + +DDEV-Local has built-in [blackfire.io](https://blackfire.io) integration. + +### Basic Blackfire Usage (Using Browser Plugin) + +1. Create an account on [blackfire.io](https://blackfire.io) +2. Install the Chrome or Firefox [browser plugin](https://blackfire.io/docs/profiling-cookbooks/profiling-http-via-browser). +3. Get the Server ID, Server Token, Client ID, and Client Token from your Account->Credentials or environment on blackfire.io. +4. Configure ddev with the credentials, `ddev config global --web-environment="BLACKFIRE_SERVER_ID=,BLACKFIRE_SERVER_TOKEN=,BLACKFIRE_CLIENT_ID=,BLACKFIRE_CLIENT_TOKEN="`. It's easiest to do this globally, but you can do the same thing at the project-level using `ddev config --web-environment`. (Note that you can also just manually edit the relevant config file.) +5. `ddev start` +6. `ddev blackfire on` to enable, `ddev blackfire off` to disable, `ddev blackfire status` to see status. +7. With Blackfire enabled, you can use the [browser extension](https://blackfire.io/docs/profiling-cookbooks/profiling-http-via-browser). + +### Profiling with the Blackfire CLI + +The Blackfire CLI is built into the web container. + +1. `ddev config global --web-environment="BLACKFIRE_SERVER_ID=,BLACKFIRE_SERVER_TOKEN=,BLACKFIRE_CLIENT_ID=,BLACKFIRE_CLIENT_TOKEN="` +2. `ddev start` +3. Examples of using the Blackfire CLI: + + * `ddev exec blackfire curl https://.ddev.site` + * `ddev exec blackfire drush st` + * `ddev exec blackfire curl https://.ddev.site` + * `ddev ssh` and then use the Blackfire CLI as described in [Profiling HTTP Requests with the CLI](https://blackfire.io/docs/profiling-cookbooks/profiling-http-via-cli). diff --git a/mkdocs.yml b/mkdocs.yml index beedbce3bb8..dce124122b0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -15,6 +15,7 @@ pages: - 'ddev Hooks': 'users/extending-commands.md' - 'Using Developer Tools with ddev': 'users/developer-tools.md' - 'PHP Step Debugging': 'users/step-debugging.md' + - 'Profiling with Blackfire': 'users/blackfire-profiling.md' - 'Troubleshooting': 'users/troubleshooting.md' - 'Docker Installation': 'users/docker_installation.md' - 'Performance': 'users/performance.md' diff --git a/pkg/version/version.go b/pkg/version/version.go index 214fd416ea2..ff7b27bc66d 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -40,7 +40,7 @@ var DockerComposeFileFormatVersion = "3.6" var WebImg = "drud/ddev-webserver" // WebTag defines the default web image tag for drud dev -var WebTag = "20210107_hardened_drush" // Note that this can be overridden by make +var WebTag = "20210111_lolautruche_blackfire" // Note that this can be overridden by make // DBImg defines the default db image used for applications. var DBImg = "drud/ddev-dbserver"