Writing Dockerfile: a best practice by which your containers are efficient as well as safe. Here's an example of essentials, well-structured that refer to the best practices while writing Dockerfiles.
Best Practices while Writing Dockerfiles
Base Image: Always start with a trusted base image like alpine or ubuntu. This ensures security and compatibility.
Minimize Layers Concatenation of commands- There should be lesser layers. For example, each of the RUN, COPY, and ADD command creates a layer. Minimizing that will make your images light. Use Multi-Stage Builds For complex apps, multi-stage builds give you the option to separate the build environment from the runtime, which gives you smaller final images.
Utilize caching: commands should be placed at the bottom in such a way that the least changing part should be placed. Due to the fact that Docker caches the layers putting static or not frequently updated instruction in earlier would speed up the rebuilding.
Least Privileges: Use the USER directive with as much as a non-root user as possible for additional security
Smaller Images: Reduce the final image by removing unwanted files through using the slim base images and minimize the images size that in turn improves performance.
Use .dockerignore: Exclude files that aren't needed in the container so that the image isn't cluttered and the build context size is smaller.
Health Checks: A HEALTHCHECK directive defines how Docker should monitor the health of the container. In this manner, the containers can be automatically restarted if needed.
Environment Variables: The ENV directive should be used to set your configuration so as not to hard code values within your Dockerfile.
Example of a Well-Structured Dockerfile
Here’s an example Dockerfile for a simple Node.js application:
Explanation of the Dockerfile
Multi-Stage Build: Here, the Dockerfile uses two stages. The first build stage will create the Node.js application, but then there's a second stage that uses a very small lightweight Nginx image to run as a server for static files, bringing the size of the final image down significantly.
Efficient Dependency Management: Simply copying the package*.json files first and performing npm install only propagates dependencies through a different mechanism that isolates them from the source code. This makes builds much faster if not so frequently updated due to changes in dependencies.
Health Check: HEALTHCHECK Instruction The HEALTHCHECK instruction essentially tells Docker to run a health check on the container. Here, it checks whether application is responding at localhost so Docker restarts the container when it is not responding.
Extremally Thin Base Image: This step utilizes nginx:alpine, the lightest possible image in production, which should make the image small and secure.
If you're looking for a better career, I personally suggest you take the DevOps Post Graduate Program!