Easy CakePHP Docker Guide with MySQL, Apache and Compose

Posted December 1, 2023
Easy CakePHP Docker Guide with MySQL, PHP Apache and Compose

CakePHP makes it easier to organize code and create scalable, maintainable applications. You probably want to use containers like Docker to Dockerize your CakePHP apps. If you want to use CakePHP and Docker, this guide is for you.

You will learn everything you need to know about CakePHP running on Docker based on the following:

  • How to run a basic CakePHP with Docker using PHP, Apache, and Docker composer.
  • How to create a Dockerfile for running CakePHP on Docker.
  • You will spin up a MySQL container and learn how to use it with Dockerize CakePHP to create a Database connection and CRUD APIs.
  • Because you have a MySQL service running alongside CakePHP within Docker, you will use PhpMyAdmin to manage and access your database

Ready? Dive into this comprehensive guide and take CakePHP to Docker using MySQL, Docker Compose, and Apache.

Step 1: Prerequisites

Running CakePHP with Docker is a step-by-step guide. You will need:

  • Docker installed and up and running on your computer.
  • Ensure you have the latest version of PHP installed on your machine.
  • CakePHP uses composer. Make sure it is installed and ready to run composer commands.

Step 2: Setting up CakePHP App

Once you have all the above prerequisites ready, head over to your working directory and create your CakePHP app using the following command:

composer create-project --prefer-dist cakephp/app cake_app

At first, you might encounter the following Error:

Easy CakePHP Docker Guide with Compose, Apache and MySQL

Your app will be created, but it won’t work. In this case, you must have ext-intl in your system. Go to C:\tools\php83\php.ini file, search ;extension=intl and remove ;. You should only have extension=intl. Save your file once you make this change.

For XAMPP:

  • Locate your php.ini file (usually in C:\xampp\php\php.ini).
  • Uncomment (remove the semicolon ;) from the line ;extension=intl.

For WampServer:

  • Click on the WampServer icon in your taskbar.
  • Go to PHP > PHP Extensions > php_intl. Ensure that it is checked.

If you are on Linux, use the following:

sudo apt update
sudo apt install php-intl php-xml -y

Now, rerun the composer command:

composer create-project --prefer-dist cakephp/app cake_app

Keep in mind:

  • This command may take some time to finish.
  • Composer will ask you to set up folder permissions. Use y to proceed.

If successful, you should have your app ready.

Easy CakePHP Docker Guide with Compose, Apache and MySQL

Step 3: Setting up your CakePHP, Dockerfile, and Docker Compose Structure

Along this guide, you will use the following file Structure. Ensure you have it ready to follow along with the next steps.

cakephp-docker/
│ ├── Dockerfile
│ └── docker-compose.yml
└── cake_app

Here:

  • The cake_app directory contains the CakePHP application you just created.
  • You will use Dockerfile to lay down all CakePHP instructions you want to run on Docker.
  • The docker-compose.yml file creates the service to spin up CakePHP and MySQL containers on Docker.

Step 4: Creating your Ideal CakePHP Dockerfile

Docker uses Dockerfile to package your application. You will use Dockerfile to let Docker know how to package your CakePHP app.

Go to your Dockerfile and follow these steps:

  • Add your base image. In this case, use Apache PHP and select the version of your choice. At the same time, create a working directory within Docker. I’m using PHP 8.2 as follows:
# Use an official PHP runtime as a parent image
FROM php:8.2-apache

# Set the working directory to /app
WORKDIR /var/www/html
  • Make sure you have the necessary dependencies ready based on the extensions you want to use. As you did locally, ensure ext-intl is installed and configured. The same case to MySQL-related extensions using docker-php-ext-install as you need them when connecting to your database:
# Install system dependencies
RUN apt-get update && apt-get install -y \
    libicu-dev \
    zlib1g-dev \
    libzip-dev

# Install PHP extensions
RUN docker-php-ext-install pdo pdo_mysql intl zip \ 
    && docker-php-ext-configure intl
  • CakePHP requires access to the filesystem. Remember how you added CakePHP folder permissions? Now, here you are using Apache to server CakePHP. Ensure you enable module rewrite as such:
# Enable Apache mod_rewrite
RUN a2enmod rewrite
  • CakePHP uses composer.lock and composer.json to manage extensions. You must ensure these files are copied to your Docker working directory. While copying them, ensure you add the right paths. For example, cake_app/composer.json:
# Copy composer.lock and composer.json
COPY cake_app/composer.json cake_app/composer.lock /var/www/html/
  • Docker isolates your app. This means the dependencies and extensions you initially had are unavailable within Docker. Now, you need to ensure Docker runs your composer.json file and install them as follows:
# Install composer dependencies
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer install --no-plugins --no-scripts

Your complete Dockerfile should be as follows:

# Use an official PHP runtime as a parent image
FROM php:8.2-apache
# Set the working directory to /app
WORKDIR /var/www/html
# Install system dependencies
RUN apt-get update && apt-get install -y \
    libicu-dev \
    zlib1g-dev \
    libzip-dev
# Install PHP extensions
RUN docker-php-ext-install pdo pdo_mysql intl zip \ 
    && docker-php-ext-configure intl
# Enable Apache mod_rewrite
RUN a2enmod rewrite
# Copy composer.lock and composer.json
COPY my-cakephp-app/composer.json my-cakephp-app/composer.lock /var/www/html/
# Copy composer.lock and composer.json
COPY cake_app/composer.json cake_app/composer.lock /var/www/html/

Step 5: Spinning a CakePHP Docker Container with Docker Compose

The above Dockerfile must be executed. To do that, you will use Docker Compose. Specifically using the docker-compose.yml. (I hope you check the project structure and have this file ready).

Update the docker-compose.yml file as follows:

version: '3.9'

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    
    ports:
      - "8000:80"
    volumes:
      - ./cake_app:/var/www/html

Docker will use this file to create a PHP container running CakePHP as a container.

The things to note are:

  • Use build to access the context of your Dockerfile. context: . check the Dockerfile path. If you have a Dockerfile on a different path, update it as such.
  • You need a volume that will copy your cake_app to Docker and map it to the Apache working directory var/www/html. You might be asked permission to access this directory in the coming steps. Make sure you allow it.

To run your container, use the following Docker Compose command:

docker-compose up --build -d

Easy CakePHP Docker Guide with Compose, Apache and MySQL

This will package and run CakePHP on Docker as follows:

Easy CakePHP Docker Guide with Compose, Apache and MySQL

Now you need to http://localhost:8000/ on the browser and access the Dockerize CakePHP app:

Easy CakePHP Docker Guide with Compose, Apache and MySQL

Everything is working except your database connection. Let’s now use MySQL and run it alongside CakePHP on Docker.

Step 6: Setting Up a CakePHP MySQL Database with Docker

Just like CakePHP, MySQL will run on Docker. In this case, you will use Docker Compose and spin up a MySQL service.

Update the docker-compose.yml file as follows:

version: '3.9'

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    
    ports:
      - "8000:80"
    depends_on:
      - db
    volumes:
      - ./my-cakephp-app:/var/www/html

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_DATABASE: cakephp_db
      MYSQL_USER: cakephp_user
      MYSQL_PASSWORD: cakephp_password
    ports:
      - "3306:3306"

What you need to note:

  • The Port 3306 must be available to run MySQL. If not, ensure you update it.
  • CakePHP will depend on MySQL as specified using depends_on: - db. This way, Docker will ensure your db service is running before attempting to create a CakePHP service and avoid unnecessary database errors.
  • db is the service running MySQL. When creating connections, db will be the host and not localhost, as you would do on bare metals.
  • All credentials such as user, passwords, and database will be created when the MySQL container is created. It’s these variables that you need to use to establish database connections.

Step 7: Configuring and Connecting CakePHP to the Database

Database connection information for CakePHP is stored in your application’s datastores. CakePHP uses config/app_local.php, config/app_local.example.php , and config/app.php files.

Because you are working on a local machine, you will use config/app_local.php to connect to MySQL.

Go to config/app_local.php and find the datasource block. Initially, it should have the following default values:

Easy CakePHP Docker Guide with Compose, Apache and MySQL

In your datasource, update the default block as follows:

'default' => [
  'className' => 'Cake\Database\Connection',
  'driver' => 'Cake\Database\Driver\Mysql',
  'persistent' => false,
  'host' => 'host', // MySQL service name as it appears on the Docker Compose file
  'username' => 'cakephp_user',
  'password' => 'cakephp_password',
  'database' => 'cakephp_db',
],

In this case, you must add MySQL database Drivers. But note the host is host and not localhost. The MySQL service name is on the Docker MySQL hostname as it appears on the Docker Compose file.

Rerun your container to add these changes:

docker-compose up --build -d

Refresh http://localhost:8000/ and check if you have a valid database connection:

Easy CakePHP Docker Guide with Compose, Apache and MySQL

You should get a CakePHP is able to connect to the database message. If otherwise, for example:

Easy CakePHP Docker Guide with Compose, Apache and MySQL

Recheck your config/app_local.php and MySQL variables on the docker-compose.yml file. If this doesn’t work for you. Delete your CakePHP containers, its volumes, and Docker image and rebuild your app using docker-compose up --build -d.

Step 8: How to access CakePHP MySQL database on Docker

Your app is running correctly. But how do you access your database? You use the MySQL Docker shell as follows:

  • Run the following command to get the complete MySQL service name:
docker ps

You will get:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
05eca362fb19 cakephp-docker-web "docker-php-entrypoi…" 18 seconds ago Up 8 seconds 0.0.0.0:8000->80/tcp cakephp-docker-web-1
14a8730261d9 mysql:8.0 "docker-entrypoint.s…" 20 seconds ago Up 13 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp cakephp-docker-db-1

Check Names; in this case, MySQL service is named cakephp-docker-db-1.

  • Now run the following command to access the MySQL container
docker exec -it cakephp-docker-db-1 bash
  • Next, use access MySQL as root:
mysql -u root -p
  • You will be asked for the root user password. This should be the password you added as MYSQL_ROOT_PASSWORD: root_password. Here, the password is root_password

Easy CakePHP Docker Guide with Compose, Apache and MySQL

  • Run the following SQL query to check if your cakephp_db was created:
show databases;

Easy CakePHP Docker Guide with Compose, Apache and MySQL

And now you have access to your CakePHP MySQL database on Docker.

However, you don’t want to always do this step to access databases. Let’s learn how to add phpMyAdmin.

Step 9: How to access CakePHP MySQL DB with phpMyAdmin on Docker

phpMyAdmin is a GUI for SQL databases. To use it with CakePHP and Docker, update the docker-compose.yml file with a phpMyAdmin service as follows:

version: '3.9'

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    
    ports:
      - "8000:80"
    depends_on:
      - db
    volumes:
      - ./my-cakephp-app:/var/www/html

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_DATABASE: cakephp_db
      MYSQL_USER: cakephp_user
      MYSQL_PASSWORD: cakephp_password
    ports:
      - "3306:3306"
  
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    links:
      - db
    ports:
      - "8081:80"
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORD: root_password

Rerun your container to add these changes:

docker-compose up --build -d

Open http://localhost:8081/ to access phpMyAdmin as follows:

Easy CakePHP Docker Guide with Compose, Apache and MySQL

Use root as the username and password as the root_password as set on MYSQL_ROOT_PASSWORD: password and login to phpMyAdmin:

Easy CakePHP Docker Guide with Compose, Apache and MySQL

And there you have your GUI working as expected.

Step 10: Build a CRUD CakePHP App with MySQL DB on Docker

The next step is running your CakePHP with Docker using the MySQL database. Now, let’s create a CRUD CakePHP app.

For this step, I hosted the CRUD app on this GitHub repository with all Docker and Docker Compose files:

Go ahead and clone it to get a CRUD CakePHP app. Then, build it with Docker, as you have done in the previous steps. Once done, all you need to do is go to your cakephp_db on PhpMyAdmin and create your table as follows:

CREATE TABLE IF NOT EXISTS tbl_users (
    id int unsigned NOT NULL AUTO_INCREMENT,
    name varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
    email varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,
    phone_no varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Easy CakePHP Docker Guide with Compose, Apache and MySQL

Open http://localhost:8000/list-users and add a new user to http://localhost:8000/add-user/ as follows:

Easy CakePHP Docker Guide with Compose, Apache and MySQL

You should be able to use the CakePHP app and access data added to your database:

Easy CakePHP Docker Guide with Compose, Apache and MySQL

At the same time, any changes you make using this API should be reflected in your database as such:

Easy CakePHP Docker Guide with Compose, Apache and MySQL

Conclusion

You have successfully deployed CakePHP to Docker. You used tools such as Docker Compose Apache, MySQL, and PhpMyAdmin to make this app work as you would expect. I hope you gained important insights to help you create future CakePHP apps with Docker, Docker Compose, MySQL, and Apache.

Happy Docker PHP Baking!

For further knowledge on how to use PHP and Docker, check:

Easy CakePHP Docker Guide with MySQL, Apache and Compose

Written By:

Joseph Chege