Running PHP, Apache, and PostgreSQL with Docker Compose

Posted October 1, 2023
Docker Apache PHP Setup with Docker Compose, PostgreSQL, and Pg4Admin

PHP is versatile, and you can use the database of your choice, such as PostgreSQL. In this guide, you’ll create a docker environment to set up a complete Docker Compose Apache PHP PostgreSQL app. To make a Docker Compose configuration for an environment with Apache, PHP, and PostgreSQL, you’ll cover the following topics:

  • Run PHP with PostgreSQL and Docker compose alongside PHP Apache.
  • Use Apache web server to serve your PHP code with Docker Compose container.
  • What you need to do and run any PHP versions (PHP 5.3, 5.4, 5.6, 7.0, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, etc.) using the PHP Apache server with a Docker container.
  • When using PostgreSQL, you will learn how to use the Docker php ext install pdo_pgsql command to configure your PostgreSQL extension for PHP.
  • Create a simple PHP app that shows you how to connect PHP Apache server and PostgreSQL on Docker
  • Run pgAdmin4 container with Docker Compose to create PostgreSQL GUI so you can access your PHP-related PostgreSQL database

Let’s Dive into this comprehensive guide and learn the easy Docker Apache PHP setup with Docker Compose and PostgreSQL.

Prerequisites

Setting up a Docker Compose Apache PHP PostgreSQL container is a step-by-step process. Ensure you have:

  • Docker installed on your computer
  • Basic knowledge of working with PHP and PostgreSQL will be great.
  • You will use the following application structure
php-docker/
│ ├── Dockerfile
│ └── docker-compose.yml
└── app/
    └── index.php

Ensure you have all files ready because:

  • Dockerfile will have all the Docker PHP-related configurations
  • docker-compose.yml creates your service, PHP Apache, PostgreSQL, and pgAdmin4 so you can have a complete PHP Docker environment setup.
  • app/index.php hosts the PHP code you will use to test your PHP Docker container.

Creating PHP Apache Server Image using PHP Dockerfile

You must create a custom Docker image to package the PHP app and all the commands to run and install what PHP needs. Here, you will use Dockerfile and add the configurations required to package your application together.

Create a Dockerfile and define the Docker image for your PHP and Apache environment as follows:

  • Use PHP Apache as your base image as follows:
# Use an official PHP Apache runtime
FROM php:8.2-apache

In the above sample, note that you use PHP 8.2. Now, if you need to use a different version, such as 5.3, 5.4, 5.6, 7.0, 7.2, 7.3, 7.4, 8.0, or 8.1, change 8.2 and everything will still work fine.

  • Use RUN to enable PHP Apache modules and install the needed extensions. Because you are using PostgreSQL, you need to run docker-php-ext-install to install pdo and pdo_pgsql for database connections as follows:
# Enable Apache modules
RUN a2enmod rewrite
# Install PostgreSQL client and its PHP extensions
RUN apt-get update \
    && apt-get install -y libpq-dev \
    && docker-php-ext-install pdo pdo_pgsql
  • Docker needs a directory to save your code within your docker Image. Set the working directory to the default Apache server path as follows:
# Set the working directory to /var/www/html
WORKDIR /var/www/html
  • Now Docker will copy your PHP app source files to this directory using the COPY command:
# Copy the PHP code file in /app into the container at /var/www/html
COPY ../app .

This Dockerfile is enough to spin up Apache PHP PostgreSQL. It should be complete as follows:

# Use an official PHP Apache runtime
FROM php:8.2-apache
# Enable Apache modules
RUN a2enmod rewrite
# Install PostgreSQL client and its PHP extensions
RUN apt-get update \
    && apt-get install -y libpq-dev \
    && docker-php-ext-install pdo pdo_pgsql
# Set the working directory to /var/www/html
WORKDIR /var/www/html
# Copy the PHP code file in /app into the container at /var/www/html
COPY ../app .

Creating PHP Apache Container with Docker Compose and Serve PHP App

A container will execute the above Dockerfile, package PHP, and Docker Compose will spin up the Apache server to run your PHP app.

Up to now, ensure you have a simple PHP script in your app/index.php:

<?php
echo "Running a PHP Apache Docker Container";
?>

Head over to docker-compose.yml and create a service to run PHP Apache and your Dockerfile as follows:

version: '3.9'
services:
  # Apache webserver service
  webserver:
    container_name: PHP-webServer
    build:
    # Dockerfile path
      context: .
      dockerfile: Dockerfile  
    # Mount the local ./app directory to /var/www/html in the container
    volumes:
      - ./app:/var/www/html 
    # Map port 8000 on the host to port 80 on the container 
    ports:
      - 8000:80   

Docker Compose package your Docker file custom image and create a PHP-webServer container. It will expose PHP on port 8000 so you can access it on the web.

Run the following command to build your container with Docker Compose:

docker-compose up -d

Docker Apache PHP Setup with Docker Compose, PostgreSQL and Pg4Admin

Docker will pop up a share widget so it can create your container volume correctly as follows:

Docker Apache PHP Setup with Docker Compose, PostgreSQL and Pg4Admin

If you didn’t get such, rerun the docker-compose up -d command.

Your Docker Demon will create a PHP Apache container as follows:

Docker Apache PHP Setup with Docker Compose, PostgreSQL and Pg4Admin

Now open http://localhost:8000/, and Docker should serve your simple PHP as follows:

Docker Apache PHP Setup with Docker Compose, PostgreSQL and Pg4Admin

Add PostgreSQL Docker Container to PHP Apache using Docker Compose

The main goal is to create a PHP app that can use PostgreSQL while running on Docker. You need to use Docker Compose and create a PostgreSQL service.

In your docker-compose.yml, add the following changes to create PostgreSQL:

version: '3.9'
services:
  # Apache webserver service
  webserver:
    container_name: PHP-webServer
    build:
    # Dockerfile path
      context: .
      dockerfile: Dockerfile  
    # Mount the local ./app directory to /var/www/html in the container
    volumes:
      - ./app:/var/www/html 
    # Map port 8000 on the host to port 80 on the container 
    ports:
      - 8000:80  
    depends_on:
      - postgres

  postgres:
    image: postgres:16.0
    environment:
      POSTGRES_DB: test_database
      POSTGRES_USER: db_user
      POSTGRES_PASSWORD: db_password
    ports:
      - "5432:5432"

Note we have added the following to the PHP container:

 depends_on:
      - postgres

This will instruct Docker that PHP will need PostgreSQL to run your code. This way, PostgreSQL must run before Docker runs the PHP Apache server.

Now, you need to create a PostgreSQL PHP database connection script to test whether PostgreSQL and PHP work correctly on Docker.

In your app/index.php file, add the following code:

<?php
$host = 'postgres';
$user = 'db_user';
$pass = 'db_password';
$db = 'test_database';

$conn = new PDO("pgsql:host=$host;dbname=$db", $user, $pass);

if (!$conn) {
    die("Connection failed");
}

echo "Connected to PostgreSQL successfully";

// Your PHP code for PostgreSQL interactions goes here

$conn = null;
?>

What you need to note:

  • $host = 'postgres' cannot be $host = 'localhost' as you would add in a typical PHP app. In this case, PHP is running Docker. Its host will be service postgres, which runs PostgreSQL. $user = 'db_user', $pass = 'db_password', and $db = 'test_database' are the variables you used in your PostgreSQL container. They must reflect as such. Otherwise, PHP will fail to connect to your database.

Rerun Docker Compose to build your containers:

docker-compose up -d

Docker Apache PHP Setup with Docker Compose, PostgreSQL and Pg4Admin

If you reload http://localhost:8000/, Apache will run PHP code and connect to the PostgreSQL database. If everything works correctly, you should have Connected to PostgreSQL successfully as follows:

Docker Apache PHP Setup with Docker Compose, PostgreSQL and Pg4Admin

Now, you can use this Docker Compose Apache PHP PostgreSQL and run your code without worries.

Accessing PostgreSQL PHP Apache Server using pgAdmin4

A database GUI is excellent when you need access to what’s happening in your DB. PostgreSQL uses pgAdmin4 to do this.

Add pgAdmin4 to Docker and access PostgreSQL.

Update the docker-compose.yml file as follows:

version: '3.9'
services:
  # Apache webserver service
  webserver:
    container_name: PHP-webServer
    build:
    # Dockerfile path
      context: .
      dockerfile: Dockerfile  
    # Mount the local ./app directory to /var/www/html in the container
    volumes:
      - ./app:/var/www/html 
    # Map port 8000 on the host to port 80 on the container 
    ports:
      - 8000:80  
    depends_on:
      - postgres

  postgres:
    image: postgres:16.0
    environment:
      POSTGRES_DB: test_database
      POSTGRES_USER: db_user
      POSTGRES_PASSWORD: db_password
    ports:
      - "5432:5432"

  pgadmin:
    image: dpage/pgadmin4:latest
    environment:
      # Default email for pgAdmin 4
      PGADMIN_DEFAULT_EMAIL: [email protected]
      # Password for accessing pgAdmin 4
      PGADMIN_DEFAULT_PASSWORD: adminpassword
    ports:
      # Expose pgadmin on 5050 
      - "5050:80"
    volumes:
      - pgadmin_data:/var/lib/pgadmin
    depends_on:
      - postgres
    restart: always
volumes:
  pgadmin_data:

Then run your containers:

docker-compose up -d

Open http://localhost:5050/ to access pgAdmin4 (it might take a few seconds to load). The use test email [email protected] and adminpassword to log in:

Docker Apache PHP Setup with Docker Compose, PostgreSQL and Pg4Admin

You need to Add New Server:

Docker Apache PHP Setup with Docker Compose, PostgreSQL and Pg4Admin

Give your Server a name:

Docker Apache PHP Setup with Docker Compose, PostgreSQL and Pg4Admin

Navigate to the Connection and use the PostgreSQL connection variables you use in the Docker container. They are:

  postgres:
    image: postgres:16.0
    environment:
      POSTGRES_DB: test_database
      POSTGRES_USER: db_user
      POSTGRES_PASSWORD: db_password
  • Host name will be postgres
  • Username is db_user
  • Password is db_password

Docker Apache PHP Setup with Docker Compose, PostgreSQL and Pg4Admin

Save these changes, and you should now have a working PostgreSQL GUI to manage PHP databases on Docker:

Docker Apache PHP Setup with Docker Compose, PostgreSQL and Pg4Admin

Conclusion

You learned to run PHP with PostgreSQL and Docker compose alongside PHP Apache. You can now create a PHP app using the PHP Apache server and PostgreSQL on Docker. You have a pgAdmin4 container with Docker Compose to create PostgreSQL GUI so you can access your PHP-related PostgreSQL database.

Running PHP, Apache, and PostgreSQL with Docker Compose

Written By:

Joseph Chege