Skip to content

Instantly share code, notes, and snippets.

@G-Goldstein
Last active March 1, 2019 13:58
Show Gist options
  • Save G-Goldstein/107116b16f15d4d7abb2f1b3d7740c7a to your computer and use it in GitHub Desktop.
Save G-Goldstein/107116b16f15d4d7abb2f1b3d7740c7a to your computer and use it in GitHub Desktop.
Docker Dojo session 2

Main process, and container lifecycle

https://hub.docker.com/_/busybox

For busybox, the default execution is sh. So, after using run, we find ourselves in a shell environment:

docker run -it busybox

But we can specify an alternate command to run in the busybox container by appending it to the Docker run command:

docker run -it busybox echo Hello World!
docker run -it busybox whoami
docker run -it busybox pwd
docker run -it busybox ls
docker run -it busybox ls /bin/

The above commands run a busybox container, but with our own command instead of sh. Our command controls the "main process", and the container stops when this main process ends.

But each run operation creates a brand new container from the image! If we modify one container, we can't see the changes in the next:

docker run -it busybox echo "Hello World!" > hello.txt
docker run -it busybox cat hello.txt

Our first Dockerfile

Image builds are defined using the Dockerfile. This is a text file that, by default, is named Dockerfile. Make sure your text editor doesn't add an extension to the name!

Each image we make is built on top of another image. The FROM instruction usually appears at the top of the Dockerfile and tells us what image we're building on.

The CMD instruction sets the command to be run when the container starts. Multiples are redundant; only the last one is used.

FROM busybox
CMD ["echo", "Hello World!"]

To build a Docker image, you must specify a tag for the image. The tag is what Docker will call the image. You must also specify the location of the Dockerfile used to build it:

docker build -t <image_tag> <path_to_dockerfile>

We're usually working in the directory of the Dockerfile, so the path is just .:

docker build -t hellodojo .

Once built, our image is as genuine as the ones we've downloaded. We can use it in all the same ways:

docker run -it hellodojo

Including overriding the command entirely, if we wish:

docker run -it hellodojo echo Hello Graham!

More Docker instructions

ENTRYPOINT vs CMD

As we've seen, the CMD instruction sets a default command to run with the container, but it can be overridden in full. If we think of containers as applications, it usually doesn't make sense to override the whole command, but it might make sense to specify arguments.

The ENTRYPOINT instruction tells Docker the base command that we'll always want to run in this container. Users can then add their own arguments at run time.

Let's create a Dockerfile to test this:

FROM busybox
ENTRYPOINT ["echo"]
CMD ["Hello World!"]

We'll need to build this again using the docker build steps from above. If we use the same name, our previous image will be overwritten.

When we specify no command, we get the same behaviour as before:

docker run -it hellodojo

But our echo command is implicit now. We can simply pass the text and our container will echo it:

docker run -it hellodojo Hello Graham!

If we want to override the entrypoint to, e.g., explore the container, we can still do that with the --entrypoint argument:

docker run -it --entrypoint=sh hellodojo

The RUN instruction

While ENTRYPOINT and CMD tell us what to run at the runtime of the container, RUN instructions run, in order, during the building of the image. We can use them to install software, download and extract zip files, and do anything else that we might do on the command line when setting up an application.

FROM busybox
RUN echo "Hello World!" > hello.txt
CMD ["cat", "hello.txt"]

During the build process, Docker will create file hello.txt in the image. When we run a container from this image, it will concatenate the output of the hello.txt file, giving the now typical greeting.

We can also see the new file in the container's directory structure if we list the directory contents:

docker run -it hellodojo ls
@G-Goldstein
Copy link
Author

I need to add some mention of the COPY instruction here, and give an example.

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