Project Docker - squatchulator/Tech-Journal GitHub Wiki
Credit to this website for help on structure configurations for build.
- This project involves us building and demonstrating our own docker compose configuration to deploy a container that uses both a web component and some sort of backend database component. Within the past few weeks, I worked in SEC-440 on a PHP/HTML server that uses redundant databases to perform lookups and add new entries, and I figured it would be fun to use that same application and containerize it! This is based on a modified version of a sample script given to us in SEC-440 that does a lookup on the 'pets' database with the 'cats' table, and I modified it to show the server it's running on, the backend database server it's using, as well as adding new entries to the database.
- Since these VMs that we are using for class are provisioned with very little resources and Elasticsearch needs at minimum 2gb of RAM to run, I am going to be using my own VMs - the instructions detailed below should remain the same.
- Follow the setup commands listed in this lab, all the way down to the Containerized Wordpress section.
- Create a new directory under your home directory. It can be named anything as long as you remember what it is. I just named mine server - it should have a directory structure similar to the following:
- You should only need to edit these files to get this project working. First, lets mess around with docker-compose.yml. Add the following to the file:
version: "3.2"
services:
php:
build: './php/'
networks:
- backend
volumes:
- ./public_html/:/var/www/html/
apache:
build: './apache/'
depends_on:
- php
- mysql
networks:
- frontend
- backend
ports:
- "8080:80"
volumes:
- ./public_html/:/var/www/html/
mysql:
image: mysql:5.6.40
networks:
- backend
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: pets
MYSQL_INITDB: /docker-entrypoint-initdb.d/
volumes:
- ./mysql-init-scripts:/docker-entrypoint-initdb.d
- dbdata:/var/lib/mysql
networks:
frontend:
backend:
volumes:
mysql-init-scripts:
driver: local
dbdata:
-
This will spin up an Apache web server with PHP running using files located in the
./php-files
directory, and will temporarily store them in the/var/www/html
directory where they would normally be. It also starts up a temporary database instance using the credentials you fill out here, and you can change the database name but since this is pet-related I recommend keeping it the same. -
Now, head into the
public_html
folder and edit thebirthday.html
file. Add the following:
<html>
<body>
<form action="birthday.php" method="post">
Currently running web interface on: (web server name here) </br>
Look up your cat's birthday! </br>
Cats Name: <input type="text" name="name"></br>
<input type="Submit">
</form>
<form action="add_cat.php" method="post">
Add a new cat:</br>
Cat's Name: <input type="text" name="new_name"></br>
Owner's Name: <input type="text" name="new_owner"></br>
Cat's Birthday (YYYY-MM-DD): <input type="text" name="new_birth"></br>
<input type="Submit" value="Add Cat">
</form>
</body>
</html>
-
This will be our web interface. It will have 2 forms; one to perform a lookup in our pet database for cats matching the name the use enters in the web form, and the second form will allow the user to add a new entry to the cats table in our pets database.
-
Now to edit the
birthday.php
file:
<?php
$username = "root";
$password = "password";
$database = "pets";
$name = $_POST['name'];
$mysqli=new mysqli('mysql', $username, $password, $database);
if ($mysqli->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$query = "SELECT * from cats where name='".$name."'";
$result = $mysqli->query($query) or die($mysqli->error.__LINE__);
$hostnameQuery = "SELECT @@hostname";
$hostnameResult = $mysqli->query($hostnameQuery);
$hostnameRow = $hostnameResult->fetch_assoc();
$hostname = $hostnameRow['@@hostname'];
if ($result->num_rows > 0) {
while ($row=$result->fetch_assoc()) {
echo "Database server currently in use: " . $hostname . "</br>";
echo $row['name']."'s birthday is ".$row['birth']."</br>";
}
}
else {
echo 'NO RESULTS';
}
?>
- This file is what the lookup part of our website will use. It's designed specifically to pass our name entry through as an SQL query and to return information in our table associated with that specific cat's name.
- Finally, we need to edit our
add_cat.php
file:
<?php
$username = "root";
$password = "password";
$database = "pets";
$newName = $_POST['new_name'];
$newOwner= $_POST['new_owner'];
$newBirth= $_POST['new_birth'];
$mysqli = new mysqli('mysql', $username, $password, $database);
$query = "INSERT INTO cats (name, owner, birth) VALUES ('$newName', '$newOwner', '$newBirth')";
$mysqli->query($query) or die($mysqli->error.__LINE__);
$mysqli->close();
header("Location: birthday.html");
exit();
?>
- This one is what handles entering a new cat into the table. It takes 3 parameters, the name, owner, and birthday of the cat, and adds them as a new row in our cats table. Once it executes, the two lines at the bottom tell it to redirect back to the original
birthday.html
page. You should be able to perform a lookup right after adding it! - Back out of that directory and head to the
apache
folder. Editapache.conf
with the following:
ServerName localhost
LoadModule deflate_module /usr/local/apache2/modules/mod_deflate.so
LoadModule proxy_module /usr/local/apache2/modules/mod_proxy.so
LoadModule proxy_fcgi_module /usr/local/apache2/modules/mod_proxy_fcgi.so
<VirtualHost *:80>
# Proxy .php requests to port 9000 of the php-fpm container
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/html/$1
DocumentRoot /var/www/html/
<Directory /var/www/html/>
DirectoryIndex index.php
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Send apache logs to stdout and stderr
CustomLog /proc/self/fd/1 common
ErrorLog /proc/self/fd/2
</VirtualHost>
- This is a demo conf file for our apache configuration, pulled from this guide. General configuration stuff to let things work how we want them too.
- While we are in this
apache
directory, edit theDockerfile
in here too:
FROM httpd:2.4.33-alpine
RUN apk update; \
apk upgrade;
# Copy apache vhost file to proxy php requests to php-fpm container
COPY apache.conf /usr/local/apache2/conf/apache.conf
RUN echo "Include /usr/local/apache2/conf/apache.conf" \
>> /usr/local/apache2/conf/httpd.conf
- This will let us start up our Apache container with minimal setup and will put our conf file in the right place.
- Now we can back out of the
apache
folder. Head into thephp
folder and add the following to theDockerfile
:
FROM php:7.2.7-fpm-alpine3.7
RUN apk update; \
apk upgrade;
RUN docker-php-ext-install mysqli
- This will get us set up with the MySQLi extension for PHP.
- Back out of this directory and finally, head into the
mysql-init-scripts
folder. Editinit.sql
with the following:
USE pets;
CREATE TABLE cats
(
id INT unsigned NOT NULL AUTO_INCREMENT, # Unique ID for the record
name VARCHAR(150) NOT NULL, # Name of the cat
owner VARCHAR(150) NOT NULL, # Owner of the cat
birth DATE NOT NULL, # Birthday of the cat
PRIMARY KEY (id) # Make the id the primary key
);
INSERT INTO cats ( name, owner, birth) VALUES
( 'Siggy', 'Harold', '2018-01-05' ),
( 'Freya', 'Gutenberg', '2017-11-10' ),
( 'Patches', 'Charlie', '2015-05-15' );
- This gives us a baseline database image to work with. It has some rows populated in the 'cats' table so that we can go ahead and start adding and looking up entries right away on startup.
- Now, it should be as easy as navigating to the directory your
docekr-compose.yml
file is located, building it withsudo docker-compose build
and runningdocker-compose up -d
. It will start your container, and at this point you should be able to visithttp://<your server ip>:8080/birthday.html
to view and use your website! - If you need to go into your MySQL server to manually add or adjust entries, you can run
sudo docker exec -it server_mysql_1 sh
and log into your database withmysql -u root -p
and enter your password.