Thursday 3 March 2016

Dockers: Part 3 - DockerFile instructions

Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image.It actually allows you to automate the steps you would normally manually take to create an image.
Below is the format of DockerFile instructions 
INSTRUCTION arguments

DockerFile Instructions:
Docker runs the instructions in Dockerfile in order.

FROM:
First instruction must be FROM. It will specify the base image on top of which you will build your images.
FROM <image>
FROM <image>:<tag>
FROM ubuntu:14.04.3

ENV:
  1. Sets the environment variable. 
    ENV var val
    ENV var1="val1" var2="val2"
  2. It also makes interpolation in the dockerfile available from the next statement via ${var}.
  3. These variables will be persisted into any containers created from the image where these variables are defined.
RUN:
  1. Run a command and commit the image.
    RUN <command>                                          # Shell form. 
    RUN ["executable" "param1" "param2"]        # exec form. 
  2. Shell form: Args are automatically prepended with "/bin/sh -c".
    Exec formmakes it possible to avoid shell string prepending, and to RUN commands using a base image that does not contain /bin/sh.RUN echo hello                        # /bin/sh -c echo hello
    RUN [ "echo", "hello" ]            # echo hi
  3. To use a different shell other that /bin/sh and keep using the shell form, you can do following on top of DockerFile.
    RUN rm /bin/sh && ln -s /bin/bash /bin/sh
  4. The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile.
    Containers can be created from any point in an image’s history.
  5. Use backslash "\" to continue the RUN command on multiple lines.

CMD:
  1. CMD specifies the command to run when the container is launched.
    In another form, it can also specify the arguments to ENTRYPOINT.
    CMD ["executable" "param1" "param2"]
    CMD ["param1" "param2"]                            # as default parameters to ENTRYPOINT. ENTRYPOINT is must in this case.
  2. CMD defaults will be override by run arguments.
    sudo docker run -it <container-name> <arguments which will override>.
NOTE: There can be only one CMD command in Dockerfile.

ENTRYPOINT:
  1. Allow you to specify the default executable.
  2. CMD contents will be passed as argument to ENTRYPOINT.
  3. Any "docker run" arguments will be passed as parameter to ENTRYPOINT.
  4. To override DockerFile EntryPoint, you need to supply --entrypoint to docker run
    sudo docker run -it --entrypoint="/bin/bash" ent_cmdd
  5. Example:
    FROM ubuntu:14.04.3
    ENTRYPOINT ["/bin/ping"]
    CMD ["localhost" "-c 2"]

    NO argument (sudo docker -it ent_cmd)                    : ping localhost
    argument (sudo docker run -it ent_cmd google.com) : ping google.com

    NOTE: You can use the exec form of ENTRYPOINT to set fairly stable default commands and arguments and then use CMD to set additional defaults that are more likely to be changed.
LABEL:
  1. LABEL adds metadata to the image in key-value pair format.
  2. LABEL multi.label1="value1" \
    multi.label2="value2" \
    other="value3"
    LABEL version="0.5.1" \
    Description="This image holds Riemann Server."
  3. New label values will override previous labels. So, your base image key value will be override by new value.
  4. Docker inspect <image-name>will show you image labels..

EXPOSE:
  1. The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. 
  2. EXPOSE does NOT make the ports of the container accessible to the host. Exposed ports are just available to processes inside the container.
  3. Given the limitation of the EXPOSE instruction, a Dockerfile author will often include an EXPOSE rule only as a hint to which ports will provide services.
  4. One can see ExposedPorts of image under Config section using
  5. sudo docker inspect <image-name>
  6. To make the ports of the container accessible to the host, you must use either the -p flag to publish a range of ports or the -P flag to publish all of the exposed ports.
    EXAMPLE:
    FROM ubuntu:14.04.3
    ENTRYPOINT [ "/bin/nc" ]
    CMD [ "-luv","6871" ]         # (nc -luv 6871) will set a udp server listening on port 6871.
    EXPOSE 6871/udp
    sudo docker build -t expose .
    sudo docker run -ti expose
    From host try to send udp packet to udp port 6871.
    nc -vu 127.0.0.1 6871
    Nothing will receive inside container because port is exposed (mere a hint) but not published (only publish will make it accessible to host).
  7. sudo docker run -ti -p 127.0.0.1:6871:6871/udp expose
    nc -vu 127.0.0.1 6871

    Now typing anything on prompt will be received inside docker.
  8. Moreover, you can see the port mapping as well like given below
    sudo docker ps -l
  9. CONTAINERID    IMAGE   COMMAND   PORTS   NAMES
    facbb246bfe6         expose     "/bin/nc -luv    6871"      127.0.0.1:6871->6871/udp evil_darwin
    NOTE: Format for publishing a container᾿s port or a range of ports to the host: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort
    containerPort is necessary. In case you donot provide hostPort, Docker will assign some available random host port.
    The port number inside the container (where the service listens) does not need to match the port number exposed on the outside of the container (where clients connect).
WORKDIR:
  1. WORKDIR instruction sets the working directory for ADD, COPY, RUN, CMD, ENTRYPOINT.
  2. EXAMPLE: 
    FROM ubuntu:14.04.3
    WORKDIR /var/log
    ENTRYPOINT ["/bin/ls"]

    Upon running above container, you will see contents of /var/log.
  3. It can resolve environment variables set by ENV.
    ENV DIR /varWORKDIR $DIR/logENTRYPOINT ["/bin/ls"]
  4. It can not expand linux variables like $USER or $HOME etc.

ADD:
  1. ADD instructions adds <src> from build-context to <dst>.ADD <src> <dst>
  2. <src> can be a file, directory, URL or tar file. In case of "tar" source, Docker will untar and then copy.
  3. If <dst> does not exist, ADD will create the full path for us.
  4. New files will be created with 755 permission. In case of URL, permissions will be 600.
  5. <src> may contain the regular expression.
    ADD hom* /mydir/
  6. You can not add from outside of build or context.

COPY:
Copy is same as 'ADD' but without the tar and remote url handling.
Docker's best practice document suggests to use COPY because it is more transparent than ADD.

USER:
  1. USER instruction will set the user for any following RUN, CMD, ENTRYPOINT command and to use when running the image.
  2. It can be override by using -u flag with "run" command.
ARG:
  1. The ARG instruction defines a variable that users can pass at build-time to the builder with the docker build command using the --build-arg <varname>=<value> flag.
    ARG logstash_version 
  2. User can define the default value for argument as well.
    ARG logstash_version=1.2.3
  3. User will build the image using
    docker build --build-arg logstash_version=2.2.2 .
ONBUILD:
  1. The ONBUILD instruction adds to the image a trigger instruction.
  2. Instructions will be triggered later when the image is used as the base for another build. 
  3. The trigger will be executed in the context of the downstream build, as if it had been inserted immediately after the FROM instruction in the downstram Dockerfile.

No comments:

Post a Comment