With the Docker Compose utility we can create our own environment for web development.
We will be using two Dockerfiles created on previous posts:
For the web server: Apache and PHP
Docker Container: Centos 7, Apache, and PHP 7.3
For the database server: MySQL
Docker Container: MySQL 8
First, we create a file named docker-compose.yml.
On that file we will define two services "web" and "db"
version: "3.7"
services:
web:
build:
context: ./apache-php
dockerfile: Dockerfile
depends_on:
- db
ports:
- "4000:80"
volumes:
- ./www:/var/www
db:
build:
context: ./mysql
dockerfile: Dockerfile
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_ROOT_HOST=%
ports:
- "3306:3306"
volumes:
- ./data:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password
This is the Dockerfile for the web server.
FROM centos:7
# Install Apache
RUN yum -y update
RUN yum -y install httpd httpd-tools
# Install EPEL Repo
RUN rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \
&& rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-7.rpm
# Install PHP
RUN yum --enablerepo=remi-php73 -y install php php-bcmath php-cli php-common php-gd php-intl php-ldap php-mbstring \
php-mysqlnd php-pear php-soap php-xml php-xmlrpc php-zip
# Update Apache Configuration
RUN sed -E -i -e '/<Directory "\/var\/www\/html">/,/<\/Directory>/s/AllowOverride None/AllowOverride All/' /etc/httpd/conf/httpd.conf
RUN sed -E -i -e 's/DirectoryIndex (.*)$/DirectoryIndex index.php \1/g' /etc/httpd/conf/httpd.conf
EXPOSE 80
# Start Apache
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
This is the Dockerfile for the database server.
# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
FROM oraclelinux:7-slim
ARG MYSQL_SERVER_PACKAGE=mysql-community-server-minimal-8.0.19
ARG MYSQL_SHELL_PACKAGE=mysql-shell-8.0.19
# Install server
RUN yum install -y https://repo.mysql.com/mysql-community-minimal-release-el7.rpm \
https://repo.mysql.com/mysql-community-release-el7.rpm \
&& yum-config-manager --enable mysql80-server-minimal \
&& yum install -y \
$MYSQL_SERVER_PACKAGE \
$MYSQL_SHELL_PACKAGE \
libpwquality \
&& yum clean all \
&& mkdir /docker-entrypoint-initdb.d
VOLUME /var/lib/mysql
COPY docker-entrypoint.sh /entrypoint.sh
COPY healthcheck.sh /healthcheck.sh
RUN chmod +x /entrypoint.sh
RUN chmod +x /healthcheck.sh
ENTRYPOINT ["/entrypoint.sh"]
HEALTHCHECK CMD /healthcheck.sh
EXPOSE 3306 33060
CMD ["mysqld"]
You can download the above files, as well as additional files as a zip file here.
Uncompress the zipped file, and you will have the following folder structure and files:
apache-php7-mysql8/
├─ apache-php/
│ └─ Dockerfile
├─ data/
├─ docker-compose.yml
├─ mysql/
│ ├─ docker-entrypoint.sh
│ └─ Dockerfile
│ └─ healthcheck.sh
└─ www/
└─ html/
└─ test.php
Now we create the containers.
Open a terminal window, navigate to the folder with the
docker-compose.yml file, and type the following command.
docker-compose up -d
You will see an output similar to this one (excerpts):
Creating network "apache-php7-mysql8_default" with the default driver Building db Step 1/13 : FROM oraclelinux:7-slim 7-slim: Pulling from library/oraclelinux cd17e56c322c: Pull complete ... Removing intermediate container 3a6206494b46 ---> 4276c3affc43 Successfully built 4276c3affc43 Successfully tagged apache-php7-mysql8_db:latest WARNING: Image for service db was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. Building web Step 1/9 : FROM centos:7 7: Pulling from library/centos ab5ef0e58194: Pull complete ... Removing intermediate container 376c3114e934 ---> 2301a4fd609d Successfully built 2301a4fd609d Successfully tagged apache-php7-mysql8_web:latest WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. Creating apache-php7-mysql8_db_1 ... done Creating apache-php7-mysql8_web_1 ... done Creating network "apache-php7-mysql8_default" with the default driver
After the containers have finished building, we can check the logs with the following command:
docker-compose logs
Output (excerpts):
Attaching to apache-php7-mysql8_db_1, apache-php7-mysql8_web_1 db_1 | [Entrypoint] MySQL Docker Image 8.0.19-1.1.15 db_1 | [Entrypoint] Initializing database db_1 | 2020-04-05T04:36:37.316161Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.19) initializing of server in progress as process 21 web_1 | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.18.0.3. Set the 'ServerName' directive globally to suppress this message db_1 | 2020-04-05T04:36:38.448178Z 5 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option. db_1 | [Entrypoint] Database initialized ... db_1 | [Entrypoint] ignoring /docker-entrypoint-initdb.d/* db_1 | db_1 | 2020-04-05T04:36:42.919259Z 10 [System] [MY-013172] [Server] Received SHUTDOWN from user root. Shutting down mysqld (Version: 8.0.19). db_1 | 2020-04-05T04:36:44.266774Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.19) MySQL Community Server - GPL. db_1 | [Entrypoint] Server shut down db_1 | db_1 | [Entrypoint] MySQL init process done. Ready for start up. db_1 | db_1 | [Entrypoint] Starting MySQL 8.0.19-1.1.15 db_1 | 2020-04-05T04:36:45.142817Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.19) starting as process 1 db_1 | 2020-04-05T04:36:45.438910Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed. db_1 | 2020-04-05T04:36:45.454484Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.19' socket: '/var/lib/mysql/mysql.sock' port: 3306 MySQL Community Server - GPL. db_1 | 2020-04-05T04:36:45.611147Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 33060
To test that our web and database servers are working correctly there is included a test.php file that will try to make a connection to the database.
<?php
$host = 'db';
$user = 'root';
$pass = 'root';
$mysqli = new mysqli($host, $user, $pass);
if (!$mysqli->connect_error) {
echo 'Connection successful!';
} else {
echo 'Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error;
}
$mysqli->close();
?>
Open your web browser and go to the http://localhost:4000/test.php url.
You should see the following text:
Connection successful!
If the connection couldn't be made, an error message, indicating the reason, will be displayed instead.
After you have finished working with your containers you can stop them:
docker-compose stop
To re-start them, you would execute the docker-compose up -d specified above.
If you don't need the containers any more you can remove them:
docker-compose down
Check the docker-compose.yml and Dockerfiles on Github
here.