Skip to content

Instantly share code, notes, and snippets.

@rgodishela
Created April 23, 2017 16:28
Show Gist options
  • Save rgodishela/6cf3d968e44db16598e0c7efedcec502 to your computer and use it in GitHub Desktop.
Save rgodishela/6cf3d968e44db16598e0c7efedcec502 to your computer and use it in GitHub Desktop.
Docker Tips and Tricks
Docker Tutorials
Getting Started:Installation
Ubuntu :
1. Log into your Ubuntu installation as a user with sudo privileges.
2. Verify that you have wget installed.
$ which wget
3. If wget isn’t installed, install it after updating your manager:
$ sudo apt-get update $ sudo apt-get install wget
4. Get the latest Docker package.
$ wget -qO- https://get.docker.com/ | sh
The system prompts you for your sudo password.
5. Verify docker is installed correctly.
Execute the following command.
$ sudo docker run hello-world
You should see the following outout.
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.
(Assuming it was not already locally available.)
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
Getting Started:Basic Commands
Info command
This command gives information about the docker setup on your machine/vm
$ docker info
Output of the command will look similar to the listing below
Containers: 16
Images: 126
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 158
Dirperm1 Supported: false
Execution Driver: native-0.2
Kernel Version: 3.13.0-32-generic
Operating System: Ubuntu 14.04.1 LTS
CPUs: 4
Total Memory: 3.141 GiB
Name: ubuntu
ID: CS3B:XJ7B:DEWA:NRXG:VGDY:HYWO:N4NA:FGXM:WYME:FW5C:WYJN:IHVJ
Username: rajdeepd
Registry: [https://index.docker.io/v1/]
WARNING: No swap limit support
Create a Container and enter its shell
$ sudo docker run -i -t debian /bin/bash
This should give you a new command prompt inside the container, very similar to if you had ssh‘ed into a remote machine. In this case the flags -i and -t tell Docker we want an interactive session with a tty attached. The command `/bin/bas`h gives a bash shell. When you exit the shell the container will stop — containers only run as long as their main process
$ docker run debian echo hello-world
hello-world
Create a container with a name
You can use -h command line parameter to specify a container name.
$ docker run -h CONTAINER1 -i -t debian /bin/bash
Output of the command above will open a tty inside the container
root@CONTAINER1:/#
Create a container with a Networking mode
Container mode can be specified using the flag :code:`-net=<NETWORK_MODE> where
$ docker run -h CONTAINER2 -i -t --net="bridge" debian /bin/bash
List of docker containers running
$ docker ps -a
Inspect a Container
$ docker inspect hopeful_pare
Output will be a JSON file.
Start a Stopped Container
$ docker start hopeful_pare
where hopeful_pare is the container name.
Enter the Shell of a Started Container
$ docker attach hopeful_pare
where hopeful_pare is the container name.
Detach from a Container
docker run -t -i → can be detached with ^P^Q and reattached with docker attach
docker run -i → cannot be detached with ^P^Q; will disrupt stdin
docker run → cannot be detached with ^P^Q;
can SIGKILL client; can reattach with docker attach
Docker Logs
If you run this command with the name of your container, you should get a list of commands executed in the container.
$ docker logs hopeful_pare
where hopeful_pare is the container name.
Removing a Single Container
$ docker rm hopeful_pare
Removing all the Containers
$ docker rm `docker ps --no-trunc -aq`
Docker Images
Show images
$ sudo docker show images
Specifying a Variant
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
Pull an Image
$ sudo docker pull debian
Create your own image
1. Create a Dockerfile with the following content
FROM debian:wheezy
2.
3. RUN apt-get update && apt-get install -y cowsay fortune
4. 



5. Go to the directory container Dockerfile and execute the following command to build a image
$ docker build -t test/cowsay-dockerfile .
6. 


You will see output as shown below
Sending build context to Docker daemon 2.048 kB
7. Sending build context to Docker daemon
8. Step 0 : FROM debian:wheezy
9. wheezy: Pulling from debian
10. 7a3e804ed6c0: Pull complete
11. b96d1548a24e: Already exists
12.
13. Status: Downloaded newer image for debian:wheezy
14. ---> b96d1548a24e
15. Step 1 : RUN apt-get update && apt-get install -y cowsay fortune
16. ---> Running in 4404353a3643
17. Get:1 http://security.debian.org wheezy/updates Release.gpg [1554 B]
18. Get:2 http://security.debian.org wheezy/updates Release [102 kB]
19. Get:3 http://httpredir.debian.org wheezy Release.gpg [2390 B]
20. .....
21. Setting up perl (5.14.2-21+deb7u2) ...
22. update-alternatives: using /usr/bin/prename to provide /usr/bin/rename
23. ---> ca3618d10f2a
24. Removing intermediate container 4404353a3643
25. Successfully built ca3618d10f2a
26. 



27. Check that image has been created
$ docker images
28. REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
29. test/cowsay-dockerfile latest ca3618d10f2a 3 minutes ago 126.9 MB
30. docker-dev dry-run-test-2 db155754d7fc 6 days ago 1.571 GB
31. <none> <none> b01392d005bb 6 days ago 1.571 GB
32. debian wheezy b96d1548a24e 7 days ago 84.97 MB
33. debian latest df2a0347c9d0 7 days ago 125.2 MB
34. dockerswarm/dind-master latest bb4cd757411e 7 days ago 159 MB
35. <none> <none> f672d2db20f6 7 days ago 1.571 GB
36. <none> <none> 1fe07c1fdf52 8 days ago 1.571 GB
37. dockerswarm/swarm-test-env latest 01e6a0da0825 2 weeks ago 515.5 MB
38. ubuntu 14.04 07f8e8c5e660 3 weeks ago 188.3 MB
39. hello-world latest 91c95931e552 5 weeks ago 910 B
40. busybox latest 8c2e06607696 5 weeks ago 2.433 MB
41. 



42. Run the cowsay program using the built image
$ docker run test/cowsay-dockerfile /usr/games/cowsay "Hi!"
43. 


This will execute and show the output
 _____
44. < Hi! >
45. -----
46. \ ^__^
47. \ (oo)\_______
48. (__)\ )\/\
49. ||----w |
50. || ||
Docker Registry
Docker allows to bundle and push the customized images on the docker hub or locally hosted docker registry. Images can be pushed or pull from this registry.
Create official Docker Hub account
$ sudo docker login
51. Username: username
52. Password:
53. Email: email@blank.com
54. WARNING:login credentials saved in /home/username/.dockercfg.
55. Account created. Please use the confirmation link we sent to your e-mail to activate it.
56. 


Search available images in the Docker hub registry
$ sudo docker search centos
57. NAME DESCRIPTION STARS OFFICIAL AUTOMATED
58. centos The official build of CentOS. 1057 [OK]
59. ansible/centos7-ansible Ansible on Centos7 43 [OK]
60. tutum/centos Centos image with SSH access. For the root... 13 [OK]
61. blalor/centos Bare-bones base CentOS 6.5 image 9 [OK]
62. jdeathe/centos-ssh-apache-php CentOS-6 6.6 x86_64 / Apache / PHP / PHP m... 9 [OK]
63. torusware/speedus-centos Always updated official CentOS docker imag... 5 [OK]
64. 


It will list all publically available images having the keyword “centos” in the Docker Hub registry.
Push customized image to Docker repository
$ sudo docker push username/newimage
65. The push refers to a repository [username/newimage] (len: 1)
66. d94fdd926b02: Image already exists
67. accbaf2f09a4: Image successfully pushed
68. aa354fc0b2b2: Image successfully pushed
69. 3a94f42115fb: Image successfully pushed
70. 7771ee293830: Image successfully pushed
71. fa81ed084842: Image successfully pushed
72. e04c66a223c4: Image successfully pushed
73. 7e2c5c55ef2c: Image successfully pushed
74. .......................................
75. 


Please note repository name should meet the username of the docker hub account in order to push the images. Currently docker gives one private repository for free. Otherwise, in general images which are pushed to docker hub account will be made publically available.
Install Private Local Docker Registry
$ docker run -p 5000:5000 registry
76. 


Tag the images
Now, we will the tag the same image created in the above tutorial to “localhost:5000/newimage” so that the repository name matches and it can be easily pushed to private docker registry.
$docker tag username/newimage:latest localhost:5000/newimage:latest
77. 


Push the image to private docker registry
$ docker push localhost:5000/newimage:latest
78. The push refers to a repository [localhost:5000/test_nginx_image] (len: 1)
79. Sending image list
80. Pushing repository localhost:5000/test_nginx_image (1 tags)
81. e118faab2e16: Image successfully pushed
82. 7e2c5c55ef2c: Image successfully pushed
83. e04c66a223c4: Image successfully pushed
84. fa81ed084842: Image successfully pushed
85. 7771ee293830: Image successfully pushed
86. 3a94f42115fb: Image successfully pushed
87. aa354fc0b2b2: Image successfully pushed
88. accbaf2f09a4: Image successfully pushed
89. d94fdd926b02: Image successfully pushed
90. Pushing tag for rev [d94fdd926b02] on {http://localhost:5000/v1/repositories/test_nginx_image/tags/latest}
91. 


Image ID can be seen by visitng the link in browser or using the curl command which comes up after pushing the image.
DOCKER NETWORKING:Bind Host Port to container Port
Make a docker file directory $ mkdir docker-file
Make a docker file
$ cd docker-file/
92. $ touch Dockerfile
93. 


Add content to docker file
$ cat > Dockerfile
94. FROM ubuntu:14.04
95. MAINTAINER abc "abc@abc.com"
96. RUN apt-get update
97. RUN apt-get install -y nginx
98. RUN echo 'Our first Docker image for Nginx' > /usr/share/nginx/html/index.html
99. EXPOSE 80
100. 


Ctrl+D to save the changes
Create your own image
1. Build a docker image
101. $ sudo docker build -t="test/test_nginx_image" .
102. 


You will see output as shown below
Sending build context to Docker daemon 2.56 kB
103. Sending build context to Docker daemon
104. Step 0 : FROM ubuntu:14.04
105. ---> 9cbaf023786c
106. Step 1 : MAINTAINER abc "abc@abc.com"
107. ---> Using cache
108. ---> 912452fdbe6d
109. Step 2 : RUN apt-get update
110. ---> Using cache
111. ---> d711127e4d76
112. Step 3 : RUN apt-get install -y nginx
113. ---> Running in 4fab72b24686
114. Processing triggers for libc-bin (2.19-0ubuntu6.3) ...
115. Processing triggers for sgml-base (1.26+nmu4ubuntu1) ...
116. ---> b9f58e96b137
117. Removing intermediate container 4fab72b24686
118. Step 4 : RUN echo 'Our first Docker image for Nginx' > /usr/share/nginx/html/index.html
119. ---> Running in 1d1702c4dae4
120. ---> c46b140fd8ad
121. Removing intermediate container 1d1702c4dae4
122. Step 5 : EXPOSE 80
123. ---> Running in a98f7685870a
124. ---> 728d805bd6d0
125. Removing intermediate container a98f7685870a
126. Successfully built 728d805bd6d0
127. 



2. Check that image has been created
128. $ docker images | grep nginx
129. test/test_nginx_image latest 1 day ago 2.433 MB
130. 



3. Run the newly created test-ngnix_image with port binding
131. $ sudo docker run -d -p 8080:80 --name test_container test/test_nginx_image nginx -g "daemon off;"
132. 356389b43b02c5afb55de8145cb33a3e6539c671a97c2c6974a6308f1d7bac8d
133. 


The -p 8080:80 option will bind the host port 8080 to the container port 80. So we will be able to see the default web page of “Our first Docker image for Nginx” by simply visting the IP address of our docker host.
$ curl http://docker-host-ip:8080
134. Our first Docker image for Nginx

135. 
Using OVS bridge for docker networking
Install OVS
$ sudo apt-get install openvswitch-switch
136. 


Install ovs-docker utility
$ cd /usr/bin
137. $ wget https://raw.githubusercontent.com/openvswitch/ovs/master/utilities/ovs-docker
138. $ chmod a+rwx ovs-docker
139. 


Create OVS bridge and adding a port to eth0
Connect one end of the bridge to eth0 (localhost) and the other end will be connected to the docker container
$ ovs-vsctl add-br ovs-br1
140. $ ovs-vsctl add-port ovs-br1 eth0
141. $ ifconfig ovs-br1 173.16.1.1 netmask 255.255.255.0 up
142. 


Add a port from OVS bridge to the Docker Container
1. Creat two ubuntu Docker Containers
$ docker run -t -i --name container1 ubuntu /bin/bash
2. $ docker run -t -i --name container2 ubuntu /bin/bash
3. 



4. Connect the container to OVS bridge
$ ovs-docker add-port ovs-br1 eth1 container1 --ipaddress=173.16.1.2/24
5. $ ovs-docker add-port ovs-br1 eth1 container2 --ipaddress=173.16.1.3/24
6. 



7. Test the connection between two containers connected via OVS bridge using Ping command
Weave Networking for Docker
Weave creates a virtual network that enables users to connect docker containers on different host and enable their auto-discovery
Install Weave
$ sudo wget -O /usr/local/bin/weave \
8. https://github.com/weaveworks/weave/releases/download/latest_release/weave
9. $ sudo chmod a+x /usr/local/bin/weave
10. 


Launch weave containers
$ weave launch
11. 


This command will internally pull weave router container and run it
Start two application containers on weave network
$ C=$(weave run 10.2.1.1/24 -t -i ubuntu)
12. $ C12=$(weave run 10.2.1.2/24 -t -i ubuntu)
13. 


C and C12 hold the containerId of the containers created
$ echo $C
14. 29e5ebaa8f0740077338a6d0d28d0760308f1a3ed2f39034392f1d278d96acd2
15. $ echo $C12
16. b0764f4e3792650c8664de2b601e00fc6dae211192dedbad36dcf1e0f11214c9
17. 


weave run command will internally run docker run -d command in order to set the ip address of weave network and start the ubuntu containers. Test the connection between two containers connected via weave network by using the ping command
 
$ docker attach $C
18. $ ping 10.2.1.2 -c 4
19. PING 10.2.1.2 (10.2.1.2) 56(84) bytes of data.
20. 64 bytes from 10.2.1.2: icmp_seq=1 ttl=64 time=0.119 ms
21. 64 bytes from 10.2.1.2: icmp_seq=2 ttl=64 time=0.152 ms
22. 64 bytes from 10.2.1.2: icmp_seq=3 ttl=64 time=0.112 ms
23. 64 bytes from 10.2.1.2: icmp_seq=4 ttl=64 time=0.104 ms
24.
25. --- 10.2.1.2 ping statistics ---
26. 4 packets transmitted, 4 received, 0% packet loss, time 2999ms
27. rtt min/avg/max/mdev = 0.104/0.121/0.152/0.022 ms
Docker Volumes
Get Started with Volumes
In this lab we learn how to create a basic docker volume and mount it in a container
Volume mounted in a container
1. Execute the following command
$ docker run -v /volume1 -i -t ubuntu /bin/bash
2. 


This will mount /volume1 inside the container created from ubuntu image and launch and bash shell.

3. The command above will get us into the terminal tty of the container. Run ls command and you will notice volume 1 there
$root@b979b5d735b0:/# ls
4. bin boot dev etc home lib lib64.. var volume1
5. 



6. On inspecting the docker container you will notice that /volume1 is mounted under / and is a ReadWrite Volume
{
7. "Volumes": {
8. "/volume1": "/var/lib/docker/vfs/dir/012..5a569b392"
9. },
10. "VolumesRW": {
11. "/volume1": true
12. }
13. }
14. 



28. 
Mount a Host Directory as a Volume
1. Create a local directory /host/logs
$ sudo mkdir -p /host/logs
2. $ sudo touch /host/logs/log1.txt
3. 



4. Execute the following command to bind /host/logs host directory to /container/logs volume
$ docker run -v /host/logs:/container/logs -i -t ubuntu /bin/bash
5. 



6. Execute ls to see the contents of mounted volume. Notice that contents are the same as created in host directory.
root@3774005dee32:/# ls
7. bin boot container .. srv sys tmp usr var
8. root@3774005dee32:/# ls container/logs/
9. log1.txt

10. 
Volumes from Docker Image
Docker Image with Volume specified in Dockerfile
In this lab we look at
1. How to add a file as a volume using Dockerfile format.
2. Create an Image from the Dockerfile
3. Use the Image to create a container and check if the file exists.
11. Create the Dockerfile
Create a Dockerfile as shown below in a directory. Make sure file1 exists in the same directory. We are gong to mount file1 as /ubuntu1/file and mount /ubuntu1 as a VOLUME.
FROM ubuntu
12. ADD file1 /ubuntu1/file
13. VOLUME /ubuntu1
14. CMD /bin/sh
15. 



Create an Image from the Dockerfile
Execute the command below to build the image test/volume-one-dockerfile
docker build -t test/volume-one-dockerfile .
16. 



Create a Docker container
Create a container from the image test/volume-one-dockerfile
docker run -it test/volume-one-dockerfile
17. 


This command above will launch the bash shell of the container. Check if the volume /ubuntu1 is mounted
# ls
18. bin boot dev etc home lib .. sbin srv sys tmp ubuntu1 usr var
19. # ls /ubuntu1
20. file
21. 




Docker Container with volume from Command Line and Image
In this section you will learn how to use command line to mount a host directory into a container created from an image
Create a Local directory
Create a local directory ubuntu2 and two files file1 and file2 in that directory.
$sudo mkdir -p /ubuntu2
22. [sudo] password for ubuntu:
23. $ sudo touch /ubuntu2/file1
24. $ sudo touch /ubuntu2/file2
25. 



Create a Container with a Volume ubuntu2
Create a container from the image :code:test/volume-one-dockerfile by specifying the directory to be mounted on the command line with a flag -v.
$ docker run -it -v /ubuntu2:/ubuntu2 test/volume-one-dockerfile
26. 


Check that the directory ubuntu2 got mounted in the docker container. Run ls in the container shell.
# ls
27. bin boot dev etc home lib sys tmp ubuntu1 ubuntu2 usr var
28. # ls ubuntu2
29. file1 file2
30. 


As you can see above both ubuntu1 and ubuntu2 got mounted as volumes.
31. [Ref]
32. https://blog.docker.com/2015/04/docker-tutorial-3-fun-with-volumes/
33. 

Container with ReadOnly Volume
Specify the :ro as shown below to make the volume readonly.
$ docker run -it -v /ubuntu2:/ubuntu2:ro test/volume-one-dockerfile
34. 


Try creating a new file in that volume from the bash shell of the container.
# touch /ubuntu2/file3
35. touch: cannot touch '/ubuntu2/file3': Read-only file system

36. 
Volumes From Another Container
Volumes from a container can be bound to another container using --volumes-from <container-name> flag. Make sure there is host directory with contents /ubuntu1/code
$ ls /ubuntu1
37. file
38. 


Create a Container with a Volume Create a container with name ubuntu1 from image ubuntu
$ docker run -it --name ubuntu1 -v /ubuntu1:/ubuntu1 ubuntu
39. root@f031b82e5da6:/# ls ubuntu1
40. file
41. 


Create Second Container with shared volumes
Create a second container ubuntu2 with volumes from ubuntu1
$ docker run -it --name ubuntu2 --volumes-from ubuntu1 ubuntu
42. 


Note : -volumes-from is also valid but deprecated.
Check that the ubuntu1 volume is bound as expected
root@b28ca7033e9d:/# ls
43. bin boot dev etc home .. ubuntu1 usr var
44. root@b28ca7033e9d:/# ls ubuntu1
45. file
 DOCKER APIS
Golang : Container Lifecycle Management
In this tutorial we look at how golang can be used to access Docker Daemon API Endpoint and manage containers.
Rerence files :
All the samples use utility functions from the file util.go.
SockerRequest is the function to make a socket call to the endpoint. In our case the endpoint uses default uri scheme of unix://localhost/.... We also need to pass method which could be GET,POST, DELETE.
func SockRequest(method, endpoint string, data interface{}) (int, []byte, error) {
46. ...
47. }
48. 


SockRequest in turn calls sockRequestRaw function to make the actual API call.
func func sockRequestRaw(method, endpoint string, data io.Reader, ct string)
49. (*http.Response, io.ReadCloser, error) {
50. ...
51. }
52. 


List Containers
We make the GET request to unix://localhost/containers/json?all=1 to get a list of containers in the JSON format. This gets Unmarshalled into samplesutils.ResponseJSON struct and then print using samplesutils.PrettyPrint.
func ListContainers() {
53. _, body, err := sampleutils.SockRequest("GET", "/containers/json?all=1", nil)
54. var respJSON *sampleutils.ResponseJSON
55. if err = json.Unmarshal(body, &respJSON); err != nil {
56. fmt.Printf("unable to unmarshal response body: %v", err)
57. }
58. sampleutils.PrettyPrint(respJSON)
59. }
60. 


This function is called from the main() function as shown below
func main() {
61. ListContainers()
62. }
63. 


Full Code Listing
Please refer to list_containers.go. for complete code listing of the sample.
Executing the Sample
Run the following command on the bash terminal
go run dockersamples/list_containers.go
64. 



Create a Container
To create a container we are going to pass the container name and the image name. API will call the endpoint unix://localhost//containers/create?name=[container_name]. Along with the request a confirg object is passed containing the image name and a flag to make sure container is not exited.
Call to samples.SockRequest(...)
_, body, err := sampleutils.SockRequest("POST", "/containers/create?name="+name, config)
65. 


body object returned is marshalled into sampleutils.ResponseCreateContainer
type ResponseCreateContainer struct {
66. Id string
67. Warnings string
68. 


Function CreateContainer(..) Listed below encloses all these calls.
func CreateContainer(name string) {
69. config := map[string]interface{}{
70. "Image": "busybox",
71. "OpenStdin": true,
72. }
73. _, body, err := sampleutils.SockRequest("POST",
74. "/containers/create?name="+name, config)
75. if err != nil {
76. fmt.Printf("Error %v\n", err)
77.
78. } else {
79. var resp *sampleutils.ResponseCreateContainer
80. if err = json.Unmarshal(body, &resp); err != nil {
81. fmt.Printf("unable to unmarshal response body: %v\n", err)
82. }
83. sampleutils.PrettyPrint(resp)
84. }
85.
86. }
87. 


Full Code Listing
Please refer to create_container.go. for complete code listing of the sample.
Executing the Sample
Run the following command on the bash terminal
go run dockersamples/create_container.go <container_name>
88. 



Start Container
In the last section we learnt how to create a container. In this section we will learn how to start a container which has already been created. Note that Create and Start are two states which are not the same.
First we get the containerId from the container name : name by calling the function samplesutils.GetContainerId(name).
Http POST request call is made by calling the function samples.SockRequest(...).
status, _, err := sampleutils.SockRequest("POST",
89. "/containers/"+containerId+"/start", nil)
90. 


status which is returned by the Http call is printed to the console. Please refer to the code list for the function.
func StartContainer(name string) {
91. containerId := sampleutils.GetContainerId(name)
92. fmt.Printf("startContainer :Container Id : %v", containerId)
93. if containerId == "" {
94. fmt.Printf("Invalid Container name %v\n", name)
95. } else {
96. status, _, err := sampleutils.SockRequest("POST",
97. "/containers/"+containerId+"/start", nil)
98. if err != nil {
99. fmt.Printf("\nerror %v\n", err)
100. } else {
101. fmt.Printf("\nStatus of the Start Request: %#v\n", status)
102. }
103. }
104. }
105. 


Full Code Listing
Please refer to start_container.go. for complete code listing of the sample.
Executing the Sample
Run the following command on the bash terminal
go run dockersamples/start_container.go <container_name>
Golang : Volume Lifecycle
In this lab we learn how to use golang to create and manage volumes in Docker.
Create a Container with a Volume
1. Create a Map object Config which has details about the image and volume binding path/
config := map[string]interface{}{
2. "Image": "busybox",
3. "OpenStdin": true,
4. "Volumes": map[string]struct{}{"/tmp": {}},
5. }
6. 



7. Pass this object to SockRequest(..) which POSTS to the default socket endpoint.

106. _, body, err := sampleutils.SockRequest("POST",
107. "/containers/create?name="+name, config)
108. 



3. Function with the complete code listing. Parameter name is the name of the container which is passed to the function
func CreateContainerWithVolume(name string) {
4. config := map[string]interface{}{
5. "Image": "busybox",
6. "OpenStdin": true,
7. "Volumes": map[string]struct{}{"/tmp": {}},
8. }
9. _, body, err := sampleutils.SockRequest("POST",
10. "/containers/create?name="+name, config)
11. if err != nil {
12. fmt.Printf("Error %v\n", err)
13.
14. } else {
15. var resp *sampleutils.ResponseCreateContainer
16. if err = json.Unmarshal(body, &resp); err != nil {
17. fmt.Printf("unable to unmarshal response body: %v\n", err)
18. }
19. sampleutils.PrettyPrint(resp)
20. }
21. }
22. 



23. Call the function CreateContainerWithVolume(name string) from the main() function
func main() {
24. if len(os.Args) > 1 {
25. arg := os.Args[1]
26. name := arg
27. CreateContainerWithVolume(name)
28. } else {
29. fmt.Printf("Please specify container name on the command line\n")
30. }
31. }
32. 



33. Execute the program
$ go run dockersamples/create_container_with_volume.go test3_vol
34. 



35. You can start the container and inspect the container to make sure volume got bound in the specifed path.
$ docker inspect test3_vol
36.
37. [{
38. "AppArmorProfile": "",
39. "Args": [],
40. "Config": {
41. ..
42. "Cmd": [
43. "/bin/sh"
44. ],
45. "Volumes": {
46. "/tmp": "/var/lib/docker/vfs/dir/ad64baef817f1..08b6584881427c29214f"
47. },
48. "VolumesRW": {
49. "/tmp": true
50. }
51. }
52. ]
53. 



109. 
Create a Container with Volume Binds
In this sample we bind a directory on the host (created on the fly) with a /tmp volume mounted in the container.
1. Create a Map object Config which has details about the image and volume binding path/
config := map[string]interface{}{
2. "Image": "busybox",
3. "Volumes": map[string]struct{}{"/tmp": {}},
4. "OpenStdin": true,
5. }
6. 



7. Pass this object to SockRequest(..) which does a Http POST to the default socket endpoint.

110. _, body, err := sampleutils.SockRequest("POST",
111. "/containers/create?name="+name, config)
112. 



3. Create a bindPath in a random Host directory and pass it while starting the Container through config object. In our case this directory is /tmp/test.yJzTpXFbfH
bindPath := sampleutils.RandomUnixTmpDirPath("test")
4. 


Please refer to util.go. for more details about RandomUnixTmpDirPath(..)
In the codeblock below notice how a Map specifying relationship between bindPath and /tmp is created. Finally samplesutil.SockRequest to start the container is called with the config.
config = map[string]interface{}{
5. "Binds": []string{bindPath + ":/tmp"},
6. }
7. containerId := sampleutils.GetContainerId(name)
8. status, _, err = sampleutils.SockRequest("POST", "/containers/"+containerId+"/start", config)
9. 



10. Function with the complete code listing. Parameter name is the name of the container which is passed to the function
func CreateContainerWithVolumeBinds(name string) {
11. config := map[string]interface{}{
12. "Image": "busybox",
13. "Volumes": map[string]struct{}{"/tmp": {}},
14. "OpenStdin": true,
15. }
16.
17. status, _, err := sampleutils.SockRequest("POST", "/containers/create?name="+name, config)
18. fmt.Printf("status: %v\n", status)
19. if err != nil {
20. fmt.Printf("Error while creating the Container: %v\n", err)
21. return
22. }
23.
24. bindPath := sampleutils.RandomUnixTmpDirPath("test")
25. fmt.Printf("BindPath: %v\n", bindPath)
26.
27. config = map[string]interface{}{
28. "Binds": []string{bindPath + ":/tmp"},
29. }
30. containerId := sampleutils.GetContainerId(name)
31. status, _, err = sampleutils.SockRequest("POST",
32. "/containers/"+containerId+"/start", config)
33. fmt.Printf("Status of the call: %v\n", status)
34. }
35. 



36. Call the function CreateContainerWithVolumeBinds(name string) from the main() function
func main() {
37. if len(os.Args) > 1 {
38. arg := os.Args[1]
39. name := arg
40. CreateContainerWithVolumeBinds(name)
41. } else {
42. fmt.Printf("Please specify container name on the command line\n")
43. }
44. }
45. 



46. Execute the program
$ go run dockersamples/create_container_with_volume_binds.go test4_vol
47. 



48. Container will be up and running, inspect the container to the check the bind created.
$ docker inspect test4_vol
49.
50. [{
51. "AppArmorProfile": "",
52. "Args": [],
53. "Config": {
54. ..
55. "Cmd": [
56. "/bin/sh"
57. ],
58. "Volumes": {
59. "/tmp": "/tmp/test.yJzTpXFbfH"
60. },
61. "VolumesRW": {
62. "/tmp": true
63. }
64. }
65. ]

66. 



113. 
Linking Docker Containers
Docker Link Flag
In order to connect together multiple docker containers or services running inside docker container, ‘–link’ flag can be used in order to securely connect and provide a channel to transfer information from one container to another. The below example shows a simple application of using a Wordpress container linked to MySQL container.
Pull the latest MySql container
$ docker pull mysql:latest
114. latest: Pulling from mysql
115. ..........................
116. 


Run MySql Container in detach mode
$ docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=wordpress -d mysql
117. 89c8554d736862ad5dbb8de5a16e338069ba46f3d7bbda9b8bf491813c842532
118. 


We will be running this database container with name “mysql-wordpress” and will set root password for MySQL container.
Pull Wordpress docker container
In the new terminal, pull the official wordpress container
$ docker pull wordpress:latest
119. latest: Pulling from wordpress
120. ..............................
121. 


Run the wordpress container linking it to MySQL Container
$ docker run -e WORDPRESS_DB_PASSWORD=password --name wordpress-container --link mysql-container:mysql -p 8080:80 -d wordpress
122. 189c0f04ce7694b4f9fadd36624f6f818023d8d1f3ed1c56de5a516255f328a9
123. 


As, we have linked both the container now wordpress container can be accessed from browser using the address http://localhost:8080 and setup of wordpress can be done easily.


Docker Compose
We will run the same previous application of wordpress and MySQL linking in this tutorial but with Docker compose which was launched recently and is a tool use to define and run complex linked applications with docker. With docker compose we can define the entire multi-container application in single file and then the application can be spinned up using one command.
Create a new project folder
$ mkdir dockercompose
124. $ cd dockercompose
125. 


Create Docker compose file
Create docker-compose.yml with preferred editor having the following contents
web:
126. image: wordpress
127. links:
128. - mysql
129. environment:
130. - WORDPRESS_DB_PASSWORD=sample
131. ports:
132. - "127.0.0.3:8080:80"
133. mysql:
134. image: mysql:latest
135. environment:
136. - MYSQL_ROOT_PASSWORD=sample
137. - MYSQL_DATABASE=wordpress
138. 


Get the linked containers up
$ docker-compose up
139. Creating dockercompose_mysql...
140. Creating dockercompose_web...
141. Attaching to dockercompose_mysql, dockercompose_web
142. mysql | Initializing database
143. ..............
144. 


 
Visit the IP address http://127.0.0.3:8080 in order to see the setup page of the newly created linked wordpress container.




BUG REPORT INFORMATION
Use the commands below to provide key information from your environment:
docker version:
docker info:
uname -a:
Provide additional environment details (AWS, VirtualBox, physical, etc.):
List the steps to reproduce the issue:
1.
2.
3.
Describe the results you received:
Describe the results you expected:
Provide additional info you think is important:
----------END REPORT ---------

145. 













Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment