In my previous post about using Docker and scripts to build static versions of your website, I used a very basic project that didn't use a database. A few of the projects I was restoring needed MySQL, so this post outlines the steps I took to make sure these websites worked correctly.
Updating the Dockerfile
Firstly, I needed to modify the Dockerfile
, to install the required MySQL extensions.
FROM php:5.6-apache as project_name
RUN a2enmod rewrite
RUN apt-get update \
&& docker-php-ext-install pdo pdo_mysql mysql mysqli
COPY ./ /var/www/html/
EXPOSE 80
Adding the MySQL Container
The docker-compose.yaml
has the biggest change. We need to add another service for MySQL and create a network so the two containers can talk to each other.
We can use the official MySQL image without the need for a specific Dockerfile
. Instead of the build
configuration, we specify the image
, in this case, MySQL 5.7.
Next, we configure the local port which is mapped to the default 3306 internal MySQL port. If you want to connect to the database from your local machine, you should use this port, but internally, the containers will talk using the default port.
We can configure the local port and database credentials using an .env
file.
When starting the MySQL container, it maps the storage engine to the .db
directory in your project root. This means the database data is maintained between sessions and is not lost if you recreate the container. Secondly, it copies a database.sql
file to the entry point initialise script – this runs the SQL file when building the container and is perfect to preload the database with the backup data you have.
version: "3.7"
services:
website:
build:
context: .
dockerfile: Dockerfile
image: project_name:latest
container_name: project_name
ports:
- '${FORWARD_APP_PORT:-8000}:80'
volumes:
- ./:/var/www/html
networks:
- project_name_network
mysql:
image: 'mysql:5.7'
container_name: project_name_mysql
ports:
- '${FORWARD_DB_PORT:-3307}:3306'
env_file:
- ./.env
environment:
MYSQL_DATABASE: '${DB_DATABASE:-database}'
MYSQL_USER: '${DB_USER:-username}'
MYSQL_PASSWORD: '${DB_PASSWORD:-password}'
MYSQL_ROOT_PASSWORD: ''
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
command:
- --default-authentication-plugin=mysql_native_password
- --sql_mode=
volumes:
- ./.db:/var/lib/mysql
- ./database.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD", "mysqladmin", "ping"]
restart: 'unless-stopped'
networks:
- project_name_network
networks:
project_name_network:
driver: bridge
Note if you're using Apple Silicon computer then you may need to define the MySQL platform to use x86
. You can do this by adding the following under the image setting.
image: 'mysql:5.7'
platform: linux/x86_64
You will need to configure your code with the correct MySQL credentials. This should use the internal name of the host, in the case above, it would be mysql
.
define('DB_HOST', 'mysql');
define('DB_NAME', 'database');
define('DB_USER', 'username');
define('DB_PASSWORD', 'password');
Finally, the stop
and remove
helper scripts that I define in the package.json
need the MySQL container added:
"stop": "docker stop project_name project_name_mysql",
"remove": "docker rm project_name project_name_mysql",
And that's it. Now you can use the build
and deploy
scripts to generate a static HTML version of your database-driven PHP website. This also works perfectly well for WordPress websites.