Customizing the image

There are a few ways that you can customize the Docker PHP images.

Installing additional PHP extensions

Let's say that we have a basic Docker compose image working in development:

docker-compose.yml

version: '3.7'services:  php:    image: serversideup/php:8.0-fpm-nginx    volumes:      - .:/var/www/html/:cached

Now let's say we want to add the PHP ImageMagick extension. To do this, we will use the docker compose build option in our YAML file.

This means we would need to change our file above to look like:

Updated docker-compose.yml file

version: '3.7'services:  php:    build:      context: .      dockerfile: Dockerfile    volumes:      - .:/var/www/html/:cached

Notice the services.php.build options. We set a . to look for a dockerfile called Dockerfile within the same directory as our docker-compose.yml file.

For extra clarity, my project directory would look like this:

Project File Structure

.
├── Dockerfile
├── docker-compose.yml
└── public
    └── index.php

The Dockerfile is where all the magic will happen. This is where we pull the Server Side Up image as a dependency, then run standard Ubuntu commands to add the extension that we need.

Dockerfile

# Set our base image
FROM serversideup/php:8.0-fpm-nginx

# Install PHP Imagemagick using regular Ubuntu commands
RUN apt-get update \
    && apt-get install -y --no-install-recommends php8.0-imagick \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*

The next time you run docker compose up, Docker will build and cache the image for you automatically.

You can verify the CLI option installed correctly by echoing out the installed modules. Run this command in a new window while your containers are running via Docker Compose:

Check loaded modules

docker compose exec php php -m

To check that PHP-FPM loaded everything properly, use the phpinfo() functionally.

⚠️ Important note about caching

  • You'll notice Docker likes to cache image builds (which is great for most functions)
  • If you make changes to your Dockerfile, you may need to include --build with your Docker compose command (read more here)

If you want to rebuild, then you would run this:

Rebuild on Docker Compose Initialization

docker compose up --build

How do I know which package name to use?

Refer to the official instructions of the extension that you are trying to install. We use Ondrej's PHP repository, so chances are you might be able to find in in here: https://launchpad.net/~ondrej/+archive/ubuntu/php/+packages

Make sure to use the same version number as well. For example... If you are using 8.0 and want to install the php-imagick package, use the name php8.0-imagick during install (see my examples above).

Production SSL Configurations

By default, we generate a self-signed certificate for simple local development. For production use, we recommend using as a proxy to your actual container.

You have a few options for using SSL in production. These configurations are only supported in the php-apache and php-nginx configurations.

Value of $SSL_MODEDescription
offThis will disable any SSL management and will use HTTP only. Direct all your container traffic to port 80.
mixedThis will support HTTP and HTTPS connections. You can send traffic to port 80 or 443.
full (default)This will provide "end-to-end encryption" to your web server. Any HTTP traffic will be redirected to HTTPS.

Using your own certificates

If you use mixed or full for your "SSL_MODE", we will check for certificate pairs at the following locations:

  1. /etc/ssl/web/ssl.crt
  2. /etc/ssl/web/ssl.key

Simply use Docker Volumes and mount the /etc/ssl/web folder with these two files in that directory.

If we do not find a certificate pair, we will generate a self-signed certificate pair for you.

The easiest way to get a trusted certificate

  1. Use a proxy that supports Let's Encrypt (like Traefik or Caddy)
  2. Make sure you allow your proxy to direct traffic encrypted with self-signed certificates (if you're proxying to the container with a self-signed certificate)

This is what we do and it's really nice to use the automatic Let's Encrypt SSL management with these products.