Project Docker - squatchulator/Tech-Journal GitHub Wiki

Project: Docker

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.

Build Configuration

  • 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:

image

  • 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 the birthday.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. Edit apache.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 the Dockerfile 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 the php folder and add the following to the Dockerfile:
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. Edit init.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 with sudo docker-compose build and running docker-compose up -d. It will start your container, and at this point you should be able to visit http://<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 with mysql -u root -p and enter your password.
⚠️ **GitHub.com Fallback** ⚠️