Containerized Apache, PHP and MariaDB development environment
Published on
There are at least a few cases when installing the full Apache, PHP and MariaDB is not a convenient option:
- developing a single project or just a few number of them
- testing a project with multiple versions of Apache, PHP and MariaDB
- having a HTTP server or a database configured for development running all the time may be a security issue
Quick start
Project structure
There are three directories:
scriptsfor initializing the databasedatabasefor the database fileswebfor all other files
The project will be available at http://localhost:8080
The containers
Download official containers:
podman pull docker.io/library/mariadb:latest
podman pull docker.io/library/php:8.1-apache
The pod
Create a pod with the official containers (you should change dbRoot to a stronger password):
podman pod create --name camp --publish 8080:80 --publish 3306:3306
podman run --detach --pod camp --name database \
--env MARIADB_ROOT_PASSWORD=dbRoot \
--volume "$PWD"/database:/var/lib/mysql:Z \
mariadb:latest
podman run --detach --pod camp --name webnphp \
--volume "$PWD"/web:/var/www/html:Z \
php:8.1-apache
Make sure pdo and pdo_mysql PHP modules are installed (php:8.1-apache does not have pdo_mysql installed by default). To add them, execute:
# install pdo_mysql then restart apache
podman exec webnphp /bin/bash -c 'docker-php-ext-install pdo pdo_mysql; apache2ctl restart'
# check installed PDO modules for PHP
podman exec webnphp /bin/bash -c 'php -m | grep -i pdo'
Alternatively, connect to the container with
podman exec -it webnphp /bin/bash
and install the missing module by running inside the container:
docker-php-ext-install pdo pdo_mysql
apache2ctl restart
php -m | grep -i pdo
exit
Note: you could check the installed PHP modules by running php -m or php -i inside the container.
Create the database
If you have a script to create your database, let’s say scripts/createDatabase.sql, you can use a container to create your database:
podman run -it --rm --pod camp \
--volume "$PWD"/scripts:/root/scripts:Z \
mariadb:latest mysql -h 127.0.0.1 --user="root" --password="dbRoot" --execute='source /root/scripts/createDatabase.sql'
Alternatively you can use a container to create the database:
podman run -it --rm --pod camp \
mariadb:latest mysql -h 127.0.0.1 -u root -p
by running your version of this createDatabase.sql script in mysql’s prompt:
create database MyTestDatabase;
grant all privileges on MyTestDatabase.* TO 'dbUser'@'localhost' identified by 'dbPass';
grant all privileges on MyTestDatabase.* TO 'dbUser'@'%' identified by 'dbPass';
flush privileges;
quit;
Initialize the database content
If you have a script to initialize your database, let’s say scripts/initializeDatabase.sql, you can use a container to initialize your database:
podman run -it --rm --pod camp \
--volume "$PWD"/scripts:/root/scripts:Z \
mariadb:latest mysql -h 127.0.0.1 \
--user='dbUser' \
--password='dbPass' \
--database='MyTestDatabase' \
--execute='source /root/scripts/initializeDatabase.sql'
Working with the database
To work with your database you can use a container with MySQL client started as dbUser:
podman run -it --rm --pod camp \
mariadb:latest mysql -h 127.0.0.1 -u dbUser -p
and manually input commands or you can launch a container with a bind mount to the scripts directory:
podman run -it --rm --pod camp \
--volume "$PWD"/scripts:/root/scripts:Z \
mariadb:latest mysql -h 127.0.0.1 \
--user='dbUser' \
--password='dbPass' \
--database='MyTestDatabase' \
and execute SQL scripts from that directory like:
source /root/scripts/initializeDatabase.sql
Utils
See the logs generated by those containers with:
podman logs webnphppodman logs database
To start, stop, restart or remove the pod use:
podman pod start camppodman pod stop camppodman pod restart camppodman pod rm camp
Short note about bind mount and SELinux labeling:
- use
:zwhen the volume will be used by multiple containers in parallel. - use
:Zto bind the volume only to one container. If you attach it to multiple containers only the last one will be able to access it.