Wilson Mar bio photo

Wilson Mar

Hello. Hire me!

Email me Calendar Skype call 310 320-7878

LinkedIn Twitter Gitter Google+ Instagram Youtube

Github Stackoverflow Pinterest

Define how little bits work together


Overview

“Dockerizing” an application is the process of converting an application to run within a Docker container and creating the Dockerfile for it.

I keep examples of Dockerfiles at
https://github.com/wilsonmar/Dockerfiles

This is a hands-on tutorial on how to create Dockerfile and docker-compose files that contain commands controlling how Docker instantiates containers across several operating systems.

A Docker image is a read-only template used to create and launch a Docker container.

Dockerize apps

Let’s begin with an example.

  1. Navigate to the folder containing a Dockerfile.

    NOTE: Creating the Dockerfile is called “dockerizing” a folder.

  2. View the Dockerfile:

    cat Dockerfile

    Alternately, you may prefer to open the file using a text editor or IDE.

    There are only a handful of instructions (verbs) in a Dockerfile.

    FROM node:0.10.44-slim
    ADD . /home/demo/box/
    RUN cd /home/demo/box && npm install
    ENTRYPOINT ["/home/demo/box/boot.sh"]
    

    Skip to see this built.

    Docker builder instructions

    # (“pound sign”) begins a comments line or a directive.

    • FROM must be the first line. It sets the image to an operating system image. For options, do a docker search.
    • MAINTAINER Wilson Mar <wilsonmar@gmail.com> # defines the file’s author
    • USER
    • ARG user1=someuser # referenced by –build-arg user=what_user in docker build
    • ARG CONT_IMG_VER
    • ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0}
    • ENV def=$abc
    • ENV foo /bar
    • WORKDIR ${foo} # sets working directory to /bar
    • VOLUME /tmp
    • ADD . $foo # add . /bar to file system
    • COPY $foo /quux

    • HEALTHCHECK–interval=5m –timeout=3s <br /> CMD curl -f http://localhost/ || exit 1
    • CMD [”–port 27017”] # provides defaults to executing container
    • CMD [“/usr/bin/wc”,”–help”] # executable and parameter
    • EXPOSE 27017 # sets the port to listen

    • RUN bash -c ‘touch /app.jar’ # updates the repository sources list, etc.
    • ENTRYPOINT [“top”, “-b”] # sets default container commands
    • ONBUILD RUN /usr/local/bin/python-build –dir /app/src
    • STOPSIGNAL SIGKILL # sets the system call signal that will be sent to the container to exit.

    See https://docs.docker.com/engine/reference/builder

    More examples at https://docs.docker.com/engine/examples

    PROTIP: A chmod or chown changes a timestamp on the file even when there is no permission or ownership change made. Each dd command adds a 1MB layer. Thus, each chmod command changes permissions and causes a copy of the entire 1MB file to the next layer.

    PROTIP: Reduce the image size by merging RUN lines:

    FROM busybox
    RUN mkdir /data \
     && dd if=/dev/zero bs=1024 count=1024 of=/data/one \
     && chmod -R 0777 /data \
     && dd if=/dev/zero bs=1024 count=1024 of=/data/two \
     && chmod -R 0777 /data \
     && rm /data/one
    CMD ls -alh /data
    

To handle UID/GID and permission issues, update image to match host uid/gid:

FROM debian:latest
ARG UID=1000
ARG GID=1000
RUN groupadd -g $GID cuser \
 && useradd -m -u $UID -g $GID -s /bin/bash cuser
USER cuser
   

Then:

$ docker build \
  --build-arg UID=$(id -u) --build-arg GID=$(id -g) .
   

This Dockerfile shows use of the ENTRYPOINT to run Apache in the foreground (i.e., as PID 1):

FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
   

Another example:

FROM jenkins/jenkins:lts
USER root
RUN  apt-get update \
  && wget -O /usr/local/bin/gosu "https://github.com/..." \
  && chmod +x /usr/local/bin/gosu \
  && curl -sSL https://get.docker.com/ | sh \
  && usermod -aG docker jenkins
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
   

An example for Java on WebLogic:

FROM kmandel/java:8
VOLUME /tmp
#ADD ${project.build.final}.jar app.jar
ADD my-api.jar app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
   

After a Dockerfile is prepared, execute from command prompt to create the corresponding image:

docker build . 

Run docker run image-name to create a container out of the image to execute it.

See https://github.com/sudo-bmitch/dc2018

Dockerizing programming code

One of the advantages of using Docker is that an application can be deployed on several operating systems. But different operating systems have different ways of specifying file paths such as:

APP_CONFIG=/etc/dev.config

Such files would contain API keys and flags to vary app behavior without requiring a re-deploy.

PROTIP: Apps in Docker should be written in a way that references a file external to itself to obtain configuration data such as API keys.

Contents in configuration files can be varied at run-time by a script that mounts different volumes containing the config file or by using a sed command which find a unique pattern in the file, then modifies the data.

Common Logging

Also, rather than writing event information to a custom database, “cloud native” application programming code print to STDOUT/STDERR. This ensures application logs have a common format so that logs from other apps and monitoring utilities can all be co-mingled in a central logging system for historical analysis together by timeline.

Logs can be acessed directly with the docker logs command and by Docker API calls.

To simplify the dockerization process, some use the Dockerize utility Jason Wilder wrote in Golang and describes here. It works by wrapping calls to apps using the ENTRYPOINT or CMD directives.

.dockerignore

The .dockerignore file is like a .gitignore file, but specifies items for Docker to ignore in the Dockerfile.

See https://docs.docker.com/engine/reference/builder/#/dockerignore-file

Mount

mount a local path and map it to a path within the container

~/Source/projecta:/usr/src/app

Docker Compose

Docker compose creates multiple containers with a single operation.

See https://docs.docker.com/compose/

An example docker-compose-dev.yml file from here:

version: '2'
services:
 
  web:
    image: node:6.1
    volumes:
      - ./:/usr/src/app
    working_dir: /usr/src/app
    command: sh -c 'npm install; npm install -g nodemon ; nodemon -e js,jade app.js'
    ports:
      - "80:3000"
    depends_on:
      - mongo
    networks:
      - all
    environment:
      MONGODB_URI: "mongodb://mongo:27017/hackathon"
 
  mongo:
    image: mongo:3
    command: mongod --smallfiles
    networks:
      - all
 
networks:
  all:
   
  1. Define attributes of Docker host in environment variables:

    • DOCKER_HOST
    • DOCKER_TLS_VERIFY
    • DOCKER_CERT_PATH

See https://docs.docker.com/v1.11/compose/compose-file/

More resources

This tutorial is based on these and other resources:

  • https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#user details ENTRYPOINT

  • http://thediscoblog.com/blog/2014/05/05/dockerfiles-in-a-jiffy/

  • https://github.com/prakhar1989/docker-curriculum by prakhar1989, who was propelled to #18 on GitHub due largely to this tutorial.

  • https://deis.com/blog/2015/dockerfile-instructions-syntax/

  • https://runnable.com/docker/java/dockerize-your-java-application

https://www.udemy.com/zero-to-docker/learn/v4/t/lecture/7270460?start=0 https://github.com/schoolofdevops/voting-app-worker https://schoolofdevops.com https://hub.docker.com/u/schoolofdevops/

More on DevOps

This is one of a series on DevOps:

  1. DevOps_2.0
  2. ci-cd (Continuous Integration and Continuous Delivery)
  3. User Stories for DevOps

  4. Git and GitHub vs File Archival
  5. Git Commands and Statuses
  6. Git Commit, Tag, Push
  7. Git Utilities
  8. Data Security GitHub
  9. GitHub API
  10. TFS vs. GitHub

  11. Choices for DevOps Technologies
  12. Java DevOps Workflow
  13. AWS DevOps (CodeCommit, CodePipeline, CodeDeploy)
  14. AWS server deployment options

  15. Cloud regions
  16. AWS Virtual Private Cloud
  17. Azure Cloud Onramp
  18. Azure Cloud
  19. Azure Cloud Powershell
  20. Bash Windows using Microsoft’s WSL (Windows Subystem for Linux)

  21. Digital Ocean
  22. Cloud Foundry

  23. Packer automation to build Vagrant images
  24. Terraform multi-cloud provisioning automation

  25. Powershell Ecosystem
  26. Powershell on MacOS
  27. Powershell Desired System Configuration

  28. Jenkins Server Setup
  29. Jenkins Plug-ins
  30. Jenkins Freestyle jobs
  31. Jenkins2 Pipeline jobs using Groovy code in Jenkinsfile

  32. Dockerize apps
  33. Docker Setup
  34. Docker Build

  35. Maven on MacOSX

  36. Ansible

  37. MySQL Setup

  38. SonarQube static code scan

  39. API Management Microsoft
  40. API Management Amazon

  41. Scenarios for load