User:Tsu2/docker-build-tutorial-1
Docker - Introduction to image building
Docker
If you haven't installed Docker on your openSUSE yet,
Install docker on openSUSE
If you have arrived here using some other distro as your HostOS, everything on this page should work without major modifications (Debian/Ubuntu users may need to append "sudo" if docker has not been configured to use regular User permissions which I consider questionable practice). Just download the opensuse image with the following command or modify to use your preferred OS image
docker pull opensuse
Building Custom Docker images - Why?
Docker supports the deployment of everything from simple single apps to full stack apps to full OS, but you will generally want to modify the deployment to your own taste, Generally speaking, public images are generic without even default configurations for even basic functionality. Typically these settings need to be declared, and they can include special network configurations, special files to be used, access to specific files and volumes, and plenty more.
So, for instance I personally aim to use Docker to configure multiple nodes in a cluster running the same application but with both unique and common settings so that each can be uniquely identified in the cluster while still knowing that they will need to discover and share data with other nodes in the cluster.
The overall strategy to accomplish this is to deploy the <same> basic app to every node but to uniquely configure each instance of the app.
Note that there are other uses for running Docker. You can run and test different distros, distro versions and apps on your machine without fear of mangling your base OS, and without the overhead of traditional virtualization based on kernel paravirtualization like VMware, KVM, Virtualbox, Parallels, Hyper-V, etc.
Dockerizing - Basic Concepts
A generic docker image typically is minimally configured with default application settings, but unable to communicate outside its container.
Reasons for creating a custom image include
- Although an app (possibly service) may be configured to listen for inbound connections, docker must be instructed to accept connections. This can be done with the EXPOSE instruction in a Dockerfile which will work with the port mapping instruction when a container is created (docker run -p hostport:containerport) - Run commands on container startup. A single command without attributes/flags can be implemented with the CMD while a command while attributes can be passed to a command with the ENTRYPOINT instruction. - RUN commands execute common and arbitrary commands during the Build
When considering what should be in the Dockerfile, it requires an understanding what the application is trying to do and its requirements, and what is trying to connect to the app in the container.
In general, the Dockerfile describes steps to modify the application, the application's settings and instructs Docker to permit inbound connections on specific ports.
Tutorial Description
The following short tutorial covers the basics of building a simple dockerfile that creates a custom image running the "ps" app. The first build configures CMD ps to run without any options, the second build invokes ps with "ENTRYPOINT" which supports passing a command line option.
This tutorial assumes you are using vim or similar console text editor, but any editor including a GUI editor can be used as long as invisible characters aren't inserted into your files (which Windows Notepad, Word and other MS text editors typically do).
Building a simple Custom Docker Image using a Dockerfile
Based on
http://www.kstaken.com/blog/2013/07/06/how-to-use-entrypoint-in-a-dockerfile/
Passing the CMD
1. View local images (you will need an OS image)
docker images
2. Create a directory you wish to use as your working directory
mdkir <workingdirectory>
cd <workingdirectory>
3. Create a dockerfile called Dockerfile (must be capitalized) which executes ps
vi Dockerfile
> FROM opensuse
> CMD ["ps"]
4. Create the image with the new dockerfile. Note that the followng command "tags" the name as "ps" and points to the working directory
$ docker build -t=ps ./
5. Verify your image was created
docker images
6. Create/run a container using your new image
docker run ps
This displays the proecesses running in the container. Most likely you will only have one process running Note that as soon as the ps results are displayed the container exits and is no longer running (following displays running containers) docker ps
Now what if we want to pass options to the app running in the container? Simply appending to the existing container command won't work.
Note that running "docker run" each time creates a new image with a new imageid and new random name.
If you want to re-use a container you should run "docker start" referencing the unique Container_ID, the random name generated or a name set with "tag="
Entrypoint
Following the above steps creating a simple container that runs the ps app within an openSUSE environment, What if you wanted to pass an option to the ps application? You can't just append the command like in a regular console, So for example the following will fail
docker run ps aux
The Entrypoint is one of many possible options which can be set in the dockerfile when building a custom image
vi Dockerfile
remove the text "CMD ps"
and enter
ENTRYPOINT ["ps"]
Then, save your file.
Your dockerfile should now have contents which looks exactly like the following
FROM opensuse
ENTRYPOINT ["ps"]
Rebuild the image, personally I would recommend a different image name to keep from crushing the old image. This makes for cleaner housekeeping
docker build -t=ps_aux ./
Today's behavior seems to support running ENTRYPOINT without passing a specified option similar to CMD Build and run a container without the "aux" option
docker run ps_aux
Now, create a container which passes the "aux" option
docker run ps_aux aux
Cleaning Up, Removing Images and Containers
Each of the containers created above are "single use" and worthless to keep. So, let's remove the containers and images created in this exercise. Before you can remove any image, you must first remove any containers that were built on those images. If you con't remember which containers were created, list all inactive and active containers as follows
docker ps -a
If the above steps were followed exactly you should see containers created within the past few minutes. You can now run the following command specifying the container name or the first few digits of the containerid. You can remove more than one container with the same command by separating each containername with a space.
docker rm containername_or_id
Docker should confirm removal by repeating each containername as it's removed
You should then be able to remove the images that were used in this exercise with the following command, note that the syntax for removing images is the same as removing containers but the command is "rmi"
docker rmi ps ps_aux
More Info
The following is the official reference that describes all the options which can be set in the dockerfile
Docker Build Documentation - Dockerfile Reference