Connect with us


How to build a Docker cron job Container easily [2020]

Last Updated on

In this tutorial, we’ll be setting up Cron jobs in Docker and discuss how to avoid a common pitfall.

Let’s Code It!

We’ll build a docker cron job that runs while other services on docker are running. This is particularly useful if we want to backup our databases.

Setting things up

Directory structure.

Create a docker-cron root directory.

Container #1: Node

To start we’ll setup a node image that will act as a service that’s supposed to run while the cron job is running.

Generate a blank node app in docker-cron:

Create a Dockerfile in the node-app directory:

 Common Pitfall

Running cron in the same container as a service.

The Docker ubuntu image by default doesn’t run cron at runtime because it’s intended to run only one process at a time. Below is improperly attempting to run two processes simultaneously, something Docker doesn’t support:

The trick is splitting cron into its own separate container.

Container #2: Cron

We’ll setup an ubuntu image that will run our cron job in a separate container. This image doesn’t come with cron by default, so we’ll need to install it and do a general update. Create a cron-app directory in the docker-cron project folder.

Create mycron in cron-app that specifies your cron:

Make sure you have a blank line at the end of mycron

This cron will run every minute.

Create in cron-app that specifies what your cron does:

Create a Dockerfile in the cron-app directory with the following contents:

Docker Compose

Now we’ll bring the two images together with Docker Compose.

Create a docker-compose.yml file in the root docker-cron directory with the following contents:

Thank you for taking the time to read this tutorial. Check out our previous article about docker add vs copy. Also, Your feedback will be appreciated.

Continue Reading
Click to comment

Leave a Reply

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


How to create a private Docker registry without https, SSL

Last Updated on

In this article, we will create a Linux private docker registry without https, SSL. few months ago when I was trying to set up a private docker registry without https there was no proper guide on the internet, thas why I decided to create this guide.

So let’s start.

Install Docker

first of all, we have to install docker in a Linux box which we are going to use as the docker registry.

you can install docker using this command:

in centos 7,RedHat

in ubuntu

then start the docker service:

you can verify docker installation using this:

private Docker registry without https

Run Docker Registry Image

now we can install the docker registry in this Linux box. actually registry is just a docker container.

so let’s pull it from the docker hub and run. Please check below, for example, docker run command.

-p 5000:5000 –> this is the port mapping from your Linux box port 5000 to container port 5000.

–name linuxteacherregistry –>  you can give any name you want for this

-e REGISTRY_STORAGE_DELETE_ENABLED=true  –> This is an environment variable and will be valuable for you in the feature. we will discuss this later in this article.

registry:2 = docker registry image we are pulling from the docker hub.

private Docker registry without https

now run the above will download the registry image from the docker hub and create your docker registry within a minute. that’s the beauty of docker 🙂

you can verify it using:

docker ps or docker container list  (its the same command but docker ps is the old command.)

you can grep it by using the name you provided earlier.

Congratulations your docker registry is up and running 🙂

Access docker registry without https/SSL

now your private docker registry is running. you can access the docker registry using your Linux box IP or localhost.

But it’s hard to memorize the IP address when we access the docker registry from other Linux boxes.

so now we are going to give a name to the registry.

Let’s add an entry to /etc/hosts file in the servers.

NOTE: you have to add this entry to all /etc/hosts files on the servers which access this docker registry.

you can give any name you want. no need to be it a .com or valid domain.because our traffic is not going through the public internet.

so I’m giving “”.

private Docker registry without https = replace it with your Linux box IP which is used to run the Docker registry = replace with any name you want.

Push to the private registry

Now let’s try to push an image to our registry.

first of all download a sample image from the docker hub to test.

Tag It

then you have to tag the image with your private docker registry name and port.


replace the “” with your registry name.

now docker knows the part before “/” is the docker registry name. otherwise, docker will try to push to the docker hub and will get an error message like “unauthorized: authentication required”

Push it.

lets push the image to our registry.

wooh.. you will get an error like a bellow because of docker try to push the image using HTPPS.

Disable HTTPS error message

To avoid the above error, you have to create a daemon.json file or edit that file. file location is this:


then add bellow entry to it.

Replace the “” with your private docker registry name.

NOTE: you have to add the above entry to all your Linux boxes that access this docker registry.

Reload Docker daemon

After that, you have to restart or reload the Docker daemon. otherwise change will not be affected.

Now you can push to your docker registry without an issue using the above push command.

Congratulations!! you have successfully created a private docker registry without https 🙂

when I was creating my registry I had a bunch of questions in my head like,

how to view images in the registry or delete images from registry or view tags of an image?

I think you have some questions like above in your head. 🙂 

so let’s find the answers to the above questions from our next article.

Also, in the previous article, we discussed different between docker add vs copy vs volume. Give it a try 🙂

Continue Reading


Saltstack Tutorial for beginners [2020]

Last Updated on

What Is SaltStack?

 Salt (Salt-Stack) is an infrastructure automation and management system written in Python. You’ll see through this introduction that it is a powerful tool. Please note that this tutorial is for beginners.


Let’s begin by installing it. I am using a Debian based distro (Ubuntu, Linux Mint ..), for other distros please check the installation manual (for this part).

For this blog post, I am going to install Master and Minion in the same server (localhost).

Master is the server and Minion is the target.

We’re going for now to configure the (local) minion:

Search for master and tell it to use localhost or or even the default gateway

and restart the service :

Salt works with a system of keys, it can tells you which Minion was accepted/rejected. To list all the Minion keys your Master knows about, type :

If the host is rejected, add it using -a :

Check that the Minion responds:

the ‘*’ refers to all Minions whose key is accepted. You can specify instead, the FQDN of your minion.


We’re going, for now, some usage examples:

For Nginx (Installation of the server and starting its service):

For vim (Installation of vim)

You can even see all of your minion servers’ disk usage:

Or list network interfaces:

You can also execute a command

salt ‘*’ ‘ls -l /etc’

To list the documentation you can type


Salt comes with an interface to derive information about the underlying system. This is called the grains interface because it presents salt with grains of information.

The grains interface is made available to Salt modules and components so that the right salt minion commands are automatically available on the right systems.

Let’s view all grains our minions (*):

To list grains data:

As an example, if we want to match all CentOS and ping them, we can also use grains this way:

To list all minions with 64-bit CPUs, and return number of CPU cores for each matching one:

Adding new grains

Grains can also be assigned within the minion configuration file.

Open :

And search for “grains”

(As you can see, there is a list of grains like “deployment” that have the value mydatacenter. You can add your own grain. Make sure everything respects YAML language standards. )

or by adding the code below (without “grains:”) in


If your favorited language is Python, you have the habit of using dicts, you can use it also as a grain :

To query the last example :

Output format

Changing the output format is easy:

“–out” could be also one of the values listed here.


As troubleshooting is always part of learning, to debug the master or the minion you can use:

Let’s see what the port connectivity from the minion with the NC command.

(Remember that salt uses two ports, you can change them in master/minion configuration under /etc/salt/)

Debug with salt-call

We’re going to use salt-call with state.highstate if you’re not familiar with states, we’re going to explain them for later:

salt-call -l debug state.highstate

The verbose output could help you troubleshoot your problems. You only need patience.

Turn up logs

Salt can be quite chatty when you change the logging setting to debug:

Foreground run

By not starting the minion in daemon mode (-d) one can view any output from the minion as it works:

Increase the default timeout value when running salt. For example, to change the default timeout to 60 seconds:

Combine all:

Salt Authentification

We already spoke about keys but here is a reminder. We’re using two main functionality of salt-key command (on the master).

To list the keys that are on the master:

salt-key -L

The keys that have been rejected, accepted and pending acceptance are listed.

The easiest way to accept the minion key is to accept all pending keys:

Salt file roots

A base environment is required to house the top file.


you can add :

If you want to organize more as I did, you can create two subdirectories: states and pillars

and under each directory, you can create other subdirectories ( dev, integration, test, production ..etc).

In this blog post, I am going to speak about states, but not pillars. You can find good examples in the official documentation.

Salt States

If you consider working with salt, states are an important point to understand and it is not complicated.

As we already had configured “file_roots” which is “/srv/salt/”, we can move to the next simple example :


On the master, add the following code to

“base” is an environment and it’s our default one. You can define a list of minion that will be attached to that environment


In the last example, all hosts are concerned ( ‘*’ ), and the state webserver will be applied to them.

Minions can be matched by glob, PCRE regular expression, or by grains.

If we modify the last example and use “grains” matching instead of just writing “*”, you’ll have to modify your code like this :

os: Debian’ is the used grain to match host(s)

The last line tells Salt to use the sls called “webserver”.

Let’s keep the first example for the rest of this tutorial and continue to the second part (SLS).

Create our ‘sls’ file called ‘webserver.sls’. Write the next code to that file:

ID declaration is a random name but unique, in our example, it is the name of the package that should be installed on our minions.

When you type :

Salt will install the package defined in “webserver.sls” on your target minions defined in “top.sls” file

Let’s move to another interesting part of salt: How can we manage a configuration file on a distant machine? This will be the main subject of the next post.

Continue Reading


Docker ADD vs COPY vs VOLUME – [2020]

Last Updated on

Let’s Learn Docker ADD vs COPY vs VOLUME with Simple Examples :

We’ll learn in this tutorial the differences between Docker ADD vs COPY vs VOLUME when configuring Dockerfiles.

They all accomplish the same task (among other capabilities): moving files from the host computer to a Docker container.


VOLUME is different from COPY and ADD because it creates a mount point that the host operating system can interact with.

This command syncs the Docker container’s /var/www directory with the host OS’s cool-project directory. When any change is made to cool-project within the host OS it is immediately made available to the docker container mounting that directory and vice versa.

Docker ADD vs COPY

Using VOLUME is especially useful for development environments where frequent modifications to the code are being made. For example, running nodemon on a Docker container with a VOLUME allows you to make changes to your code that are immediately reflected as if Docker were invisible.


COPY accomplishes everything that VOLUME accomplishes, but does it during build time. This is necessary for configuring containers with modified config files with services such as httpd, Nginx, MongoDB, etc… For example when configuring an Nginx container modifying the nginx.conf file is an operation that must be done with COPY.

One setback to COPY is that it makes only the container that was copied to aware of the contents. Meaning we cannot access the contents on our host computer, or on other running docker containers, something VOLUME does.

Docker  COPY vs ADD


ADD is exactly the same as COPY except for one distinct difference. ADD can fetch content from a URL and it will not extract the content, only downloading to the specific location. Check the bellow example.

If the local content is recognized as compressed, will uncompress the contents. Check the bellow example.

It has the same setbacks that COPY has.

This is the Dockerfile we used for the above Examples.

What do I do?

I use Volumes by default whenever I can so that I don’t have to rebuild my Docker container every time there’s a modification to the code.

So this is the ending of the Docker ADD vs COPY vs VOLUME Article. we will appreciate your feedback and check out our new article about mail Command in Linux.

Continue Reading


Copyright © 2019