|
| 1 | +== Docker Image |
| 2 | + |
| 3 | +*PURPOSE*: This chapter explains how to create a Docker image. |
| 4 | + |
| 5 | +As explained in <<Docker_Basics>>, Docker image is the *build component* of Docker and a read-only template of application operating system. |
| 6 | + |
| 7 | +=== Dockerfile |
| 8 | + |
| 9 | +Docker build images by reading instructions from a _Dockerfile_. A _Dockerfile_ is a text document that contains all the commands a user could call on the command line to assemble an image. `docker build` command uses this file and executes all the commands in succession to create an image. |
| 10 | + |
| 11 | +`build` command is also passed a context that is used during image creation. This context can be a path on your local filesystem or a URL to a Git repository. |
| 12 | + |
| 13 | +_Dockerfile_ is usually called _Dockerfile_. The complete list of commands that can be specified in this file are explained at https://docs.docker.com/reference/builder/. The common commands are listed below: |
| 14 | + |
| 15 | +.Common commands for Dockerfile |
| 16 | +[width="100%", options="header", cols="1,4,4"] |
| 17 | +|================== |
| 18 | +| Command | Purpose | Example |
| 19 | +| FROM | First non-comment instruction in _Dockerfile_ | `FROM ubuntu` |
| 20 | +| COPY | Copies mulitple source files from the context to the file system of the container at the specified path | `COPY .bash_profile /home` |
| 21 | +| ENV | Sets the environment variable | `ENV HOSTNAME=test` |
| 22 | +| RUN | Executes a command | `RUN apt-get update` |
| 23 | +| CMD | Defaults for an executing container | `CMD ["/bin/echo", "hello world"]` |
| 24 | +| EXPOSE | Informs the network ports that the container will listen on | `EXPOSE 8093` |
| 25 | +|================== |
| 26 | + |
| 27 | +=== Create your first Docker image |
| 28 | + |
| 29 | +_Hello World_ Dockerfile is shown: |
| 30 | + |
| 31 | +.Hello World Dockerfile |
| 32 | +[source, text] |
| 33 | +---- |
| 34 | +FROM ubuntu |
| 35 | +
|
| 36 | +CMD ["/bin/echo", "hello world"] |
| 37 | +---- |
| 38 | + |
| 39 | +This image uses `ubuntu` as the base image. `CMD` command defines the command that needs to run. It provides a different entry point of `/bin/echo` and gives the argument "`hello world`". |
| 40 | + |
| 41 | +Build this image as: |
| 42 | + |
| 43 | +[source, text] |
| 44 | +---- |
| 45 | +> docker build -t helloworld . |
| 46 | +Sending build context to Docker daemon 2.048 kB |
| 47 | +Step 0 : FROM ubuntu |
| 48 | +Pulling repository docker.io/library/ubuntu |
| 49 | +a5a467fddcb8: Download complete |
| 50 | +3fd0c2ae8ed2: Download complete |
| 51 | +9e19ac89d27c: Download complete |
| 52 | +ac65c371c3a5: Download complete |
| 53 | +Status: Downloaded newer image for ubuntu:latest |
| 54 | + ---> a5a467fddcb8 |
| 55 | +Step 1 : CMD /bin/echo hello world |
| 56 | + ---> Running in 132bb0bf823f |
| 57 | + ---> e81a394f71e3 |
| 58 | +Removing intermediate container 132bb0bf823f |
| 59 | +Successfully built e81a394f71e3 |
| 60 | +---- |
| 61 | + |
| 62 | +List the images available: |
| 63 | + |
| 64 | +[source, text] |
| 65 | +---- |
| 66 | +> docker images |
| 67 | +REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE |
| 68 | +helloworld latest 9c0e7b56cbee 13 minutes ago 187.9 MB |
| 69 | +---- |
| 70 | + |
| 71 | +Run the container: |
| 72 | + |
| 73 | + docker run -it helloworld |
| 74 | + |
| 75 | +to see the output: |
| 76 | + |
| 77 | + hello world |
| 78 | + |
| 79 | +Change the base image from `ubuntu` to `busybox`, build the image again: |
| 80 | + |
| 81 | + docker build -t helloworld2 . |
| 82 | + |
| 83 | +[source, text] |
| 84 | +---- |
| 85 | +> docker images |
| 86 | +REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE |
| 87 | +helloworld latest e81a394f71e3 26 minutes ago 187.9 MB |
| 88 | +helloworld2 latest c458787fadcf 3 seconds ago 1.113 MB |
| 89 | +ubuntu latest a5a467fddcb8 2 days ago 187.9 MB |
| 90 | +busybox latest 3d5bcd78e074 4 days ago 1.113 MB |
| 91 | +---- |
| 92 | + |
| 93 | +==== Run WildFly |
| 94 | + |
| 95 | +Create a new text file _Dockerfile_ in an empty directory: |
| 96 | + |
| 97 | +[source, text] |
| 98 | +---- |
| 99 | +FROM jboss/wildfly |
| 100 | +---- |
| 101 | + |
| 102 | +Build the image: |
| 103 | + |
| 104 | + docker build -t mywildfly . |
| 105 | + |
| 106 | +Run the container: |
| 107 | + |
| 108 | + docker run -it mywildfly |
| 109 | + |
| 110 | +==== Deploy Java EE 7 Application |
| 111 | + |
| 112 | +Create a new text file _Dockerfile_ in an empty directory: |
| 113 | + |
| 114 | +[source, text] |
| 115 | +---- |
| 116 | +FROM jboss/wildfly |
| 117 | +
|
| 118 | +CMD ["/opt/jboss/wildfly/bin/standalone.sh", "-c", "standalone-full.xml", "-b", "0.0.0.0"] |
| 119 | +
|
| 120 | +RUN curl -L https://github.com/javaee-samples/javaee7-hol/raw/master/solution/movieplex7-1.0-SNAPSHOT.war -o /opt/jboss/wildfly/standalone/deployments/movieplex7-1.0-SNAPSHOT.war |
| 121 | +---- |
| 122 | + |
| 123 | +Three things happen in this image: |
| 124 | +. Uses "`jboss/wildfly`" as the base image |
| 125 | +. Starts WildFly application server in Full Platform mode |
| 126 | +. Copies the WAR file from from a URL to the deployment directory of WildFly |
| 127 | + |
| 128 | +Build the image: |
| 129 | + |
| 130 | + docker build -t movieplex . |
| 131 | + |
| 132 | +==== Difference between CMD and ENTRYPOINT |
| 133 | + |
| 134 | +*TL;DR* `CMD` will work for most of the cases. |
| 135 | + |
| 136 | +Default entry point for a container is `/bin/sh`, the default shell. |
| 137 | + |
| 138 | +Running a container as `docker run -it ubuntu` uses that command and starts the default shell. The output is shown as: |
| 139 | + |
| 140 | +[source, text] |
| 141 | +---- |
| 142 | +> docker run -it ubuntu |
| 143 | +root@88976ddee107:/# |
| 144 | +---- |
| 145 | + |
| 146 | +`ENTRYPOINT` allows to override the entry point to some other command, and even customize it. For example, a container can be started as: |
| 147 | + |
| 148 | +[source, text] |
| 149 | +---- |
| 150 | +> docker run -it --entrypoint=/bin/cat ubuntu /etc/passwd |
| 151 | +root:x:0:0:root:/root:/bin/bash |
| 152 | +daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin |
| 153 | +bin:x:2:2:bin:/bin:/usr/sbin/nologin |
| 154 | +sys:x:3:3:sys:/dev:/usr/sbin/nologin |
| 155 | +. . . |
| 156 | +---- |
| 157 | + |
| 158 | +This command overrides the entry point to the container to `/bin/cat`. The argument(s) passed to the CLI are used by the entry point. |
| 159 | + |
| 160 | +==== Difference between ADD and COPY |
| 161 | + |
| 162 | +*TL;DR* `COPY` will work for most of the cases. |
| 163 | + |
| 164 | +`ADD` has all capabilities of `COPY` and has the following additional features: |
| 165 | + |
| 166 | +. Allows tar file auto-extraction in the image, for example, `ADD app.tar.gz /opt/var/myapp`. |
| 167 | +. Allows files to be downloaded from a remote URL. However, the downloaded files will become part of the image. This causes the image size to bloat. So its recommended to use `curl` or `wget` to download the archive explicitly, extract, and remove the archive. |
| 168 | + |
| 169 | +=== Import and export images |
| 170 | + |
| 171 | +Docker images can be saved using `save` command to a .tar file: |
| 172 | + |
| 173 | + docker save helloworld > helloworld.tar |
| 174 | + |
| 175 | +These tar files can then be imported using `load` command: |
| 176 | + |
| 177 | + docker load -i helloworld.tar |
| 178 | + |
| 179 | + |
0 commit comments