Docker Hub Nginx Tutorial
In this tutorial we will see how to take advantage of Docker Hub to deal with Docker images, with an Nginx image, one of the most used web servers in the last times.
For this tutorial, Linux Mint 18 and Docker version 1.12.1 have been used.
You may skip Docker installation and jump directly to the beginning of the example below.
1. Installation
Note: Docker requires a 64-bit system with a kernel version equal or higher to 3.10.
We can install Docker simply via apt-get
, without the need of adding any repository, just installing the docker.io
package:
sudo apt-get update sudo apt-get install docker.io
For more details, you can follow the Install Docker on Ubuntu Tutorial.
2. Pulling the official image
Before anything, let’s pull the Nginx official Docker image from Docker Hub:
docker pull nginx
For the latest version. Or, for example, we could pull the stable version:
docker pull nginx:stable
You can check all the releases in the tags section.
3. Creating a repository in Docker Hub
We have to create a repository for our Nginx image. For that, we first need an account at Docker Hub.
Once registered, in the main page, we have to click the “Create repository” button. The only required field is the repository name, but it’s always a good practice to fill the description (Markdown is supported).
For this example, the repository I created is named my-nginx
. So, the complete repo name would be, in my case, julenpardo/my-nginx
.
4. Making some changes within the container
Let’s create a container from our image:
docker run -p 8080:80 --name=nginx1 -d nginx
We can check that it works accessing http://localhost:8080
from our browser.
Now, we have a running instance of the official Nginx image, so, it wouldn’t have much sense to have in our repo the same image as the one hosted by Nginx. So, let’s made some changes in our running container.
For making changes within our running container, first we need the interactive shell. For that, we have to execute the following:
docker exec -it nginx1 /bin/bash
We will install PHP-FPM for serve PHP applications with Nginx:
apt-get update apt-get install -y php5-fpm \ vim # We need a text editor; you can install your favorite
Now, we start the process:
/etc/init.d/php5-fpm start
We have to overwrite the configuration for the default site, placed in /etc/nginx/conf.d/default.conf
:
default.conf
server { listen 80; server_name localhost; root /usr/share/nginx/html; index index.html index.htm; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } location ~ \.php$ { fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name; include fastcgi_params; } }
Finally, we have reload Nginx:
service nginx reload
To test it, we can create a simple PHP script in /usr/share/nginx/html
:
phpinfo.php
<?php phpinfo();
5. Committing and pushing the changes made within the container
We have configured our running container to serve as PHP server. If we would remove it and create another container from the same image, the changes would be lost.
For preserving our running container, we can commit the changes made on it, and push it to the Docker Hub (like with Git and remote repositories). The syntax is the following:
docker commit <container-name|container-id> <repository>
So, in my case, would just be:
docker commit nginx1 julenpardo/my-nginx
Additionally, we can add messages to the commits, with the -m
(--message
) option, which is usually a good idea:
docker commit -m 'Nginx & PHP FPM' nginx1 julenpardo/my-nginx
If we check the existing images (executing docker images
), we will see that now we have a new image named julenpardo/my-nginx
. But, before pushing it to our repo, we need to login, just executing:
docker login
Introducing our Docker Hub credentials.
Now, we can push our image to the remote repository on Docker Hub executing:
docker push julenpardo/my-nginx # Remember to use your username
If now, we remove everything:
docker stop nginx1 docker rm nginx1 docker rmi nginx
And we pull and run our own image:
docker pull julenpardo/my-nginx docker run -p 8080:80 -d --name=my-nginx julenpardo/my-nginx
We can check that the new container created for our own image, is the same as the previous container, at the moment of the commit, with the same files and packages installed.
6. Using Dockerfiles hosted in GitHub
The recommended way to manage our images is using Dockerfiles, instead of making changes and committing them. For doing the same as before, we can create the following Dockerfile:
Dockerfile
FROM nginx MAINTAINER Julen Pardo <julen.pardo@outlook.es> ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update RUN apt-get install -y php5-fpm RUN /etc/init.d/php5-fpm start COPY files/default.conf /etc/nginx/conf.d/default.conf COPY files/phpinfo.php /usr/share/nginx/html/phpinfo.php
Note: we need a files
directory with the files used in the Dockerfile.
First of all, we have to link our Docker Hub account to the GitHub one, in “Settings/Linked Account & Services”. Docker has also to be authorized in GitHub, in “Integrations”.
After creating a GitHub repository and pushing the repo there, we have to go to “Settings/Integrations & services”, and add a Docker service.
Then, in Docker Hub, we have to create an automated build, from “Create/Create Automated Build”. A list of your repositories should appear; create one for hosting the Dockerfile and the other files.
Now, every time we make changes within the Dockerfile and push it to the remote GitHub repository, the image will be automatically built in Docker Hub. For example, if we would edit the Dockerfile to install, for example, UWSGI:
RUN apt-get install -y uwsgi
Commit the changes and push it to the GitHub repo, a build will start (you can check it in “Build Details” section in Docker Hub.
If we pull that image from the Docker Hub and create a container from it, we can check that UWSGI is installed on it!
7. Summary
This tutorial has shown how to use an Nginx Docker image combined with Docker Hub (actually applicable to any image), the cloud service for hosting Docker images, seeing both methods of making the changes directly within an existing container, and committing those changes; and using a Dockerfile managed under Git, and automating the builds in the Docker Hub.