Home >Technology peripherals >It Industry >How to Build an Image with the Dockerfile
From building applications, installing dependencies and services, to automated deployment, and more - it all starts with Dockerfile. Let's review the syntax of Dockerfile, from basic to complexity, and some best practices when building Docker images.
This guide will write a Dockerfile that guides Docker to select a minimized Linux (base image) for the applications we will deliver, and comes with our selected toolset and specific configuration to effectively build our own Linux distribution , this distribution is just right suitable for running our applications.
With Docker you can "build, deliver, and run any application, no matter where you are." That is, you can package your application with all the binary and runtime libraries, backend tools, operating system tuning and even specific services required for the application to run – and enable it to be delivered and deployed automatically .
Docker implemented software container technology makes this possible. Although I won't go into the details behind it here, you can read more about Docker, what software containers are and how they work in Understanding Docker, Containers, and Safer Software Delivery.
Installing Docker
Luckily, the latest version of Docker (version 1.12 as of this writing) makes the installation process very smooth, and you can get a simple and easy-to-understand guide for Windows, MacOS, and Linux.
To build the image in Docker, you first need to set the directive for this build and the context in a plain text file called Dockerfile (more on this later). This file has a syntax similar to the Apache configuration file—one instruction per line and its corresponding parameters, all instructions are processed in sequence. Comments begin with # characters and spaces. Finally, once you have the Dockerfile, the command docker build will build the image, which we will cover in more detail later.
Before we start writing the Dockerfile, we will set up the workspace. We will create a directory called my_image in the home directory, use it as our working directory, and place the Dockerfile in it:
<code class="language-bash">mkdir ~/my_build cd ~/my_build touch Dockerfile</code>
Now we are ready to start building the image.
When creating an image, in most cases you will use one starting point—i.e. another image. This could be the official Ubuntu, MySQL, WordPress, or any other image available in Docker Hub. You can also use the images you created yourself before.
Note: You can create your own basic image using Docker's minimum image (called scratch) that contains your own core tools and directory structure. I won't cover this process here, but you can refer to the guide on creating basic images on the Docker website.
For example, if you want to start with a minimized Debian distribution, you will add the following to your Dockerfile:
<code class="language-dockerfile"># 设置基础镜像 FROM debian</code>
FROM must be the first instruction you use when writing a Dockerfile. Note that you can also use a specific version of the base image by appending: and version_name at the end of the image name. For example:
<code class="language-dockerfile"># 设置基础镜像 FROM debian:sid</code>
In the above code, we are using "sid" Debian (unstable distribution). This is also important when you need a specific version of Ruby or Python interpreter, MySQL version, etc. when you use the official basic image of any of these tools. Currently, in this guide, we will stick to the default (stable) debian image.
You can choose to specify who the maintainer is, replace Lucero del Alba with your name or person or team responsible for the construction:
<code class="language-dockerfile"># 作者 MAINTAINER Lucero del Alba</code>
This is not required, but we can also add some metadata using the LABEL directive, which will be available later when checking the image using the docker inspect command:
<code class="language-dockerfile"># 额外的元数据 LABEL version="1.0" LABEL description="First image with Dockerfile."</code>
For more information about this feature, see the Docker Object Tag.
At this point, we will select some tools and libraries to include in the mirror so that our container has everything we need to perform the expected action. At the end of this tutorial, we will do a job that is very close to actually building a Linux distribution.
Some containers (such as those running PostgreSQL databases) are designed to run in the background. However, we often need a console to perform certain operations on the container, so we may need some extra tools because the underlying image will only bundle the minimum GNU tools.
You will almost certainly have caching issues when trying to install additional packages on your image. This is because the underlying image has cached metadata and the real-time repository from which you extract data changes frequently.
In a Debian-based distribution, you can add the following command before installing a new package to handle this:
<code class="language-bash">mkdir ~/my_build cd ~/my_build touch Dockerfile</code>
Tools like code editor, locale, git or tmux - now is the time to install everything you need afterwards so they are bundled in the image.
We will install one per line:
<code class="language-dockerfile"># 设置基础镜像 FROM debian</code>
We can install all of this in one line, but if we want to add or remove packages later, we need to rerun the whole process. So the best practice here is to install one package per line so that you can benefit from Docker's cache.
In addition, keep it simple. You don't want to install the tool "just in case" as this may increase build time and image size.
We will also deliver our application in this image. Do you need a specific version of PHP, Ruby or Python, and some modules? Now is the time to deliver all the programs and runtimes needed to deliver the application.
You can specify as you like, as this container is designed to run your application only:
In this example, we will install Python 3 along with Psycopg 2 (for connecting to PostgreSQL database), Python Mustache module, and YAML module. (When you create your own Dockerfile, you will naturally install the specific dependencies you need.)<code class="language-dockerfile"># 设置基础镜像 FROM debian:sid</code>
Compilation and download package
You can even script this file on a separate file, add this file to the build and run it, which we will see in the Delivery Your Own Application section.
Cleaning
Also, please note that we are using apt-get because we chose Debian, but please use the corresponding command for the distribution of the base image.
<code class="language-dockerfile"># 作者 MAINTAINER Lucero del Alba</code>Deliver your own application
The whole purpose of building this environment is to enable you to deliver your application smoothly and get ready to run. To add the contents of files, directories, and even remote URLs to the image, we will use the ADD directive.
context. To simplify operations, we put everything in the aforementioned my_build directory, along with the Dockerfile itself.
Assuming using the app and everything we want to put into the image, we have the following files in ~/my_build (where app.py and lib.py are in the subdirectory app/):
<code class="language-bash">mkdir ~/my_build cd ~/my_build touch Dockerfile</code>
We add the .bashrc and .profile scripts to the /root directory in the container so that they execute when we start the shell on the container and copy the contents of app/ to the /app/ directory in the container.
We add the following command:
<code class="language-dockerfile"># 设置基础镜像 FROM debian</code>
Finally, we will set some environment variables that are needed at both the system and application level.
Many of you use the default Debian character set to do it, but since we are targeting an international audience, let's see how to have a UTF-8 terminal. We installed the locales package before, so now all we have to do is generate the character set and set up the appropriate Linux environment:
<code class="language-dockerfile"># 设置基础镜像 FROM debian:sid</code>
You may also need to set some environment variables for the application to exchange passwords and paths. Dockerfile provides ENV instructions to do this accurately:
<code class="language-dockerfile"># 作者 MAINTAINER Lucero del Alba</code>
Note that you can also pass environment variables from the command line when starting the container, which may be convenient for sharing some sensitive information (such as passwords).
Of course, you have to adjust the Dockerfile as you want, but hopefully you understand its possibilities.
This is the complete file:
<code class="language-dockerfile"># 额外的元数据 LABEL version="1.0" LABEL description="First image with Dockerfile."</code>
From inside the my_build directory, we will use the docker build command, passing the -t flag to "tag" the new image with the name, in this case my_image. . Indicates that the Dockerfile is in the current directory, and the so-called "context" - that is, the remaining files that may exist in that location:
<code class="language-dockerfile"># 更新源列表 RUN apt-get clean RUN apt-get update</code>
This will generate a long output where each "step" is a directive in our Dockerfile. Here is a truncated output:
<code class="language-dockerfile"># 每行安装一个基本应用程序,以获得更好的缓存 RUN apt-get install -qy git RUN apt-get install -qy locales RUN apt-get install -qy nano RUN apt-get install -qy tmux RUN apt-get install -qy wget</code>
We can use the docker images command to list our images:
<code class="language-dockerfile"># 安装应用程序运行时和模块 RUN apt-get install -qy python3 RUN apt-get install -qy python3-psycopg2 RUN apt-get install -qy python3-pystache RUN apt-get install -qy python3-yaml</code>
This will output our newly created my_image and other basic images we downloaded:
<code class="language-dockerfile"># 清理 RUN apt-get -qy autoremove</code>
…That's it, our mirror is ready to be delivered and run!
Finally, in order to start our newly created interactive terminal, we will use the docker run command:
<code>.bashrc .profile app/app.py app/lib.py Dockerfile</code>
I did not introduce all the possibilities of Dockerfile. In particular, I did not review how EXPOSE ports so that you can run services and even link containers between them; how HEALTHCHECK containers to verify that they are still working; even how to specify VOLUME to store and recover data from the host... and other useful features.
We will introduce these in future articles. Currently, you may want to check out the following resources.
From Docker website:
From SitePoint:
Dockerfile is a text document containing all commands that the user can call on the command line to assemble the image. Using Dockerfile simplifies the process of building images in Docker. It allows you to automate the process, making it more efficient and less prone to errors. Dockerfile also provides clear, versioning documentation on how to build images, which makes it easier for other developers to understand your work and use or modify it.
Dockerfile provides a variety of ways to optimize the build process. One of the most effective ways is to use multi-stage builds. This allows you to use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different foundation, and each instruction begins a new stage of construction. You can optionally copy artifacts from one stage to another, leaving everything you don't want to appear in the final image.
There are several best practices for writing Dockerfiles. First, you should avoid installing unnecessary packages to keep the mirror size small. Second, use multi-stage builds to optimize the build process. Third, each Dockerfile should represent a single application. If you have multiple applications, you should use multiple Dockerfiles. Finally, you should use the .dockerignore file to exclude files and directories that should not be included in the image.
Dockerfile can be debugged by building the image and running it with the shell command. If the build fails, Docker returns an error message that can help you identify the problem. You can also use the RUN command to execute commands that will help you debug your Dockerfile.
Yes, you can use environment variables in your Dockerfile. The ENV directive sets the environment variable to this value. This value will be in the environment of all subsequent instructions in the build phase and can also be replaced inline in many instructions.
You can use the COPY directive to copy new files from the host to the Docker image. Copy files from source on the host to the destination in the Docker image.
You can use the EXPOSE directive to notify the Docker container to listen for a specified network port at runtime. However, this does not actually publish the port. To publish a port, you need to use the -p flag on the docker run command.
You can use the WORKDIR directive to set the working directory for any subsequent RUN, CMD, ENTRYPOINT, COPY, and ADD directives in the Dockerfile.
You can use the RUN directive to run commands in a Docker image. This will execute any command on the new layer above the current image and submit the result.
You can use the CMD directive to provide default values for the executing container. These can include executable files, or executable files can be omitted, in which case you must specify the ENTRYPOINT directive.
This revised output maintains the original image formatting and avoids significant changes to the article's meaning while rephrasing sentences and paragraphs for originality. Remember to replace /uploads/20250218/...
with the actual image URLs.
The above is the detailed content of How to Build an Image with the Dockerfile. For more information, please follow other related articles on the PHP Chinese website!