官术网_书友最值得收藏!

Our first Dockerfile

Now that we know a little bit about how to get around containers, this is a good place to try out creating our own container. To start building a container, the first thing that we need to know is that the default filename that Docker looks for when building images is Dockerfile. While you can use different names for this main configuration file, it is highly discouraged though in some rare cases, you might not be able to avoid it - if, for example, you need a test suite image and the main image build files in the same folder. For now, we will assume you just have a single build configuration, and with that in mind, how about we see what one of these basic Dockerfile looks like. Create a test folder somewhere on your filesystem and put this into a file named Dockerfile:

FROM ubuntu:latest

RUN apt-get update -q && \
apt-get install -qy iputils-ping

CMD ["ping", "google.com"]

Let's examine this file line by line. First, we have the FROM ubuntu:latest line in there. This line indicates that we want to use the latest Ubuntu Docker image as our base on which we will layer our own service. This image will be automatically pulled from Docker Hub, but this image can also be from a custom repository, your own local image, and could be based on any other image as long as it provides a good base for your service (that is, NGINX, Apline Linux, Jenkins, and so on) if we wanted to.

The next line is very important as the base Ubuntu image does not come with almost anything out of the box, so we need to install the package that provides the ping utility (iputils-ping) through its package manager apt , just like we would on the command line by using the RUN directive to Docker. Before we install it, though, we also need to make sure that our update indexes are up-to-date, and we use apt-get update for that. In a bit, we will cover in detail why we used && to chain the update and install commands, but for now, we will magically ignore it so that we don't derail our example too much.

The CMD directive instructs Docker that by default, Docker will run "ping" "google.com" every time the container is started without further arguments. This directive is used to start the service within the container, and it ties the life cycle of the container to that process, so if our ping fails, our container terminates, and vice versa. You can only have one CMD line in your Dockerfile, so be especially careful what you use it for.

Now that we have the whole container configured, let's build it:

$ # Build using Dockerfile from current directory and tag our resulting image as "test_container"
$ docker build -t test_container .

Sending build context to Docker daemon 1.716MB
Step 1/3 : FROM ubuntu:latest
---> 14f60031763d
Step 2/3 : RUN apt-get update -q && apt-get install -qy iputils-ping
---> Running in ad1ea6a6d4fc
Get:1 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
<snip>
The following NEW packages will be installed:
iputils-ping libffi6 libgmp10 libgnutls-openssl27 libgnutls30 libhogweed4
libidn11 libnettle6 libp11-kit0 libtasn1-6
0 upgraded, 10 newly installed, 0 to remove and 8 not upgraded.
Need to get 1304 kB of archives.
<snip>
Setting up iputils-ping (3:20121221-5ubuntu2) ...
Processing triggers for libc-bin (2.23-0ubuntu9) ...
---> eab9729248d9
Removing intermediate container ad1ea6a6d4fc
Step 3/3 : CMD ping google.com
---> Running in 44fbc308e790
---> a719d8db1c35
Removing intermediate container 44fbc308e790
Successfully built a719d8db1c35
Successfully tagged test_container:latest

As the comment on it implies, what we did here with docker build -t test_container . is that we built the container (using the default Dockerfile configuration name) in our current directory and tagged it with the name test_container. Since we didn't specify the version at the end of test_container, Docker assigned us one called latest, as we can see from the end of the output. If we carefully examine the output, we can also see that each change to the base image creates a new layer and that layer's ID is then used as the input into the next directive, each layer creating its own filesystem diff onto the image. If, for example, we run the build again, Docker is smart enough to know that nothing has changed and it will use the cached version of those layers again. Compare the final container ID (a719d8db1c35) with the one from the previous run:

$ docker build -t test_container .

Sending build context to Docker daemon 1.716MB
Step 1/3 : FROM ubuntu:latest
---> 14f60031763d
Step 2/3 : RUN apt-get update -q && apt-get install -qy iputils-ping
---> Using cache
---> eab9729248d9
Step 3/3 : CMD ping google.com
---> Using cache
---> a719d8db1c35
Successfully built a719d8db1c35
Successfully tagged test_container:latest

If any change is detected in the directives of the Dockerfile, Docker will rebuild that layer and any subsequent ones to ensure consistency. This functionality and selective "cache busting" will also be covered later and it has a very important role in managing your repository and image sizes.

With the container built, let's see whether it actually works (to exit its loop, press Ctrl + C):

$ # Run the image tagged "test_container"
$ docker run test_container

PING google.com (216.58.216.78) 56(84) bytes of data.
64 bytes from ord30s21-in-f14.1e100.net (216.58.216.78): icmp_seq=1 ttl=52 time=45.9 ms
64 bytes from ord30s21-in-f14.1e100.net (216.58.216.78): icmp_seq=2 ttl=52 time=41.9 ms
64 bytes from ord30s21-in-f14.1e100.net (216.58.216.78): icmp_seq=3 ttl=52 time=249 ms
^C
--- google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 41.963/112.460/249.470/96.894 ms

Another success! You wrote your first running Docker container!

主站蜘蛛池模板: 西丰县| 临洮县| 抚宁县| 天柱县| 彰武县| 滁州市| 石门县| 江川县| 元氏县| 新民市| 昌乐县| 双流县| 温泉县| 疏勒县| 交城县| 长顺县| 黄平县| 梁山县| 诏安县| 诸城市| 综艺| 白河县| 合川市| 泰来县| 海晏县| 滨州市| 砚山县| 桦川县| 丹巴县| 漳平市| 汾西县| 萍乡市| 嘉义市| 库伦旗| 青田县| 乐至县| 承德市| 吴川市| 唐海县| 时尚| 漳平市|