Intro to Docker and Docker compose

we will use docker containers to manage the different services. Here is an example of a http server container and an api server container, that we will use as an example for two containers built to communicate with each other, open a port to the host and automate the start up including the build and shutdown processes.

what is docker anyway? Here is a list of basic commands to get started

docker pull ubuntu
docker container ls -a
docker ps
docker ps -aq
docker rm container
docker rmi image
docker images
docker create --name nameit nginx
docker attach nameit
docker start nameit
docker run -it --name nameit nginx
docker run -d -p 8080:80 --name nameit2 -v nginx
docker exec -it nameit2 bash

For setting up our docker server container, using a http_server.Docker file:

# this container is based on ubuntu:18.04 image
FROM ubuntu:20.04
# run some commands as root to install needed packages               
RUN apt-get update -y
RUN apt-get install -y nano
RUN apt-get install -y python3.8
RUN apt-get install -y sudo
# create user with temp pw, add him to group and delete tmp pw
RUN useradd p_server_user -p 'temporary' -u 1001 -m
RUN passwd -d p_server_user
RUN usermod -aG sudo p_server_user
# from here on we run commands as the user
USER p_server_user
# set some env variables
WORKDIR /home/p_server_user/src
ENV PORT=8888
# expose port to host
EXPOSE 8888

now to automate the process of building and starting the server container with a shell script

#!/bin/bash
docker build \
--file=http_server.Dockerfile \
--tag="http_server:0.1" \
.

docker create \
--interactive \
--tty \
--rm \
--name=http_server\
--publish-all \
--mount type=bind,source="$(pwd)/src",target=/home/p_server_user/src \
--workdir /home/p_server_user/src \
server_container:0.1

docker start http_server
docker port http_server
docker attach http_server

don’t forget to make it executable

sudo chmod +x server_builder.sh
./server_builder.sh

Now we will make the same for the node.js api server that the http container will communicate with, this is the api_server.Dockerfile:

# this container is based on node:12.18-slim image
FROM node:12.18-slim
# run some commands as root to install needed packages
RUN apt-get update -y
RUN apt-get install -y nano
RUN apt-get install -y sudo
# add default container user to group and delete default pw
RUN passwd -d node
RUN usermod -aG sudo -u 1001 node
# from here on we run commands as the user
USER node
# set some env variables
WORKDIR /home/node/src
# node container launches into nodejs env, we want it to start into shell, this forward this comman
CMD ["/bin/bash"]
ENV PORT=12345
# expose port to host
EXPOSE 12345

then the deployment shell script

#!/bin/bash
docker build \
--file=api_server.Dockerfile \
--tag="api_server:0.1" \
.

docker create \
--interactive \
--tty \
--rm \
--name=api_server \
--publish-all \
--mount type=bind,source="$(pwd)/src",target=/home/node/src \
--workdir /home/node/src \
api_server:0.1

docker start api_server
docker port api_server
docker attach api_server

We will create a simple express.js function on the api server as a backend for the http server. For that we will need to install express, and initiate npm with our service:

npm init # give it a name like api_server
npm install express

then let’s create our service, e.g. api_server.js:

#!/usr/local/bin/node

var express = require('express');
var app = express();

app.listen(process.env.PORT);

app.get(
 '/person',
 function (req, res) {
  res.json({
   name: 'Tom',
   surname: 'Jerry'
  })
 }
);

Now we can let docker compose take care of handling the set up of these containers and especially the communication between them. For that we will create our composer config file docker-compose.yml

version: '3'

services:
        api:
                image: api_server:0.1
                container_name: api_server
                build:
                        context: ./api_server
                        dockerfile: api_server.Dockerfile
                command: /home/node/src/api_server.js
                volumes:
                        - ./api_server/src:/home/node/src
                              

        web:
                image: http_server:0.1
                container_name: http_server
                build:
                        context: ./http_server
                        dockerfile: http_server.Dockerfile
                command: /home/http_server_user/src/http_server.py
                volumes:
                        - ./http_server/src:/home/http_server_user/src
                ports:
                        - 8080:8888
                environment:
                        - API_SERVER_URL=http://api:12345

once we run docker-compose, we will have the http server available on localhost:8080, the api server will not be reachable from outside the container, except for http server. Now let’s create the start.sh scripts:

#!/bin/bash

docker-compose up -d --build
docker port http_server

and respectively the stop.sh script, don’t forget to make them executable!

#!/bin/bash
docker-compose down

Leave a comment

Your email address will not be published. Required fields are marked *