docker-create-image
Create docker image
There are several ways to create an image, you can create it by
$ docker commit
# from an existingcontainer
$ docker load
# from a savedtar package
$ docker build
# from aDockerfile
or from standard input
Here I only say how to create an image from Dockerfile, for other ways, please refer to docker command that I posted earlier.
Basically speaking, Dockerfile is a sequence of instructions
in order, docker parses these instructions
one by one created layer when necessary, at last generates an image with these layers and conf.
Here is an overview of all instructions that docker provided, I will explain some of them later on with more details.
instructions
Here is just a basic usage of some commands, details refer to
- FROM: Sets the base image for subsequent
- MAINTAINER: set the author field of the generated images(deprecated use LABEL instead)
RUN: Execute commands in a new layer on top of the current image and commit the result
CMD: Allow only one CMD as the start command when container starts
- LABEL: Add metadata to an image
- EXPOSE: Informs container runtime that the container listens on the specified network ports at runtime, it’s just declaration
- ENV: Sets an environment variable
ADD: Copy new files or directories or remote file URLs from into the filesystem of the container, it can process tar, deb etc uncompressed then copy
COPY: Copy new files or directories into the filesystem of the container
ENTRYPOINT: Allows you to configure a container that will run as an executable
VOLUME: Creates a mount point and marks it as holding externally mounted volumes from native host or other containers
Here is an example of Dockerfile, see comments for more details
1 | # from base image to create new |
There are several rules that you must obey to avoid troubles
- Write one CMD in Dockerfile, if many, the last on takes effect
- Better to use CMD or ENTRYPOINT, not both, if both used, CMD will be passed to ENTRYPOINT as parameter
- CMD may be overwritten by command from cli $docker run nginx /bin/bash, /bin/bash overwrites CMD in nginx image
- Remove unnecessary files when do apt-get
- Avoid RUN apt-get upgrade and dist-upgrade
NOTE: instruction in Dockerfile may be overwritten by parameter from cli, like ENTRYPOINT may be overwritten by docker run –entrypoint, so check what conf container uses by
$docker inspect $container_id(name)
how build works
When you issue a docker build command, the current working directory is called the build context, all recursive contents of files and directories in the current directory are sent to the Docker daemon
, but only the ones used by Dockerfile is copied to image, other is not used!!!, docker client(issuer) and docker daemon can be at different machines, in that case, make sure there is no unnecessary files under current dir, as all files will be sent to docker daemon, it may take long timer if the current dir is large, after docker daemon receives all and parses Dockerfile and execute each instruction one by one with order, create layer if necessary or set conf for this image, at last save image to the local registry of machine where docker daemon is running.
Actually before it runs, docker daemon created a temporary for this image and chroot to it, so that the destination path(ADD ./test.tar /
) in Dockefile is for the new rootfs
build an image
from a file
1 | $ ls |
from standard input
1 | # t is image name |
check info about image
check instructions used by an image
1
2
3
4
5
6
7
8
9$ docker history $image_id(name) --no-trunc
$ docker history $image_id(name)
IMAGE CREATED CREATED BY SIZE COMMENT
output:
5a9061639d0a 26 hours ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
<missing> 26 hours ago /bin/sh -c #(nop) STOPSIGNAL SIGTERM 0B
<missing> 26 hours ago /bin/sh -c #(nop) EXPOSE 80 0B
<missing> 26 hours ago /bin/sh -c ln -sf /dev/stdout /var/log/nginx… 22Bcheck instructions with full content of an image
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25cat /var/lib/docker/image/aufs/imagedb/content/sha256/5a9061639d0aeca4b13f8e18b985eea79e55168969d069febdb6723993ebba7d | python -m json.tool
output:
...
"history":[
{
"created": "2019-10-17T04:43:59.291372925Z",
"created_by": "/bin/sh -c ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log"
},
{
"created": "2019-10-17T04:43:59.546729941Z",
"created_by": "/bin/sh -c #(nop) EXPOSE 80",
"empty_layer": true
},
{
"created": "2019-10-17T04:43:59.807233891Z",
"created_by": "/bin/sh -c #(nop) STOPSIGNAL SIGTERM",
"empty_layer": true
},
{
"created": "2019-10-17T04:44:00.059327535Z",
"created_by": "/bin/sh -c #(nop) CMD [\"nginx\" \"-g\" \"daemon off;\"]",
"empty_layer": true
}
]As you can see some instructions Did NOT create layer at all, see ‘empty_layer’ field.
check the config for an image
1
2
3$ docker images
$ docker inspect 5a9061639d0a
# this will show what's the cmd, env, entrypoint, volume, rootfs etc for this image