Docker setup for consistent PHP configuration

Background
I come from XAMPP for Windows, which was really easy, but had a design flaw.

I stumbled upon Docker and read that many developers praise its flexibility.

What I need help with
What’s the easiest way to set up apache + php + phpmyadmin such that there is only one php version + config for everything?

My hopes

  • A webserver which I can use for local development and bugfixing.

  • For staging and live, I use a hosting provider.

  • Use this webserver to upgrade old php projects (2014) from php 7.4 to 8.x.

It would also be nice if the webserver could support https, as that makes it easier to migrate software that relies on that between local, staging and live environments.

How far I got

  • I started with a promising YouTube-tutorial on how to make a webserver in Docker.

  • I fetched Docker from Microsoft Store and followed the instructions. However, I ran into issues when I started to actually use that setup.

  • I needed more extensions, which I found with Docker php extension installer.

  • The above research resulted in the following code:

    My docker-compose.yaml
    services:
      web:
        build: ./docker/web
        volumes:
          - ./:/var/www/html/
          - ./php.ini:/usr/local/etc/php/php.ini
        ports:
          - 80:80
      db:
        image: mysql:8.0.43
        volumes:
         - db:/var/lib/mysql/
        environment:
          - MYSQL_ROOT_PASSWORD=[REDACTED]
          - MYSQL_USER=[REDACTED]
          - MYSQL_PASSWORD=[REDACTED]
          - MYSQL_DATABASE=Testserver
          
      phpmyadmin:
        image: phpmyadmin
        restart: always
        ports:
          - 8080:80
        environment:
          - PMA_HOST=db
        depends_on:
          - db
    volumes:
      db:
    
    My Dockerfile
    FROM php:7.4.33-apache
    RUN docker-php-ext-install mysqli
    
    # Install php extension installer
    # Documentation: https://github.com/mlocati/docker-php-extension-installer
    ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
    
    # Setup desired extensions
    RUN install-php-extensions\
    # First install dependencies
     imagick\
    # Then install extensions
      bz2\
      exif\
      gd\
      igbinary\
      intl\
      xdebug\
      zip
    
    My php.ini
    file_uploads = On
    memory_limit = 500M
    upload_max_filesize = 64M
    post_max_size = 64M
    
  • I then attempted to import a database backup of more than 2 MB in phpmyadmin. This failed.

  • Looking into why, I saw that phpmyadmin was using its image’s own version of php (8.x) and not the one I had configured (7.4.33)

  • This was when I gave up trying to figure this out on my own.

I hope you can help me with this :blush:

Docker can help, but you stil need to understand some application-related configurations. Docker just gives you isolation so you don’t need to run a virtual machne whenever dependencies of two applications are not compatible. Just one reason from many, but you need to read the image descriptions or any documentation that comes with the images or application. If the image maintainer made configuration easier through environment variables or customizable commands, you may be able to do everything without actually readong the documentation of the application.

Here is the image description

It shows a list of environment variables to pass, including the one which increases the upload limit. Memory limit could also be important

Why did you expect using a PHP version defined in an unrelated Dockerfile made for another container? :slight_smile:

Each image is a template for new containers and each image has their own filesystem. Including libraries or in this case PHP interpreter. IN this regard it is almost like virtual machines, but containers are not virtual machines. You chose phpmyadmin as image and that has its own PHP interpreter defined here:

You can find the link to this in the image description I also linked above.

Search for “docker nginx reverse proxy” or “docker traefik reverse proxy”. These usually support generating a valid certificate with certbot (Let’s Encrypt).

I wrote about Nginx reverse proxy here:

But it does not add TLS. And I already switched to Traefik, but nginx was simpler for basic example.

I know people are alos using Nginx Proxy Manager that supports SSL/TLS

You will have more issues with TLS as well if you never configured reverse proxies before. With XAMPP, you had virtual hosts with a single HTTPD server that didn’t need an additional proxy. Now you could have multiple services each running in its own container with their own server and only one can listen on port 80 or port 443. Using aproxy is not mandatory in a local environment, but depending on your workflow, especially when you need SSL/TLS, it is recommended so your SSL config is in one proxy and not configured multiple different ways in each container.

Since this topic is a very general question, I tried to answer what I could quickly, but when you have a specific question while trying to implement either a reverse proxy or properly running a container, please open a new topic with a descriptive title which will get you more help focused on the exact problem. Otherwise it becomes a general question looking for a blogpost written for your exact use case.

You can still reply here to what I wrote of course.

1 Like