Docker Compose

Getting Started

We'll create 3 services at once with docker composer.
We need one API server and two web servers to show data from API.

  • API Server with Node
  • Web Server with PHP
  • Web Server with node
  • docker-compose.yml

Set Up Project

mkdir simple-compose && cd simple-compose
mkdir api-node && mkdir website-php && mkdir website-node
touch docker-compose.yml

1. Create an API Server with Node

# Curent Path: simple-compose/
cd api-node && npm init -y && npm i express && touch app.js && touch Dockerfile

app.js:

const express = require("express");
const app = express();
const PORT = 80;

// For allowing request from the Node Web Server
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

app.get("/", (req, res) => {
  res.send({ items: ["Chocolate", "Shooting Star", "Mother is an alien"] });
});

app.listen(PORT, () => {
  console.log(`GODORI API SERVER IS RUNNING`);
});

dockerfile:

FROM node:alpine
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
CMD node app.js
EXPOSE 3000

test:

docker build --tag=godori-api .
docker run -p 3000:80 godori-api
# oepn http://localhost:3000 on the browser

2. Create a Web Server with PHP

# Curent Path: simple-compose/
cd website-php && touch index.php

index.php:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
</head>
<body>
    <p>ICECREAM MENU</p>
    <ul>
    <?php
        $json = file_get_contents('http://api-node/');
        $obj = json_decode($json);
        $items = $obj->items;
        foreach ($items as $item) {
            echo "<li>$item</li>";
        }
    ?>
    </ul>
</body>
</html>

3. Create a Web Server with Node

# Curent Path: simple-compose/
cd website-node && npm init -y && npm i express 
touch app.js && touch index.html && touch Dockerfile

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Document</title>
  </head>
  <body>
    <input type="button" onclick="getIcecream();" value="GET ICECREAM" />
    <ul id="flavor"></ul>
  </body>
  <script>
    const outside_url = "http://localhost:3000";

    const getIcecream = () => {
      fetch(outside_url)
        .then(res => {
          if (res.ok) {
            res.json().then(data => {
              const ul = document.getElementById("flavor");
              data["items"].forEach(item => {
                let li = document.createElement("LI");
                let text = document.createTextNode(item);
                li.appendChild(text);
                ul.appendChild(li);
              });
            });
          }
        })
        .catch(err => {
          console.log(err);
        });
    };
  </script>
</html>

app.js:

const express = require("express");
const app = express();
const path = require("path");
const PORT = 80;

app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname + "/index.html"));
});

app.listen(PORT);

Dockerfile:

FROM node:alpine
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
CMD node app.js
EXPOSE 5000

4. Write the docker-compose.yml

docker-compose:

version: "3"  # Version of YAML file format 

services:
  api-node:                # Service 1: API Server
    build: ./api-node      # Build image from api-node directory
    volumes:               # For executing live code change
      - ./api-node:/app
    ports:                 # Expose host port 3000
      - 3000:80           

  website-php:             # Service 2: PHP Web Site
    image: php:apache      # Build image from php:apache
    volumes:
      - ./website-php:/var/www/html
    ports:
      - 4000:80
    depends_on:            # Run after api-node service
      - api-node

  website-node:            # service 3: Node Web Site
    build: ./website-node  # Build image from website-node directory
    volumes:
      - ./website-node:/app
    ports:
      - 5000:80
    depends_on:
      - api-node

5. Run Docker Composer!

# Curent Path: simple-compose/
docker-compose up

image.png

  • PHP Server is running on http://localhost:4000
    image.png

  • Node Server is running on http://localhost:5000
    แ„‡แ…ฎแ‡€แ„‹แ…งแ„‚แ…ฅแ‡‚แ„‹แ…ณแ†ซ_แ„‹แ…ตแ„†แ…ตแ„Œแ…ต_2019__4__28__แ„‹แ…ฉแ„’แ…ฎ_11_42.png
    If you Click the button, it will fetch data through an external API server.

    // index.html in website-node dir
    const outside_url = "http://localhost:3000";

Reference