August 12, 2017

Disabling xDebug in Production

We see how we can enable or disable the Xdebug PHP module based on the application environment.

The last thing I like to do is automatically enable or disable the Xdebug module based on the application environment.

This means Xdebug won't just be disabled (turned off) in production, the module itself won't even be loaded.

In any other environment, Xdebug will be enabled and configured.

Start Command

We start by editing the start-container script to automatically enable or disable xdebug based on a new variable APP_ENV.

If it's "production" or "prod", it disabled xdebug. Otherwise it enabled it.

This takes advantage of ubuntu/debian's PHP setup where it uses symlinks to enable or disable PHP modules, depending on the relevant PHP SAPI (fpm, cli, apache2).

#!/usr/bin/env bash

if [ ! "production" == "$APP_ENV" ] && [ ! "prod" == "$APP_ENV" ]; then
    # Enable xdebug

    ## FPM
    ln -sf /etc/php/7.0/mods-available/xdebug.ini /etc/php/7.0/fpm/conf.d/20-xdebug.ini

    ## CLI
    ln -sf /etc/php/7.0/mods-available/xdebug.ini /etc/php/7.0/cli/conf.d/20-xdebug.ini
else
    # Disable xdebug

    ## FPM
    if [ -e /etc/php/7.0/fpm/conf.d/20-xdebug.ini ]; then
        rm -f /etc/php/7.0/fpm/conf.d/20-xdebug.ini
    fi

    ## CLI
    if [ -e /etc/php/7.0/cli/conf.d/20-xdebug.ini ]; then
        rm -f /etc/php/7.0/cli/conf.d/20-xdebug.ini
    fi
fi

# Config /etc/php/7.0/mods-available/xdebug.ini
sed -i "s/xdebug\.remote_host\=.*/xdebug\.remote_host\=$XDEBUG_HOST/g" /etc/php/7.0/mods-available/xdebug.ini

php -S 0.0.0.0:80 -t /var/www/html

Docker Compose

Once that's set, we can update the docker-compose.yml file to incorporate the new APP_ENV environment variable:

version: '2'
services:
  app:
    build:
      context: ./
      dockerfile: Dockerfile
    image: xdebug-example:latest
    environment:
      APP_ENV: "${APP_ENV}"
      XDEBUG_HOST: ${XDEBUG_HOST}
    volumes:
     - ./app:/var/www/html
    ports:
     - "80:80"

Helper Script

Finally, we can update our helper script to set the APP_ENV variable. It defaults to "local", but we can set it to whatever we want on the fly.

#!/usr/bin/env bash

# Set environment variables for dev
export XDEBUG_HOST=$(ipconfig getifaddr en1) # Specific to Macintosh
export APP_ENV=${APP_ENV:-local}

if [ $# -gt 0 ]; then
    docker-compose "$@"
else
    docker-compose ps
fi

Try it Out

We're ready to try this out!

# Spin down any running containers
./develop down

# Rebuild the image to suck in latest `start-container` file
./develop build

# Turn on containers, let it use the
# default "local" environment - xdebug is enabled!
./develop up -d
./develop exec app php --info | grep remote_enable

# Spin containers down
./develop down

# Check that xdebug is not present/enabled when APP_ENV is
# set to "production"
APP_ENV=production ./develop up -d
./develop exec app php --info | grep remote_enable

Looking for a deeper dive into Docker?

Sign up here to get a preview of the Shipping Docker course! Learn how to integrate Docker into your applications and develop a workflow to make using Docker a breeze!

All Topics