Hands dirty with Docker
To install the docker machine in the AWS:
#for the default docker
docker-machine create --driver amazonec2 aws01
#for the custom centos
docker-machine create --driver amazonec2 --amazonc2-region ap-southeast-2 --amazonec2-ami ami-0c2aba6c -amazonec2-ssh-user ojitha aws-demo
If you run the above default (in the N. virginia region), here the way to set the env
~ docker-machine env aws01
#output is :
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://54.173.183.175:2376"
export DOCKER_CERT_PATH="/Users/ojitha/.docker/machine/machines/aws01"
export DOCKER_MACHINE_NAME="aws01"
# Run this command to configure your shell:
# eval $(docker-machine env aws01)
#for the custom
#eval $(docker-machine env aws-demo)
For example, to run a simplest docker container
~ docker run --name hello-A dockerinaction/hello_world
Unable to find image 'dockerinaction/hello_world:latest' locally
latest: Pulling from dockerinaction/hello_world
a3ed95caeb02: Pull complete
1db09adb5ddd: Pull complete
Digest: sha256:cfebf86139a3b21797765a3960e13dee000bcf332be0be529858fca840c00d7f
Status: Downloaded newer image for dockerinaction/hello_world:latest
hello world
As shown in the above shell output, you can this container has been downloaded from the docker registry.
To display the docker containers at active
~ docker ps -a
Here the output of the command:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
43e0288e9b09 dockerinaction/hello_world "echo 'hello world'" 5 minutes ago Exited (0) 5 minutes ago hello-A
63e8f6440a22 amazonlinux:latest "/bin/bash" 12 months ago Exited (137) 12 months ago suspicious_stonebraker
8ae7c51a90fe microsoft/mssql-server-linux "/bin/sh -c /opt/mss…" 12 months ago Exited (137) 12 months ago hopeful_volhard
As you see all the containers are stoped, otherwise you can use the following command to stop the container
docker stop hello-A
For example install nginx server
docker run --detach --name web nginx:latest
Here detach will take the process to foreground: this process will not exist until use of the root process to exist using --rm
option.
You can list all the local docker images
~ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest ae513a47849c 5 days ago 109MB
lambci/lambda python2.7 64cb3bf41370 7 months ago 965MB
microsoft/mssql-server-linux latest 7b1c26822d97 12 months ago 1.35GB
amazonlinux latest 766ebb052d4f 13 months ago 162MB
dockerinaction/hello_world latest a1a9a5ed65e9 2 years ago 2.43MB
To show images repository, tag and image id:
docker image ls [<image>]
You can create your own docker container using Dockerfile, and running the following command:
docker build -t <image name>
to start
docker run --name <container name> <image name>
To remove unnecessary containers
docker system prune
Networking
Docker runs internal DNS server at 127.0.0.11 which is accessible. There are three types for networking
* None
* bridge (default): connect to the host via bridge
* Host : Directly connect to the host
Bridge is the preferred way to connect containers. Containers in the separate networks are isolated, but can connect to as many networks required. Docker container is discoverable via Docker DNS:. But DNS is not available in the default bridge.
To create the user define bridge networks, frontend, backend
docker network create --driver bridge frontend
docker network create --driver bridge backend
To find all the available networks, run
docker network ls
for example create two containers as follows:
docker container run -it --network=frontend -d --name=front-1 busybox:latest
docker container run -it --network=backend -d --name=backend-1 busybox:latest
Now if you create 3rd container without -d to interact and ping from there,
~ docker container run -it --network=backend --name=backend-test busybox:latest
/ # ping -c 2 front-1
ping: bad address 'front-1'
/ # ping -c 2 backend-1
PING backend-1 (172.22.0.2): 56 data bytes
64 bytes from 172.22.0.2: seq=0 ttl=64 time=0.132 ms
64 bytes from 172.22.0.2: seq=1 ttl=64 time=0.139 ms
--- backend-1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.132/0.135/0.139 ms
/ #
As shown in the above example, you can only ping the back end network connections.
Now we can connect the backend-test container to frontend network as follows
docker network connect frontend backend-test
Now if you ping the front-1 container connection
docker attach backend-test
/ # ping -c 2 front-1
PING front-1 (172.21.0.2): 56 data bytes
64 bytes from 172.21.0.2: seq=0 ttl=64 time=0.123 ms
64 bytes from 172.21.0.2: seq=1 ttl=64 time=0.212 ms
--- front-1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.123/0.167/0.212 ms
/ #
This has been explained in the following diagram:

Docker originally comes with —link
to connect containers. This is actually creates environment variables within the container with the IP address to connect. This is not longer recommended.
Dockerfile
Every docker project is depends on its Dockerfile.: specification need to build the Docker image. This file should be in the base directory. Each instruction in the specification create a new layer.
Here the way to create simple image which shows how to copy a file. Here the Dockerfile
FROM debian:stretch
COPY test.txt /data/test.txt
In the same directory run the following command. Don't forget the last .
for the current directory.
docker build -t file-copy .
Now run the container
docker run --rm -it file-copy
root@fe5ba852cb54:/# ls data
test.txt
root@fe5ba852cb54:/#
To copy the directory for example test directory to data directory
FROM debian:stretch
COPY test /data/
for example to copy zip file the Dockerfile is
FROM debian:stretch
ADD test.txt.gz /data/
Now create a image
docker build -t zip-copy .
Now create a container and lis the contents in the data directory,
docker run --rm -it zip-copy ls -R /data
/data:
test.txt.gz
Use the RUN
to execute shell script for example in the unix
RUN /bin/bash -c “set -o pipefail && wget -0 – http://<web site> | wc -l”
Run is the best command to install the os packages need for the application.
RUN has two forms:
FROM debian:stretch
RUN mkdir /app
WORKDIR /app
#get the file name with the interpreted host name such as host-is-c60cb038cf15
#RUN touch host-is-${HOSTNAME}
# this is just host-is-${HOSTNAME}
RUN ["touch", "host-is-${HOSTNAME}"]
CMD ["ls"]
Test with the following commands,
docker build --rm --no-cache -f Dockerfile -t test:latest .
docker run --rm test:latest ls -al
changes made by RUN
are cached and which will save repeated builds. But cached old data can be a problem: use --no-cache
flag to avoid this problem.
If you need to change the shell use the SHELL
, for example Windows :
FROM microsoft/windowsservercore
SHELL ["powershell", "-NoProfile", "-Command"]
the CMD
specify the default commands to run when the container is started. This has shell and exec forms as in the above command RUN
. There can be only once CMD
(not as multiple RUN
commands) but can pass argument at the build time.
The ENTRYPOINT
is similar to CMD
but this allow the container to be a command.
To verify docker compose file, type in the same directory.
for example, see how to list the directory contents ?
FROM debian:stretch
ENTRYPOINT ["ls"]
You can use both the CMD
and the ENNTRYPOINT
togather
FROM debian:stretch
ENTRYPOINT ["echo"]
CMD "hello ojitha"
if you run, the CMD will pass the string to the ENTRYPOINT
and display "hello ojitha".
Let's see how to use network ports. Here the simple Dockerfile:
FROM ruby:latest
# update and install nodejs
RUN apt-get update && apt-get install -y nodejs
# intall rail
RUN gem install rails
RUN mkdir /app
WORKDIR /app
# start blog
RUN rails new blog
# Expose prot 3000
EXPOSE 3000
# change the work directory
WORKDIR /app/blog
# start the server
ENTRYPOINT [ "bin/rails" , "server"]
Create image as follows
docker build --rm -f Dockerfile -t blog:latest .
Run the docker container as follows in the background and assign port 3000 to random local port:
docker run -d -p 3000 --name demo blog:latest
Now run the following command to find the local mapping to the exposed port:
docker container ps
If you found the port http://localhost:<port>
to access the site.
docker-compose config
to build the docker image
docker-compose build --no-cache
docker-compose up -d
To see all the containers created in the above step
docker-compose ps
to follow the logs:
docker-compose logs -f
Environment Variables
The ENV
is the command to define the environment variables in the Dockerfile such as:
FROM debian:stretch
ENV NAME=ojitha
RUN mkdir /app
ADD script.sh /app/script.sh
WORKDIR /app
RUN chmod +x script.sh
CMD ["./script.sh"]
This script.sh file has only one line:
#!/bin/bash
echo Hello $NAME !
If you need to pass in the command line to override the Dockerfile variable name
:
docker run --rm -e NAME=world file_copy:latest
#or
docker run --rm -e NAME="world of mine" file_copy:latest
If you have more variable to manage, then use a file such as mytest.env: line per varaible
NAME=Australia
Then run with the flag --env-file
as follows:
docker run --rm --env-file testprop.env file_copy:latest
As ENV
there is ARG
which help to define such as for example dev, test and prod environments.
For example suppose, you have dev.conf, test.conf and prod.conf. For dev you have to copy dev.conf to env.conf, for prod environment you have to copy prod.conf to env.conf.
FROM debian:stretch
ARG env=dev
COPY ${env}.conf /env.conf
The files prod.conf, test.conf and dev.conf should be in the root directory to copy. You can run
# build image
docker build --rm -f Dockerfile -t file_copy:latest .
# create container
docker run --rm file_copy:latest cat /env.conf
This should display the contents of the dev.conf file.
To see all the running processors in the docker compose
docker-compose top
from the above command you can get the up and running containers, if you need to stop or start a particular container
docker-compose stop <container>
# ....
docker-compose start <container>
# or use the following to create and start the container
docker-compose up <container>
following command stop giving any resources to the container , but you cannot restart host and un-pause
docker-compose pause
but above is good to get the snapshot
To completely destroy what have been done with
docker-compose down
Above will stop all containers created and remove them as well. Be careful !
retag the docker image
# form the docker image ls find the existing tag
docker tag <existing-tag> <new-tag>
#to push to local repo
docker push <new-tag>
Comments
Post a Comment
commented your blog