**Topic: OAI and M5G over Kubernetes**
> University: Bandung Institute of Technology
> Department: School of Electrical Engineering and Informatics (Telecommunication Engineering)
> Email: fandi.z.w@gmail.com [color=#ffa700]
# **<center><i ></i> Learn about Docker and How to Build a Docker image </center>**
Contents:
[TOC]
## **What is Docker?**
Docker is a tool designed to make it easier to create, deploy, and run applications by using containers. Containers allow a developer to package up an application with all of the parts it needs, such as libraries and other dependencies, and deploy it as one package.
### Understanding containers

Containers are an abstraction at the app layer that packages code and dependencies together. Multiple containers can run on the same machine and share the OS kernel with other containers, each running as isolated processes in user space. Containers take up less space than VMs (container images are typically tens of MBs in size), can handle more applications and require fewer VMs and Operating systems. Containers can be thought of as necessitating three categories of software:
* Builder: technology used to build a container.
* Engine: technology used to run a container.
* Orchestration: technology used to manage many containers.
## **Installing Docker**
Install the docker type command:
`sudo apt-get update`
`sudo apt-get install docker.io`


Start the docker service and enable it to start at boot time:
`systemctl start docker`
`systemctl enable docker`

## **Create Dockerfile**
Create a new directory for the dockerfile. Inside it, create a new and empty dockerfile. In this case /myimages is my new directory, and Dockerfile is a new empty file.
`mkdir ~/myimages`
`cd myimages/`
`touch Dockerfile`
Edit the `Dockerfile` with nano:
```nano=
#Download base image ubuntu 16.04
FROM ubuntu:16.04
#Update
RUN apt-get update
#Install Nginx, php-fpm and superfisord as a dependencies from ubuntu repository
RUN apt-get install -y nginx php7.0-fpm supervisor && \
rm -rf /var/lib/apt/lists/*
#Configuring those dependencies,
#Define the ENV variable
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/7.0/fpm/php.ini
ENV nginx_conf /etc/nginx/nginx.conf
ENV supervisor_conf /etc/supervisor/supervisord.conf
#Enable PHP-FPM on Nginx virtual host configuration
COPY default ${nginx_vhost}
RUN sed -i -e 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' ${php_conf} && \
echo "\ndaemon off;" >> ${nginx_conf}
#Configure Supervisord for Nginx and PHP-FPM
#Copy supervisor config
COPY supervisord.conf ${supervisor_conf}
#Create a new directory for php-fpm, changing /var/www/html owner directory and PHP directory to www-data
RUN mkdir -p /run/php && \
chown -R www-data:www-data /var/www/html && \
chown -R www-data:www-data /run/php
#Define the volume, so we can mount the directories listed to the host machine
#Volume config
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]
#Last but not least, setup the default container command CMD and open the port for HTTP and HTTPS.
#Creating a new start,sh file for default CMD command when container is starting. This file contains the supervisord command, and copy the file to the new image with the COPY docker command.
#Configure Services and Port
COPY start.sh /start.sh
CMD ["./start.sh"]
EXPOSE 80 443
```

Create a new configuration file for the virtual host named 'default' a supervisord configuration file 'supervisord.conf' and a service configuration script 'start.sh'.

Paste this config inside `default`:
```nano
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
```
This config inside `supervisord.conf`:
```nano
[unix_http_server]
file=/dev/shm/supervisor.sock ; (the path to the socket file)
[supervisord]
logfile=/var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
user=root ;
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///dev/shm/supervisor.sock ; use a unix:// URL for a unix socket
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /etc/supervisor/conf.d/*.conf
[program:php-fpm7.0]
command=/usr/sbin/php-fpm7.0 -F
numprocs=1
autostart=true
autorestart=true
[program:nginx]
command=/usr/sbin/nginx
numprocs=1
autostart=true
autorestart=true
```
Last, for start.sh:
```nano
#!/bin/sh
/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
```
Save and Exit.
Make start.sh executable:
chmod +x start.sh
## **Build New Docker Image and Create Container**
### Build a new docker image:
`sudo docker build -t nginx_image .`

### Create a new container
Before it, create a new directory in superuser mode:
`mkdir -p /webroot`
Run the new container:
```terminal
docker run -d -v /webroot:/var/www/html -p 80:80 --name container1 nginx_image
```
check container:
`docker ps`

## **Testing Nginx and PHP=FPM in the Container**
Create a new simple index.html in the /webroot directory with echo:
```terminal
echo '<h1>Hello World</h1>' > /webroot/index.html
```
to check ip address host:
Step 1: `docker ps`
Step 2: copy the container id
Step 3: `docker inspect <container_id>`
Step 4: find ipAddress: "n.n.n.n"
Step 5: testing with curl by accessing the host machine ip address: curl n.n.n.n or curl -I n.n.n.n


We can see the result of Hello world above.
Echo the phpinfo() to /webroot/info.php:

And last, check the browser with this url:
http://n.n.n.n/info.php
in my case n.n.n.n = 172.17.0.2/info.php

The new docker image 'nginx_image' has been successfully created, now we can create more containers based on that image.
## **Docker Architecture**
So, after we had installed Docker, actually we installed 2 kinds of docker.
1. Client
2. Server
We can check it by command:
`docker version`

There are 2 kinds of docker is currently running.