How to expose multiple ports of Container to Docker?

I used EXPOSE 8080 to expose 8080 port to the docker host in my earliest post.

I need to expose two ports, one for application access and another one for JMX monitoring.

EXPOSE 8080 48080

While running the docker, use one -p parameter for each port to be exposed as given below,

$ docker run -p 6666:8080 -p 58080:48080 messenger

 

Creating docker image for SpringBoot REST gateway

This post documents the steps I performed to containerize my REST application built with Spring Boot.

This uses the following tools

  1. Spring Tool Suite 4
  2. Maven – STS inbuilt
  3. Open JDK (Built by Azul)
  4. Docker

 

Step 1: Build your spring boot application using Maven:

SpringBoot and Docker 01

This will build the file and jar file will be copied to the target folder of your project folder.

[INFO] --- maven-jar-plugin:3.1.2:jar (default-jar) @ messenger ---
[INFO] Building jar: D:\Pandian\Documents\workspace_hamsa\messenger\target\messenger-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.1.8.RELEASE:repackage (repackage) @ messenger ---
[INFO] Replacing main artifact with repackaged archive
[INFO]
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ messenger ---
[INFO] Installing D:\Pandian\Documents\workspace_hamsa\messenger\target\messenger-0.0.1-SNAPSHOT.jar to C:\Users\barat\.m2\repository\org\grassfield\messenger\0.0.1-SNAPSHOT\messenger-0.0.1-SNAPSHOT.jar
[INFO] Installing D:\Pandian\Documents\workspace_hamsa\messenger\pom.xml to C:\Users\barat\.m2\repository\org\grassfield\messenger\0.0.1-SNAPSHOT\messenger-0.0.1-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  13.659 s
[INFO] Finished at: 2019-10-12T08:57:43+08:00
[INFO] ------------------------------------------------------------------------

You may see above. The jar file messenger-0.0.1-SNAPSHOT.jar is created in the target folder.

Step 2: Create Dockerfile

We start building our own container now. We need to define the docker configuration in a Dockerfile. It will be placed in the root of project folder.

Following is the Docker file for this project.

#this uses alpine base image with openjdk 8
FROM openjdk:8-jdk-alpine

#Maintainer contact details
MAINTAINER Murugapandian Ramaiah 

#where to persist the data generated by the container.
VOLUME /tmp

#which port of this container is to be exposed outside
EXPOSE 8080

#specify the SpringBoot bulky jar
ARG JAR_FILE=target/messenger-0.0.1-SNAPSHOT.jar
ADD ${JAR_FILE} messenger.jar

#specify how to execute the application
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom", "-jar", "/messenger.jar"]

Step 3: Build the container image

SSH the project folder to the /tmp partition of docker host Execute the following command.

$ cd /tmp/messenger
$ docker build -t messenger .
Step 1/7 : FROM openjdk:8-jdk-alpine
 ---> a3562aa0b991
Step 2/7 : MAINTAINER Murugapandian Ramaiah
 ---> Using cache
 ---> 4bb0470845c7
Step 3/7 : VOLUME /tmp
 ---> Using cache
 ---> 232d70e90d54
Step 4/7 : EXPOSE 8080
 ---> Using cache
 ---> 0a1d2e61d4a4
Step 5/7 : ARG JAR_FILE=target/messenger-0.0.1-SNAPSHOT.jar
 ---> Using cache
 ---> f179766aa87f
Step 6/7 : ADD ${JAR_FILE} messenger.jar
 ---> bc76f586ac0b
Step 7/7 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom", "-jar", "/messenger.jar"]
 ---> Running in 0646cdbee037
Removing intermediate container 0646cdbee037
 ---> 574eb9b9004b
Successfully built 574eb9b9004b
Successfully tagged messenger:latest

The container image is created

$ docker image ls
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
messenger            latest              574eb9b9004b        23 minutes ago      123MB
openjdk              8-jdk-alpine        a3562aa0b991        5 months ago        105MB
pandian/centos_ssh   latest              7f019be4424c        14 months ago       294MB
centos               latest              5182e96772bf        14 months ago       200MB
ubuntu               latest              735f80812f90        14 months ago       83.5MB
hello-world          latest              2cb0d9787c4d        15 months ago       1.85kB

messenger is added.

Step 4: run the container.

$ docker run -p 6666:8080 messenger

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.8.RELEASE)

2019-10-12 07:11:42.372  INFO 1 --- [           main] org.grassfield.msg.MessengerApplication  : Starting MessengerApplication v0.0.1-SNAPSHOT on 0f9f70c91b73 with PID 1 (/messenger.jar started by root in /)
2019-10-12 07:11:42.375  INFO 1 --- [           main] org.grassfield.msg.MessengerApplication  : No active profile set, falling back to default profiles: default
2019-10-12 07:11:43.394  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-10-12 07:11:43.430  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-10-12 07:11:43.431  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.24]
2019-10-12 07:11:43.530  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-10-12 07:11:43.530  INFO 1 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1118 ms
2019-10-12 07:11:43.758  INFO 1 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-10-12 07:11:44.005  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-10-12 07:11:44.008  INFO 1 --- [           main] org.grassfield.msg.MessengerApplication  : Started MessengerApplication in 2.072 seconds (JVM running for 2.438)

I endorse this post by Rajeev – https://www.callicoder.com/spring-boot-docker-example/

Dont miss this carving in Temple of tooth, Kandy (Summer 2019)

Dont miss this carving in Temple of tooth, Kandy (Summer 2019)

 

Error while building the docker image lstat /tmp/Dockerfile: no such file or directory

I’m trying to build a docker image. When I issue the build command I got the following error.


$ docker build -t messenger .
unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /tmp/Dockerfile: no such file or directory

I was executing the command from /tmp instead of /tmp/messenger, where the Dockerfile is located. When I executed from /tmp/messenger, it worked.

சாந்தி நிலவ வேண்டும். உலகிலே சாந்தி நிலவ வேண்டும் -  I captured this serene Buddha statue at Temple of tooth, Kandy during 2019 summerat temple of t

சாந்தி நிலவ வேண்டும். உலகிலே சாந்தி நிலவ வேண்டும் – I captured this serene Buddha statue at Temple of tooth, Kandy during 2019 summerat temple of t

Cannot connect to the Docker daemon

So I see this problem when I tried to run a hello-world container

$ docker run hello-world
docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.
See 'docker run --help'.

Check if the docker is running in the host.
Yes it is running

$ sudo service docker status
[sudo] password for pandian:
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2019-10-12 09:12:03 +08; 18s ago
     Docs: https://docs.docker.com
 Main PID: 17992 (dockerd)
    Tasks: 18
   CGroup: /system.slice/docker.service
           └─17992 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Oct 12 09:11:59 docker dockerd[17992]: time="2019-10-12T09:11:59.472499831+08:00" level=warning msg="Your kernel does not support swap memory limit"
Oct 12 09:11:59 docker dockerd[17992]: time="2019-10-12T09:11:59.472521907+08:00" level=warning msg="Your kernel does not support cgroup rt period"
Oct 12 09:11:59 docker dockerd[17992]: time="2019-10-12T09:11:59.472528459+08:00" level=warning msg="Your kernel does not support cgroup rt runtime"
Oct 12 09:11:59 docker dockerd[17992]: time="2019-10-12T09:11:59.472676228+08:00" level=info msg="Loading containers: start."
Oct 12 09:12:00 docker dockerd[17992]: time="2019-10-12T09:12:00.302342870+08:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip
Oct 12 09:12:00 docker dockerd[17992]: time="2019-10-12T09:12:00.604326576+08:00" level=info msg="Loading containers: done."
Oct 12 09:12:03 docker dockerd[17992]: time="2019-10-12T09:12:03.531536271+08:00" level=info msg="Docker daemon" commit=a872fc2f86 graphdriver(s)=overlay2 version=19.03.3
Oct 12 09:12:03 docker dockerd[17992]: time="2019-10-12T09:12:03.535138604+08:00" level=info msg="Daemon has completed initialization"
Oct 12 09:12:03 docker dockerd[17992]: time="2019-10-12T09:12:03.722547518+08:00" level=info msg="API listen on /var/run/docker.sock"
Oct 12 09:12:03 docker systemd[1]: Started Docker Application Container Engine.
lines 1-19/19 (END)

Docker daemon is running now.

$ ls -alt /var/run/docker.sock
srw-rw---- 1 root docker 0 Oct 12 09:11 /var/run/docker.sock

Run the hello-world now.

$ docker run hello-world

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.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/
I captured Kandy lake in Sri Lanka during the summer season of 2019

I captured Kandy lake in Sri Lanka during the summer season of 2019

Docker Commands to start/stop containers

Getting docker images

To search for available images in the repository..

$ docker search centos
NAME                               DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
centos                             The official build of CentOS.                   4585                [OK]
ansible/centos7-ansible            Ansible on Centos7                              115                                     [OK]
jdeathe/centos-ssh                 CentOS-6 6.10 x86_64 / CentOS-7 7.5.1804 x86…   99                                      [OK]
consol/centos-xfce-vnc             Centos container with "headless" VNC session…   60                                      [OK]
imagine10255/centos6-lnmp-php56    centos6-lnmp-php56                              44                                      [OK]
tutum/centos                       Simple CentOS docker image with SSH access      43
centos/mysql-57-centos7            MySQL 5.7 SQL database server                   38
gluster/gluster-centos             Official GlusterFS Image [ CentOS-7 +  Glust…   32                                      [OK]
openshift/base-centos7             A Centos7 derived base image for Source-To-I…   31
centos/python-35-centos7           Platform for building and running Python 3.5…   28
centos/postgresql-96-centos7       PostgreSQL is an advanced Object-Relational …   26
kinogmt/centos-ssh                 CentOS with SSH                                 22                                      [OK]
openshift/jenkins-2-centos7        A Centos7 based Jenkins v2.x image for use w…   14
pivotaldata/centos-gpdb-dev        CentOS image for GPDB development. Tag names…   7
openshift/mysql-55-centos7         DEPRECATED: A Centos7 based MySQL v5.5 image…   6
openshift/jenkins-1-centos7        DEPRECATED: A Centos7 based Jenkins v1.x ima…   4
openshift/wildfly-101-centos7      A Centos7 based WildFly v10.1 image for use …   4
darksheer/centos                   Base Centos Image -- Updated hourly             3                                       [OK]
pivotaldata/centos                 Base centos, freshened up a little with a Do…   2
blacklabelops/centos               CentOS Base Image! Built and Updates Daily!     1                                       [OK]
pivotaldata/centos-mingw           Using the mingw toolchain to cross-compile t…   1
jameseckersall/sonarr-centos       Sonarr on CentOS 7                              0                                       [OK]
pivotaldata/centos-gcc-toolchain   CentOS with a toolchain, but unaffiliated wi…   0
smartentry/centos                  centos with smartentry                          0                                       [OK]
pivotaldata/centos7-build          CentosOS 7 image for GPDB compilation           0

To download the image from the search results..

$ docker pull centos
Using default tag: latest
latest: Pulling from library/centos
256b176beaff: Pull complete
Digest: sha256:6f6d986d425aeabdc3a02cb61c02abb2e78e57357e92417d6d58332856024faf
Status: Downloaded newer image for centos:latest

After downloading the image, we may run the instance.

$ docker run centos

Now, we have downloaded many images. To see the list of images..

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              5182e96772bf        10 days ago         200MB
ubuntu              latest              735f80812f90        2 weeks ago         83.5MB
hello-world         latest              2cb0d9787c4d        5 weeks ago         1.85kB

To run an interactive shell of centos, lets run it.

$ docker run -it centos
[root@53771652af4a /]# hostname
53771652af4a
[root@53771652af4a /]# id
uid=0(root) gid=0(root) groups=0(root)

Customizing the containers

Let’s modify this container a bit. For example. following is how we install net-tools package

[root@53771652af4a /]# ifconfig
bash: ifconfig: command not found
[root@53771652af4a /]# yum install net-tools
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
* base: mirror.0x.sg
* extras: mirror.0x.sg
* updates: mirror.0x.sg
base | 3.6 kB 00:00:00
extras | 3.4 kB 00:00:00
updates | 3.4 kB 00:00:00
(1/4): base/7/x86_64/group_gz | 166 kB 00:00:00
(2/4): extras/7/x86_64/primary_db | 174 kB 00:00:00
(3/4): base/7/x86_64/primary_db | 5.9 MB 00:00:00
(4/4): updates/7/x86_64/primary_db | 5.0 MB 00:00:01
Resolving Dependencies
--> Running transaction check
---> Package net-tools.x86_64 0:2.0-0.22.20131004git.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

======================================================================================================================================================
Package Arch Version Repository Size
======================================================================================================================================================
Installing:
net-tools x86_64 2.0-0.22.20131004git.el7 base 305 k

Transaction Summary
======================================================================================================================================================
Install 1 Package

Total download size: 305 k
Installed size: 917 k
Is this ok [y/d/N]: y
Downloading packages:
warning: /var/cache/yum/x86_64/7/base/packages/net-tools-2.0-0.22.20131004git.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
Public key for net-tools-2.0-0.22.20131004git.el7.x86_64.rpm is not installed
net-tools-2.0-0.22.20131004git.el7.x86_64.rpm | 305 kB 00:00:00
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Importing GPG key 0xF4A80EB5:
Userid : "CentOS-7 Key (CentOS 7 Official Signing Key) "
Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5
Package : centos-release-7-5.1804.1.el7.centos.x86_64 (@Updates)
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Is this ok [y/N]: y
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : net-tools-2.0-0.22.20131004git.el7.x86_64 1/1
Verifying : net-tools-2.0-0.22.20131004git.el7.x86_64 1/1

Installed:
net-tools.x86_64 0:2.0-0.22.20131004git.el7

Complete!
[root@53771652af4a /]# ifconfig
eth0: flags=4163 mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
RX packets 8448 bytes 12601933 (12.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4833 bytes 321266 (313.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73 mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

Similarly I have installed openssh server as well. As we customized our container now, we need to commit it to retain the updated copy. To commit it, lets exit the container shell and execute the following command from the docker machine.

$ docker commit -m "added net-tools and ssh server" -a "pandian" 53771652af4a pandian/centos_ssh
sha256:7f019be4424c070511efb90e357b720333df5d80f845de6a7d569b94ac829fd7

To get the container id, you may use docker ps command as below.

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
53771652af4a        centos              "/bin/bash"         27 minutes ago      Exited (0) 7 minutes ago                        relaxed_vaughan
f6ed55b0451c        centos              "/bin/bash"         33 minutes ago      Exited (0) 33 minutes ago                       relaxed_rosalind
462658ae9e5a        ubuntu              "bash"              15 hours ago        Up 15 hours                                     inspiring_mahavira
1aebd1e64faa        ubuntu              "bash"              15 hours ago        Exited (127) 15 hours ago                       gracious_banach
ff56bc579e04        hello-world         "/hello"            15 hours ago        Exited (0) 15 hours ago                         distracted_lamarr
e209861d337d        hello-world         "/hello"            15 hours ago        Exited (0) 15 hours ago                         laughing_ramanujan

As we commited our image, lets see the image list now. the repository has the updated image.

$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
pandian/centos_ssh   latest              7f019be4424c        25 minutes ago      294MB
centos               latest              5182e96772bf        10 days ago         200MB
ubuntu               latest              735f80812f90        3 weeks ago         83.5MB
hello-world          latest              2cb0d9787c4d        5 weeks ago         1.85kB

Starting and stopping instances

Here is the way we stop the instances.

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
462658ae9e5a        ubuntu              "bash"              15 hours ago        Up 15 hours                             inspiring_mahavira
$ docker stop 462658ae9e5a
462658ae9e5a

To start the instance the instance customized by us..

$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
pandian/centos_ssh latest 7f019be4424c 43 minutes ago 294MB
centos latest 5182e96772bf 10 days ago 200MB
ubuntu latest 735f80812f90 3 weeks ago 83.5MB
hello-world latest 2cb0d9787c4d 5 weeks ago 1.85kB
$ docker run -it pandian/centos_ssh
[root@d66d18a06066 /]# ifconfig
eth0: flags=4163 mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 25 bytes 3024 (2.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73 mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

 

Docker – Setup

I am drafting the step-by-steps to install Docker in this post.

VM Setup

I created a new Ubuntu VM 16.04 in my Xen Server with manual network setup. Hence I have given a static IP to this new VM.

I Installed the xentools using the following commands. This is not required if you do not want to install it.


sudo mount /dev/dvd /media
sudo /media/pandian/XenServer\ Tools/Linux/install.sh

 

After successful installation of xentools, a reboot of VM is required.

Install SSH demon.


sudo apt update

sudo apt upgrade

sudo apt-get install openssh-server

sudo apt-get install curl

 

Add the GPG of docker repository.


curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

 

Add Docker repository to ubuntu sources and install Docker from docker repo, instead of default ubuntu repo.


sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

sudo apt-get update

apt-cache policy docker-ce

sudo apt-get install -y docker-ce

sudo systemctl status docker

Docker is now installed and started.

But it needs sudo to run docker command.


$ docker info
Got permission denied while trying to connect to the Docker daemon socket at uniial unix /var/run/docker.sock: connect: permission denied
$ sudo docker info

Hence, add the unix user to docker group to avoid it. Here is how we shall do it. Credit goes to digitalocean.


~$ sudo usermod -aG docker ${USER}
~$ su - ${USER}
Password:
~$ id -nG
pandian adm cdrom sudo dip plugdev lpadmin sambashare docker

$ id
uid=1000(pandian) gid=1000(pandian) groups=1000(pandian),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare),999(docker)

So the user has been added to docker group. id confirms the same. Now it is the time to run our first hello-world container. As we do not have this image locally, it is downloaded from docker repository.


~$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
9db2ca6ccae0: Pull complete
Digest: sha256:4b8ff392a12ed9ea17784bd3c9a8b1fa3299cac44aca35a85c90c5e3c7afacdc
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.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:
https://docs.docker.com/engine/userguide/