Category Archives: PSR-4

Docker LAMP Stack With Composer PSR-4 Autoloading – Apache Server

I wanted to create a Docker Lampstack with Composer PSR-4 Autoloading.

Here are my requirements:

  • Run on Ubuntu 22.04 or Windows
  • Apache Server
  • PhpMyadmin
  • PHP Version 8.3
  • Mysql Version 8
  • Composer
  • PS4- Autoloading
  • PHPMailer

These are the steps to run Composer and implement PSR-4 Autoloading in Docker:

Install Docker on your system if you don't already have it installed.

Step 1: Create a new project directory:

mkdir lampstack-project
cd lampstack-project

Step 2: Create a file named docker-compose.yml in the project directory:

touch docker-compose.yml

Step 3: Open the file using your preferred text editor:

nano docker-compose.yml

Step 4: Setting up the Services
In this step, we'll define the services we need for our project. We'll be using 3 services:

  • db: This service is for our database, which will run on the MySQL image.
  • web: This service is for our web server, which will run on the Apache image.
  • phpmyadmin: This service provides a graphical user interface to our MySQL database. It runs on the phpMyAdmin image.

Add the following contents to the docker-compose.yml file.

name: myapp

services:
  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: mydatabase
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypassword
    ports:
      - "3306:3306"
  web:
    build: .
    volumes:
      - ./:/var/www/html/
      - '/var/www/html/vendor' # Prevents first volume from overwriting vendor directory.
    ports:
      - "8000:80"
    links:
      - db
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports:
      - "8080:80"
    environment:
      PMA_HOST: db
      PMA_PORT: 3306
      PMA_ARBITRARY: 1
    links:
      - db

Step 5: Writing the Dockerfile
In this step, we'll write a Dockerfile that will define how our web service will be built.

This dockerfile sets up a basic PHP environment and installs the necessary PHP extensions. It also installs Composer and runs composer install to install the dependencies listed in your composer.json file.

Create a new Dockerfile with the following contents.

touch dockerfile
nano dockerfile
FROM php:8.3.6-apache

# Install dependencies and PHP extensions
RUN apt-get update && apt-get upgrade -y && \
    apt-get install -y libzip-dev zip nano && \
    docker-php-ext-install pdo pdo_mysql && \
    pecl install xdebug && docker-php-ext-enable xdebug && \
    apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev && \
    docker-php-ext-configure gd --with-freetype --with-jpeg && \
    docker-php-ext-install -j$(nproc) gd && \
    docker-php-ext-install zip

# Install Composer
COPY --from=composer/composer:latest-bin /composer /usr/bin/composer

# Set the COMPOSER_ALLOW_SUPERUSER environment variable
ENV COMPOSER_ALLOW_SUPERUSER 1

# Copy the code into the container
COPY . /var/www/html/

# Set the working directory to /var/www/html/
WORKDIR /var/www/html/

# Install PHPMailer
RUN composer require phpmailer/phpmailer

# Set Apache document root to /var/www/html/public
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf

# Run composer Install
RUN composer install

Step 6: Adding the composer.json File
In this step, we'll add a composer.json file that specifies the dependencies for our project.

Create a composer.json file in your project root with the following contents:

touch composer.json
nano composer.json

Paste this into your composer.json. I have added some package dependency's to demonstrate the automatic installation of Composer packages.

{
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    }
}

Step 7: Create a public directory & index.php in the project directory

mkdir public && touch public/index.php

Step 8: Open editor and add this to PHP code to index.php for Autoloading.

nano public/index.php
<?php

require_once '../vendor/autoload.php';

$controller = new App\Controllers\ExampleController();
echo $controller->index();

Step 9: Creating the ExampleController
In this step, we'll create an ExampleController that will handle the requests to our web service. This controller will return a simple message to confirm that our setup is working.

Create the Controller Directory and file ExampleController.php and open ExampController.php in your editor.

mkdir -p app/Controllers
touch app/Controllers/ExampleController.php

* Windows Use:

mkdir app\Controllers
touch app/Controllers/ExampleController.php

Step 10: Open editor & add the following PHP code to ExampleController.php

nano app/Controllers/ExampleController.php
<?php

namespace App\Controllers;

class ExampleController
{
    public function index()
    {
        return 'Hello World!';
    }
}

Step 11: Running the Docker Compose File

In this step, we'll run the docker-compose file to start the services we defined in step 4. The code for the docker-compose file will start the services and link them together, allowing them to communicate with each other.

Run the docker-compose up command from the directory where your docker-compose.yml file is located.

docker-compose up not only starts the containers defined in the docker-compose.yml file, but also builds the images if they do not already exist. The up command checks if the image specified in the docker-compose.yml file is present in the local system, and if it is not found, the image is built using the Dockerfile specified in the same file.

docker-compose up

This will run your PHP application with PSR-4 autoloading enabled via Composer, inside an Apache server and linked with a MySQL 8 database.

Composer should have run and installed the sample packages.

Step 12: Testing the Setup

In this step, we'll test our setup by making a request to our web service. If everything is set up correctly, we should see the message returned by the ExampleController.

Open a web browser and go to http://localhost:8000. You should see the output of your PHP script.

To access phpMyAdmin, go to http://localhost:8080 in your web browser. You will be prompted to log in with a username and password.

The username is "myuser" and the password is "mypassword", as specified in the environment variables of the "db" service in the docker-compose.yml file.

After logging in to phpMyAdmin, you should be able to see the "mydatabase" database and make any necessary changes to it through the phpMyAdmin interface.

PhpMyAdmin Logins

Server: db
User: myuser
Pasword:mypassword

User: root
Pasword:root

The "db" is specified in the PMA_HOST environment variable in the phpmyadmin service, and the port is specified in the ports section of the db service. When you access PHPMyAdmin on port 8080, it will connect to the database service running on db:3306.

Docker Container Terminal

To get a terminal in the Docker Container you can run the following command. You will be the root user so you can do anything you want from the terminal within your container including adding or deleting Composer Packages.

# Get a terminal
docker exec -it lampstack-project-web-1 /bin/bash

# To get out of the terminal shell, type 
exit

When you're done, you can stop the containers using the following command:

docker-compose down

Docker LAMP Stack With Composer PSR-4 Autoloading

This tutorial is partially obsolete. See updated version here.

I wanted to create a Docker Lampstack with Composer PSR-4 Autoloading.

Here are my requirements:

  • Run on Ubuntu 22.04
  • Apache Server
  • PhpMyadmin
  • PHP Version 8.1
  • Mysql Version 8
  • Composer
  • PS4- Autoloading

These are the steps to run Composer and implement PSR-4 Autoloading in Docker:

Install Docker on your system if you don't already have it installed.

Step 1: Create a new project directory:

mkdir lampstack-project
cd lampstack-project

Step 2: Create a file named docker-compose.yml in the project directory:

touch docker-compose.yml

Step 3: Open the file using your preferred text editor:

nano docker-compose.yml

Step 4: Setting up the Services
In this step, we'll define the services we need for our project. We'll be using 3 services:

  • db: This service is for our database, which will run on the MySQL image.
  • web: This service is for our web server, which will run on the Apache image.
  • phpmyadmin: This service provides a graphical user interface to our MySQL database. It runs on the phpMyAdmin image.

Add the following contents to the docker-compose.yml file.

version: '3.7'
services:
  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: mydatabase
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypassword
    ports:
      - "3306:3306"
  web:
    build: .
    volumes:
      - ./:/var/www/html/
    ports:
      - "8000:80"
    links:
      - db
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports:
      - "8080:80"
    environment:
      PMA_HOST: db
      PMA_PORT: 3306
      PMA_ARBITRARY: 1
    links:
      - db

Step 5: Writing the Dockerfile
In this step, we'll write a Dockerfile that will define how our web service will be built.

This dockerfile sets up a basic PHP environment and installs the necessary PHP extensions. It also installs Composer and runs composer install to install the dependencies listed in your composer.json file.

Create a new Dockerfile with the following contents.

touch dockerfile
nano dockerfile
FROM php:8.1-apache

# Install required PHP extensions
RUN apt-get update && apt-get install -y \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libmcrypt-dev \
    libpng-dev \
    libzip-dev \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) gd \
    && docker-php-ext-install pdo_mysql \
    && docker-php-ext-install zip

# Install Nano Text Editor
 RUN apt-get install -y nano     

# Install Composer
COPY --from=composer/composer:latest-bin /composer /usr/bin/composer

# Set the COMPOSER_ALLOW_SUPERUSER environment variable
ENV COMPOSER_ALLOW_SUPERUSER 1

# Copy the code into the container
COPY . /var/www/html/

# Set the working directory to /var/www/html/
WORKDIR /var/www/html/

# Run Composer to install dependencies
RUN composer install

# Expose port 8000
EXPOSE 8000

# Set the entrypoint to the Apache service
ENTRYPOINT ["apache2-foreground"]

Step 6: Adding the composer.json File
In this step, we'll add a composer.json file that specifies the dependencies for our project.

Create a composer.json file in your project root with the following contents:

touch composer.json
nano composer.json

Paste this into your composer.json. I have added some package dependency's to demonstrate the automatic installation of Composer packages.

{
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    },
    "require-dev": {
        "ext-pdo": "*",
        "php": "^8.1",
        "codeception/codeception": "^5.0",
        "codeception/module-phpbrowser": "*",
        "codeception/module-asserts": "*",
        "codeception/module-webdriver": "^4.0",
        "phpunit/phpunit": "^10.0"
    }
}

Step 7: Create an index.php in the project directory

touch index.php
nano index.php

Step 8: Add this to PHP code to index.php for Autoloading.

<?php

require_once __DIR__ . '/vendor/autoload.php';

$controller = new App\Controllers\ExampleController();
echo $controller->index();

Step 9: Creating the ExampleController
In this step, we'll create an ExampleController that will handle the requests to our web service. This controller will return a simple message to confirm that our setup is working.

Create the Controller Directory and file ExampleController.php and open ExampController.php in your editor.

mkdir -p app/Controllers
touch app/Controllers/ExampleController.php
nano app/Controllers/ExampleController.php

Step 10: Add the following PHP code to ExampleController.php

<?php

namespace App\Controllers;

class ExampleController
{
    public function index()
    {
        return 'Hello World!';
    }
}

Step 11: Running the Docker Compose File

In this step, we'll run the docker-compose file to start the services we defined in step 4. The code for the docker-compose file will start the services and link them together, allowing them to communicate with each other.

Run the docker-compose up command from the directory where your docker-compose.yml file is located.

docker-compose up not only starts the containers defined in the docker-compose.yml file, but also builds the images if they do not already exist. The up command checks if the image specified in the docker-compose.yml file is present in the local system, and if it is not found, the image is built using the Dockerfile specified in the same file.

docker-compose up

This will run your PHP application with PSR-4 autoloading enabled via Composer, inside an Apache server and linked with a MySQL 8 database.

Composer should have run and installed the sample packages.

Step 12: Testing the Setup

In this step, we'll test our setup by making a request to our web service. If everything is set up correctly, we should see the message returned by the ExampleController.

Open a web browser and go to http://localhost:8000. You should see the output of your PHP script.

To access phpMyAdmin, go to http://localhost:8080 in your web browser. You will be prompted to log in with a username and password.

The username is "myuser" and the password is "mypassword", as specified in the environment variables of the "db" service in the docker-compose.yml file.

After logging in to phpMyAdmin, you should be able to see the "mydatabase" database and make any necessary changes to it through the phpMyAdmin interface.

PhpMyAdmin Logins

Server: db
User: myuser
Pasword:mypassword

User: root
Pasword:root

The "db" is specified in the PMA_HOST environment variable in the phpmyadmin service, and the port is specified in the ports section of the db service. When you access PHPMyAdmin on port 8080, it will connect to the database service running on db:3306.

Docker Container Terminal

To get a terminal in the Docker Container you can run the following command. You will be the root user so you can do anything you want from the terminal within your container including adding or deleting Composer Packages.

# Get a terminal
docker exec -it lampstack-project-web-1 /bin/bash

# To get out of the terminal shell, type 
exit

When you're done, you can stop the containers using the following command:

docker-compose down