If you read my HomeKit articles, you will have seen that I use Docker to compile my code. Docker is operating-system-level virtualisation mainly intended for developers and sysadmins. Docker makes it easier to create and deploy applications in an isolated environment.

Dockerfile

A Dockerfile is a script that contains collections of commands and instructions that will be automatically executed in sequence in the docker environment for building a new docker image. In this blog, I will show you how to create your own Docker image with a Dockerfile. We will explain detail related to the Dockerfile to enable you to build your own Docker image.

 

Installing Prerequisites

Before we can install the software we need to install some software. Because I using a MacBook Pro with macOS 10.15.6 (Catalina) at this time of writing. I’m using Docker to install some docker files. You can also use Oracle Virtual Box and install Ubuntu, but this is a little more complicated, because you need to switch between the two OSes. For this guide, we will use the Ubuntu 20.04 with 1 GB of RAM, 25 GB free disk space, and 2 CPU’s. Also, we will use Ubuntu 20.04 as the base image to build the custom Docker image.

Download Docker

Okay let’s get started go to https://www.docker.com and press “Get Started” and press on “Download for Mac“. before you can download your free version you need to make an account. be sure to write it down because you will need it later. When you made your account you can login on the site and download your free version.

Docker Desktop for Mac

Docker Desktop for Mac is an easy-to-install desktop app for building, debugging, and testing Dockerized apps on a Mac. Docker Desktop for Mac is a complete development environment deeply integrated with the Mac OS Hypervisor framework, networking, and filesystem. Docker Desktop – Mac is the fastest and most reliable way to run Docker on a Mac.

System requirements

Your Mac must meet the following requirements to successfully install Docker Desktop:

  • Mac hardware must be a 2010 or a newer model, with Intel’s hardware support for memory management unit (MMU) virtualization, including Extended Page Tables (EPT) and Unrestricted Mode. You can check to see if your machine has this support by running the following command in a terminal: sysctl kern.hv_supportIf your Mac supports the Hypervisor framework, the command prints kern.hv_support: 1.
  • macOS must be version 10.13 or newer. That is, Catalina, Mojave, or High Sierra. We recommend upgrading to the latest version of macOS.If you experience any issues after upgrading your macOS to version 10.15, you must install the latest version of Docker Desktop to be compatible with this version of macOS.Note: Docker supports Docker Desktop on the most recent versions of macOS. That is, the current release of macOS and the previous two releases. Docker Desktop currently supports macOS Catalina, macOS Mojave, and macOS High Sierra.As new major versions of macOS are made generally available, Docker stops supporting the oldest version and support the newest version of macOS (in addition to the previous two releases).
  • At least 4 GB of RAM.
  • VirtualBox prior to version 4.3.30 must not be installed as it is not compatible with Docker Desktop.

Install and run Docker Desktop on Mac

  1. Double-click Docker.dmg to open the installer, then drag the Docker icon to the Applications folder.
  2. Double-click Docker.app in the Applications folder to start Docker. (In the example below, the Applications folder is in “grid” view mode.)The Docker menu in the top status bar indicates that Docker Desktop is running, and accessible from a terminal.If you’ve just installed the app, Docker Desktop launches the onboarding tutorial. The tutorial includes a simple exercise to build an example Docker image, run it as a container, push and save the image to Docker Hub.
  3. Click the Docker menu (whale menu) to see Preferences and other options.
  4. Select About Docker to verify that you have the latest version.

Congratulations! You are now successfully running Docker Desktop.

ATOM

Atom is a free and open-source text and source code editor for macOS, Linux, and Microsoft Windows with support for plug-ins written in Node.js, and embedded Git Control, developed by GitHub. Atom is a desktop application built using web technologies. Most of the extending packages have free software licenses and are community-built and maintained. You can download your free copy here.

Introduction to the Dockerfile Command

A Dockerfile is a script that contains all commands for building a Docker image. The Dockerfile contains all instructions that will be used to create the Docker image with the ‘docker build‘ command.

Before creating your first Dockerfile, you should familiar with the Dockerfile instruction. Below some Dockerfile instruction that you must know.

FROM
Set the base-image for the new image that you want to create. The FROM instruction will initialise the new build-stage and must be located at the top of the Dockerfile. With this instruction, you can add additional information about your Docker image, such as the version, description, maintainer, etc. The LABEL instruction is a key-value pair that allows you to add multiple labels and multi-line values.

RUN
This instruction used to execute command during the build process of the docker image. You can install additional packages needed for your Docker images.

ADD
The ADD instruction is used to copy files, directories, or remote files from URL to your Docker images, from the ‘src‘ to the absolute path ‘dest‘. Also, you can set up the default ownership of your file.

ENV
The ENV instruction is used to define an environment variable that can be used during the build stage and can be replaced inline in many as well.

CMD
The CMD instruction is used to define the default command to execute when running the container. And the Dockerfile must only contain one CMD instruction, and if there is multiple CMD, the last CMD instruction will be run.

EXPOSE
This instruction is used to expose the container port on the specific network ports at runtime. The default protocol exposed is TCP, but you can specify whether the TCP or UDP.

ARG
The ARG instruction is used to define a variable that the user can pass at the built-time. You can use this instruction in the docker ‘build command’ during the build time using the ‘–build-arg variable=value’ option and can be pass through the Dockerfile. Also, you can use multiple ARG at the Dockerfile.

ENTRYPOINT
The ENTRYPOINT instruction is used to define the first and default command that will be executed when the container is running. Define the command to start your application with the ENTRYPOINT instruction.Advertisement

WORKDIR
The WORKDIR instruction is used to define the default working directory of your Docker image. The RUN, CMD, ENTRYPOINT, and ADD instructions follow the WORKDIR instruction. You can add multiple WORKDIR instruction on your Dockerfile, and if there is doesn’t exist, it will be created automatically.

USER
The USER instruction is used to define the default user or gid when running the image. The RUN, CMD, and ENTRYPOINT follow the USER instruction in the Dockerfile.

VOLUME
The VOLUME instruction ad used to enable access/linked directory between the container and the host machine.

Now, let’s start to create the first Dockerfile.

Create Dockerfile and Other Configurations

In this step, we will show you how to build a custom Docker image for your application using the Dockerfile. We will create a new custom Docker image based on Ubuntu 20.04 image, for the PHP-FPM and Nginx services, then run the new container with a simple phpinfo script.

First, create a new project directory and create an empty Dockerfile. Open the Terminal app. Click the Finder icon in your dock. Click Go. Click Utilities. Double-click Terminal. Type mkdir Nginx-image and press Enter.

mkdir nginx-image


Change into the directory by typing cd nginx-image and press Enter.

cd nginx-image



Make a new file in atom called Dockerfile by typing atom dockerfile and press Enter. Now Atom will automatically make the file and open the Atom application.

atom dockerfile


Now edit the ‘Dockerfile‘ script using the Atom editor.

On the top of the line, add the base-image Ubuntu 20.04 image using the FROM instruction as below.

 

#Download base image ubuntu 20.04
FROM ubuntu:20.04

Now add detailed information about the custom image using the LABEL instruction.

# LABEL about the custom image
LABEL maintainer="[email protected]"
LABEL version="0.3.0"
LABEL description="This is custom Docker Image for \
the PHP-FPM and Nginx Services."

For the apt packages installation, we will skip any interactive post-install step using the environment variable ‘DEBIAN_FRONTEND=noninteractive‘.

# Disable Prompt During Packages Installation
ARG DEBIAN_FRONTEND=noninteractive

Next, run the ‘apt update‘ command before installing any packages.

# Update Ubuntu Software repository
RUN apt update

Now install the Nginx, PHP-FPM, and supervisor packages. Once all installation is completed, remove all packages cache to reduce the size of the custom image.

# Install nginx, php-fpm and supervisord from ubuntu repository
RUN apt install -y nginx php-fpm supervisor && \
    rm -rf /var/lib/apt/lists/* && \
    apt clean

Define a new environment variable that can be passed on the custom image.

#Define the ENV variable
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/7.4/fpm/php.ini
ENV nginx_conf /etc/nginx/nginx.conf
ENV supervisor_conf /etc/supervisor/supervisord.conf

Now copy the Nginx default configuration to the ‘nginx_vhost‘ variable, replace the PHP configuration ‘cgi.fix_pathinfo=1‘ with ‘cgi.fix_pathinfo=0‘ on the php.ini config file, then add the ‘daemon off‘ option to the default ‘nginx_conf‘ variable.

# Enable PHP-fpm on nginx virtualhost 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}

Copy the custom supervisor configuration to the ‘supervisor_conf‘ variable.

#Copy supervisor configuration
COPY supervisord.conf ${supervisor_conf}

Create a new directory for PHP-FPM sock file, change the ownership of the web-root directory ‘/var/www/html‘ and PHP-FPM directory ‘/run/php‘ to the default user ‘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 for the custom image so we can mount all of those directories to the host machine.

# Volume configuration
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]

Now add the ‘start.sh‘ script and define the default container command using the CMD instruction as below.

# Copy start.sh script and define default command for the container
COPY start.sh /start.sh
CMD ["./start.sh"]

And the last, open the default HTTP and HTTPS ports on the container using the EXPOSE instruction.

# Expose Port for the Application 
EXPOSE 80 443

Save and leave Atom open.

Below is the complete Dockerfile script that we just created.

# Download base image ubuntu 20.04
FROM ubuntu:20.04

# LABEL about the custom image
LABEL maintainer="[email protected]"
LABEL version="0.3.0"
LABEL description="This is custom Docker Image for \
the PHP-FPM and Nginx Services."

# Disable Prompt During Packages Installation
ARG DEBIAN_FRONTEND=noninteractive

# Update Ubuntu Software repository
RUN apt update

# Install nginx, php-fpm and supervisord from ubuntu repository
RUN apt install -y nginx php-fpm supervisor && \
    rm -rf /var/lib/apt/lists/* && \
    apt clean
    
# Define the ENV variable
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/7.4/fpm/php.ini
ENV nginx_conf /etc/nginx/nginx.conf
ENV supervisor_conf /etc/supervisor/supervisord.conf

# Enable PHP-fpm on nginx virtualhost 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}
    
# Copy supervisor configuration
COPY supervisord.conf ${supervisor_conf}

RUN mkdir -p /run/php && \
    chown -R www-data:www-data /var/www/html && \
    chown -R www-data:www-data /run/php
    
# Volume configuration
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]

# Copy start.sh script and define default command for the container
COPY start.sh /start.sh
CMD ["./start.sh"]

# Expose Port for the Application 
EXPOSE 80 443

 

 

Next, we will create a new additional configuration for Nginx, supervisor, and the start.sh script.

Nginx virtual host configuration file

The ‘default‘ Nginx virtual host configuration will contain the section for the PHP-FPM. In effect, you can run the PHP script using the Custom image without any changes.

 

Create a new Nginx file in atom called ‘default‘. This is a virtual host configuration file. Type atom default and press Enter. Now Atom will automatically make the file and open the Atom application.

atom default

Now edit the ‘Default‘ file using the Atom editor.

Paste the following configuration into it.

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.4-fpm.sock;
    }
}

 

Save and leave Atom open.

Supervisord.conf configuration file

Next, we will create the 'supervisord.conf' configuration which contains both Nginx and PHP-FPM program that will be running automatically.

Create a new file in atom called ‘supervisord.conf‘. This is a configuration file. Type atom supervisord.conf and press Enter. Now Atom will automatically make the file and open the Atom application.

atom supervisord.conf

Now edit the ‘supervisord.conf‘ file using the Atom editor.

Paste the following configuration into it.

[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             ;

[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
 
[include]
files = /etc/supervisor/conf.d/*.conf
 
[program:php-fpm7.4]
command=/usr/sbin/php-fpm7.4 -F
numprocs=1
autostart=true
autorestart=true
 
[program:nginx]
command=/usr/sbin/nginx
numprocs=1
autostart=true
autorestart=true

Save and leave Atom open.

Start.sh configuration file

Create a new file in atom called ‘start.sh‘. This is a configuration file. Type atom start.sh and press Enter. Now Atom will automatically make the file and open the Atom application.

atom start.sh

Now edit the ‘start.sh‘ file using the Atom editor.

Paste the following configuration into it.

#!/bin/sh
/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf

Save and closeAtom.

Set file permission

Now we have to set some file permissions to make the 'start.sh' script executable. First we have a look into our directory by typing ls.

ls


TIP: We can use the -l (long format) option to have ls list the file permissions for files and directories.


 

Here we see all the file we created. Now we can set the right permissions by typing chmod +x start.sh and press enter.

 

 

REFERENCE

Docker, Get started with docker (2020), Docker Desktop is a tool for MacOS and Windows machines for the building and sharing of containerized applications and microservices. , https://docker.com Muhammad Arul, How to forge (2020), How to create Docker Images with a Dockerfile on Ubuntu 20.04 LTS, https://www.howtoforge.com/tutorial/how-to-create-docker-images-with-dockerfile/ ubuntu, Ubuntu 20.04.1 LTS (2020), More ways to use Ubuntu everywhere , https://ubuntu.com/download/desktop Atom, A hackable text editor for the 21st Century (2020), IA text editor is at the core of a developer’s toolbox, but it doesn’t usually work alone. Work with Git and GitHub directly from Atom with the GitHub package., https://atom.io