Today we will learn everything about docker image. You might wonder how a Dockerfile creates an Image which runs a container. We will see all the commands which are used in Dockerfile like FROM, RUN, COPY, ENTRYPOINT, CMD, EXPOSE etc.
Please explain Docker Image clearly
Sure. Docker image is a bundle which is used to run a piece of software. In one sense, this is everything. If you want to run MySql, there will be a docker image for it.
This docker image consists of a Dockerfile which holds instructions which we call layers.
This is the Dockerfile for Mysql for version 8.0 –
# # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" # # PLEASE DO NOT EDIT IT DIRECTLY. # FROM oraclelinux:8-slim RUN set -eux; \ groupadd --system --gid 999 mysql; \ useradd --system --uid 999 --gid 999 --home-dir /var/lib/mysql --no-create-home mysql # add gosu for easy step-down from root # https://github.com/tianon/gosu/releases ENV GOSU_VERSION 1.14 RUN set -eux; \ # TODO find a better userspace architecture detection method than querying the kernel arch="$(uname -m)"; \ case "$arch" in \ aarch64) gosuArch='arm64' ;; \ x86_64) gosuArch='amd64' ;; \ *) echo >&2 "error: unsupported architecture: '$arch'"; exit 1 ;; \ esac; \ curl -fL -o /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$gosuArch.asc"; \ curl -fL -o /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$gosuArch"; \ export GNUPGHOME="$(mktemp -d)"; \ gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \ gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \ rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \ chmod +x /usr/local/bin/gosu; \ gosu --version; \ gosu nobody true RUN set -eux; \ microdnf install -y \ bzip2 \ gzip \ openssl \ xz \ zstd \ # Oracle Linux 8+ is very slim :) findutils \ ; \ microdnf clean all RUN set -eux; \ # https://dev.mysql.com/doc/refman/8.0/en/checking-gpg-signature.html # gpg: key 3A79BD29: public key "MySQL Release Engineering <[email protected]>" imported key='859BE8D7C586F538430B19C2467B942D3A79BD29'; \ export GNUPGHOME="$(mktemp -d)"; \ gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ gpg --batch --export --armor "$key" > /etc/pki/rpm-gpg/RPM-GPG-KEY-mysql; \ rm -rf "$GNUPGHOME" ENV MYSQL_MAJOR 8.0 ENV MYSQL_VERSION 8.0.29-1.el8 RUN set -eu; \ . /etc/os-release; \ { \ echo '[mysql8.0-server-minimal]'; \ echo 'name=MySQL 8.0 Server Minimal'; \ echo 'enabled=1'; \ echo "baseurl=https://repo.mysql.com/yum/mysql-8.0-community/docker/el/${VERSION_ID%%[.-]*}/\$basearch/"; \ echo 'gpgcheck=1'; \ echo 'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql'; \ # https://github.com/docker-library/mysql/pull/680#issuecomment-825930524 echo 'module_hotfixes=true'; \ } | tee /etc/yum.repos.d/mysql-community-minimal.repo RUN set -eux; \ microdnf install -y "mysql-community-server-minimal-$MYSQL_VERSION"; \ microdnf clean all; \ # the "socket" value in the Oracle packages is set to "/var/lib/mysql" which isn't a great place for the socket (we want it in "/var/run/mysqld" instead) # https://github.com/docker-library/mysql/pull/680#issuecomment-636121520 grep -F 'socket=/var/lib/mysql/mysql.sock' /etc/my.cnf; \ sed -i 's!^socket=.*!socket=/var/run/mysqld/mysqld.sock!' /etc/my.cnf; \ grep -F 'socket=/var/run/mysqld/mysqld.sock' /etc/my.cnf; \ { echo '[client]'; echo 'socket=/var/run/mysqld/mysqld.sock'; } >> /etc/my.cnf; \ \ # make sure users dumping files in "/etc/mysql/conf.d" still works ! grep -F '!includedir' /etc/my.cnf; \ { echo; echo '!includedir /etc/mysql/conf.d/'; } >> /etc/my.cnf; \ mkdir -p /etc/mysql/conf.d; \ # ensure these directories exist and have useful permissions # the rpm package has different opinions on the mode of `/var/run/mysqld`, so this needs to be after install mkdir -p /var/lib/mysql /var/run/mysqld; \ chown mysql:mysql /var/lib/mysql /var/run/mysqld; \ # ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime chmod 1777 /var/lib/mysql /var/run/mysqld; \ \ mkdir /docker-entrypoint-initdb.d; \ \ mysqld --version; \ mysql --version RUN set -eu; \ . /etc/os-release; \ { \ echo '[mysql-tools-community]'; \ echo 'name=MySQL Tools Community'; \ echo "baseurl=https://repo.mysql.com/yum/mysql-tools-community/el/${VERSION_ID%%[.-]*}/\$basearch/"; \ echo 'enabled=1'; \ echo 'gpgcheck=1'; \ echo 'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql'; \ # https://github.com/docker-library/mysql/pull/680#issuecomment-825930524 echo 'module_hotfixes=true'; \ } | tee /etc/yum.repos.d/mysql-community-tools.repo ENV MYSQL_SHELL_VERSION 8.0.29-1.el8 RUN set -eux; \ microdnf install -y "mysql-shell-$MYSQL_SHELL_VERSION"; \ microdnf clean all; \ \ mysqlsh --version VOLUME /var/lib/mysql COPY docker-entrypoint.sh /usr/local/bin/ RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat ENTRYPOINT ["docker-entrypoint.sh"] EXPOSE 3306 33060 CMD ["mysqld"]
This image will create a container which will run MySql. Every individual step is a layer.
Let’s understand each instruction of this Dockerfile –
FROM
FROM indicates the base image on which this container resides. Each and every image will have a base image. So, for mysql
, the base image is oraclelinux
. It’s a linux based operating system by Oracle. If you open the Dockerfile of oraclelinux, you will find that it is dependent on some other image. The most fundamental image is scratch
, which is empty and provided by docker for a start.
RUN
RUN instruction is used to run commands in the terminal of the container. You can run shell scripts and nearly all the linux commands which container is supporting. So, with this instruction, you can install libraries, essential software and much more.
ENV
ENV will help you in setting an environment variable in your container. So, you can set usernames, passwords, API keys or anything which is worth setting as environment variable.
VOLUME
VOLUME instruction indicates that the data files will be stored in given directory. In mysql, it is indicated that the database files will be store at /var/lib/mysql
.
COPY
COPY instruction is used to copy something from host machine to a container directory. You might be wondering why we didn’t use RUN instruction with cp
command of linux? Why use a separate COPY instruction. This is because cp
will copy a file within container only. Remember, RUN instruction is used to run commands inside container terminal. So, it can’t be used to transfer stuff from host node. That’s why we use COPY instruction.
EXPOSE
EXPOSE is used to open ports on container. This is very handy as we can open the required ports only and keep our container safe.
ENTRYPOINT
ENTRYPOINT instruction is used to start a command or script every time the container starts. It supports extra parameters which we can pass while running the container. For example, in our mysql image, we can pass the username, password and even the database name while running the container. So ENTRYPOINT will run docker-entrypoint.sh
and pass the provided parameters to it. You can not override this from run command. A Dockerfile can have only one ENTRYPOINT instruction.
CMD
CMD is similar to the ENTRYPOINT but you can override it completely while running container.
Kubernetes Series
- Introduction to Kubernetes
- Introduction to Docker, Containers, Images & Repository
- Install and Run Docker Images
- Docker Image – FROM, RUN, COPY, ENTRYPOINT, CMD, EXPOSE explained
- Why docker run or start command not running my container?
- How to list all docker images in system?
- How to list all docker containers?
- How to start/stop a docker container?
- Difference between docker run and docker start
- How to bind docker container port with host?
- How to get logs of docker container?
- How to live stream logs of docker container?
- Set custom name to a docker container
- Access docker container filesystem & terminal
- Getting docker details using docker inspect
- Kyverno – Installation, Policies, Testing, Reporting, Monitoring, Security
- Complete Kubernetes Project Step By Step
- Introduction to Kubernetes Objects