Install and Configure Docker
Install pre-requisites.
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
Set up the stable respository.
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
Returns.
adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
grabbing file https://download.docker.com/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
Install the latest version of Docker Community Edition (CE) and containerd.
sudo yum install docker-ce docker-ce-cli containerd.io
Start Docker.
sudo systemctl start docker
Enable Docker to start at bootup.
systemctl enable docker
Returns.
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
Verify that Docker CE is installed correctly by running the hello-world image.
sudo docker run hello-world
Returns.
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:41a65640635299bab090f783209c1e3a3f11934cf7756b09cb2f1e02147c6ed8
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
Create the docker group.
sudo groupadd docker
Add current user to the docker group.
sudo usermod -aG docker $USER
For this change to take effect you will need to logoff and log back into the VM. In some cases you may need to restart the VM.
az vm restart --resource-group Py4SAS --name Py4SAS-vm
Configure Docker to start on boot.
sudo systemctl enable docker
Returns:
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
Fetch local Docker images.
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 5 months ago 1.84kB
Build Docker Image
Create a Docker container using a redis in-memory database to count web visitors along with flask as a Python-based web development framework.
Create new directory.
mkdir $HOME/docker-test
cd $HOME/docker-test
Create the app.py script.
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
The script needs the Flask and Redis libraries. Create the requirements.txt file to make these libraries available inside the Docker container.
Flask
Redis
To create a Docker container create a text file called Dockerfile.
# Use an official Python runtime as a parent image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
Build the Docker image with the build sub-command and give it the tag first_container.
docker build -t first_container .
Truncated output.
Successfully built 96f924107cbf
Successfully tagged first_container:latest
Verify the Docker image is built.
docker images
Returns.
REPOSITORY TAG IMAGE ID CREATED SIZE
first_container latest 96f924107cbf About a minute ago 131MB
python 2.7-slim ca96bab3e2aa 2 weeks ago 120MB
hello-world latest fce289e99eb9 5 months ago 1.84kB
Open port 8000.
az vm open-port --priority 1002 --resource-group Py4SAS --name Py4SAS-vm --port 8000
Run the Container
Run the app inside the container.
docker run -p 8000:80 first_container
Returns:
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
The ps sub-command shows the running container.
docker ps
Returns.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4ee5209e8094 first_container "python app.py" 2 minutes ago Up 2 minutes 0.0.0.0:8000->80/tcp agitated_curie
Load the page on port 8000.
Stop the container.
docker stop 4ee5209e8094
Returns.
4ee5209e8094
Docker Commands
Show running containers.
docker ps -a
Force a container to remain running.
docker run -d -p 38080:38080 containerID tail -f /dev/null
Remove all stopped containers.
docker rm $(docker ps -q -f status=exited)
Docker Compose
For complex applications with a lot of components, orchestrating all the containers to start up and shut down together and communications can quickly become unwieldy. Docker Compose makes it easier for users to orchestrate the processes of Docker containers including start up, shut down, and setting up intra-container linking and volumes.
Download Doker Compose.
sudo curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
Returns.
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 617 0 617 0 0 1799 0 --:--:-- --:--:-- --:--:-- 1798
100 15.4M 100 15.4M 0 0 25.5M 0 --:--:-- --:--:-- --:--:-- 25.5M
Make the file executable.
sudo chmod +x /usr/local/bin/docker-compose
Validate Docker compose.
docker-compose --version
Returns.
docker-compose version 1.24.1, build 4667896b
Test a deployment by creating the hello-world
directory and creating the docker-compose.yml
file.
mkdir ~/hello-world && \
cd ~/hello-world
Create the docker-compose.yml
file.
vi docker-compose.yml
Adding.
az-test:
image: hello-world
Where az-test
names the container and the image pulled is hello-world
.
Build-up the container.
docker-compose up
Returns.
Pulling az-test (hello-world:)...
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:6540fc08ee6e6b7b63468dc3317e3303aae178cb8a45ed3123180328bcc1d20f
Status: Downloaded newer image for hello-world:latest
Creating hello-world_az-test_1 ... done
Attaching to hello-world_az-test_1
. . .
hello-world_az-test_1 exited with code 0
To list a group of Docker containers (both stopped and running), use the following command:
docker-compose ps -a
Returns.
Name Command State Ports
------------------------------------------------
hello-world_az-test_1 /hello Exit 0