Wilson Mar bio photo

Wilson Mar

Hello. Hire me!

Email me Calendar Skype call 310 320-7878

LinkedIn Twitter Gitter Google+ Youtube

Github Stackoverflow Pinterest

Define how little bits work together


Overview

The object of this tutorial is to get you to confidently create Dockerfile and docker-compose files which define how Docker instantiate containers across several operating systems.

I want you to feel confident that you’ve mastered this skill. That’s why this takes a hands-on approach where you type in commands and we explain the responses and possible troubleshooting. This is a “deep dive” because all details are presented.

Like a good music DJ, I’ve carefully arranged the presentation of concepts into a sequence for easy learning, so you don’t have to spend as much time as me making sense of the flood of material around this subject.

Sentences that begin with PROTIP are a high point of this website to point out wisdom and advice from experience. NOTE point out observations that many miss. Search for them if you only want “TL;DR” (Too Long Didn’t Read) highlights.

Stuck? Contact me and I or one of my friends will help you.

Basic Concepts

Docker containers are created using docker images, built by parsing a Dockerfile containing Docker commands.

Dockerize apps

“Dockerizing” an application is the process of converting an application to run within a Docker container.

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.

    The response:

    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 sets the image to an operating system image. For options, do a . This must be the first line. docker search.
    • MAINTAINER 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 foo /bar
    • ENV def=$abc
    • 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

    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"]
    

    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"]
    

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

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

Blogs on this topic:

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

More on DevOps

This is one of a series on DevOps:

  1. DevOps_2.0
  2. User Stories for DevOps

  3. Choices for DevOps Technologies
  4. Java DevOps Workflow
  5. AWS DevOps (CodeCommit, CodePipeline, CodeDeploy)
  6. AWS server deployment options

  7. Digital Ocean
  8. Cloud regions
  9. AWS Virtual Private Cloud
  10. Azure Cloud Powershell

  11. Git and GitHub vs File Archival
  12. Git Commands and Statuses
  13. Data Security GitHub
  14. Git Commit, Tag, Push
  15. Git Utilities
  16. GitHub API

  17. TFS vs. GitHub

  18. Jenkins Server Setup
  19. Jenkins Plug-ins
  20. Jenkins Freestyle jobs
  21. Jenkins2 Pipeline jobs using Groovy code in Jenkinsfile

  22. Dockerize apps
  23. Docker Setup
  24. Docker Build

  25. Maven on MacOSX

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

  29. Ansible

  30. MySQL Setup

  31. SonarQube static code scan

  32. API Management Microsoft
  33. API Management Amazon

  34. Scenarios for load