Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Five Tips for Building Docker Images

DZone's Guide to

Five Tips for Building Docker Images

A DZone user shares some great ways to keep Docker images simple, clean, and hassle-free.

· DevOps Zone
Free Resource

The Nexus Suite is uniquely architected for a DevOps native world and creates value early in the development pipeline, provides precise contextual controls at every phase, and accelerates DevOps innovation with automation you can trust. Read how in this ebook.

No doubt containers are a breakthrough technology in the DevOps world. So, how do we effectively build and use Docker images to speed up our deployment? This will be important for us in both our development and release cycles. Here are some of our experiences — check it out, buddy!

docker_deployment.jpg

Permanent Link: http://dennyzhang.com/docker_deployment

Tips for building a Docker image:

  • Cache Internet Download as Much as Possible. Usually, deployment needs to download hundreds of MB of data from the internet. Quite often, critical deployments may suffer from slow internet or connection issues. The more we cache, the faster the deployment will be. The ultimate goal is to support offline, all-in-one deployment from the Docker image.
  • Treat Docker Image as a Plain OS Golden Image. I know Docker is powerful, but we also have lots of VM or bare metal deployments. To avoid vendor lock-in issues, we usually need to support deployment with or without Docker. It's better we enforce deployment CI for both scenarios.

    Here is an example if you're using Kitchen for CI. By default, we test with a customized Docker image. When we specify IMAGE_NAME to ubuntu:14.04, we're confident the deployment would be fine for normal Ubuntu14.04 OS.
---
driver:
  name: docker
driver_config:
  instance_name: "all-in-one"
  use_sudo: false
  privileged: true
  remove_images: false
  image: <%= ENV.fetch('IMAGE_NAME', "denny/mydockertest:v1") %>


  • Audit All Packages and Services Installed in Docker Images. Start a Docker container from the image, then list and check all packages and services installed. For what? First, we want to keep the Docker image as small as possible, so that image delivery will be fast. Second, the more packages and services enabled, the more issues we will get, such as package conflicts or occupied tcp ports. Some services' post-installation scripts would even change critical global config files or leave unexpected flagfiles. It's better we keep the Docker image simple and stupid. Tip: List What Packages Were Installed In My Server.
  • Clean Shutdown All Services at the End of Each Docker Build. If we don't do this, services will be killed at the end of the Docker image's life. Lockfiles of service under /var/lock/* may not be properly handled. As a result, when we test deployment from the new built image, services may fail to start, which will result in invalid tests.
  • Add Verification Steps to Double Confirm the Image. When things are changed, we may need to rebuild Docker images from time to time. To confirm everything is fine, we can add automatic verification logic in the Docker build process.

Here is a sample with all above practices applied.


########## How To Use Docker Image ###############
##  docker run -t -d --privileged -p 8022:22 \
##          denny/mydockertest:v1 /usr/sbin/sshd -D
##
##################################################

FROM denny/sshd:v1
MAINTAINER Deny <denny@dennyzhang.com>
ARG devops_branch=master
ARG working_dir=/root/chef
##################################################
# Install basic packages
RUN apt-get -yqq update && \
    apt-get -yqq install curl && \
    apt-get -yqq install openssh-server && \
    apt-get install -y sudo lsb-release && \
    # Install chef
    curl -L https://www.opscode.com/chef/install.sh | bash && \
    # clean up files to make this docker layer smaller
    rm -rf /var/chef/cache/*.plugin && \
    rm -rf /usr/share/doc && \
    apt-get clean && apt-get autoclean
##################################################
# checkout code
RUN bash /root/git_update.sh ${working_dir} \
    git@github.com:DennyZhang/chef_community_cookbooks.git \
    ${devops_branch} && \
    echo "cookbook_path [\"${working_dir}/${devops_branch}/mdmdevops/community_cookbooks\", \
    \"${working_dir}/${devops_branch}/mdmdevops/cookbooks\"]" \
    > /root/client.rb

# Chef all-in-one deployment. This step takes minutes
RUN echo "{\"run_list\": [\"recipe[all-in-one::predownload]\"]}" \
    > /root/client.json && \
    chef-solo --config /root/client.rb -j /root/client.json && \
    # Clean up to make docker image smaller
    rm -rf /tmp/* /var/tmp/* && \
    rm -rf /var/chef/cache/jdk-*.tar.gz && \
    rm -rf /var/chef/cache/*.plugin && \
    rm -rf /usr/share/doc && \
    apt-get clean && apt-get autoclean
##################################################

# Shutdown services
RUN service couchbase-server stop || true && \
    service elasticsearch stop || true && \
    service nagios3 stop || true && \
    service apache2 stop || true && \
    service haproxy stop || true && \
    service nagios-nrpe-server stop || true && \
    rm -rf /run/apache2/apache2.pid && \
    rm -rf /var/log/apache2/* && \
    rm -rf /usr/local/var/run/vagrant_ubuntu_trusty_64.pid && \
    rm -rf /root/docker.rb /root/docker.json

# Verify docker image
RUN test -f /var/chef/cache/couchbase-server-enterprise_4.1.0-ubuntu14.04_amd64.deb && \
    test -f /var/chef/cache/elasticsearch-2.3.3.deb && \
    test -f /etc/apt/sources.list.d/ruby2.1-repo.list && \
    test -f /etc/apt/sources.list.d/haproxy-repo.list && \
    dpkg -s haproxy | grep "1.6.5"

# Clean up to make docker image smaller
RUN rm -rf /tmp/* /var/tmp/* /var/chef/cache/jdk-*.tar.gz && \
    rm -rf /var/chef/cache/*.plugin && \
    rm -rf /usr/share/doc && \
    apt-get clean && apt-get autoclean

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
##################################################


Like our blog posts? Discuss with us on LinkedIn, Wechat, or NewsLetter!

The DevOps Zone is brought to you in partnership with Sonatype Nexus.  See how the Nexus platform infuses precise open source component intelligence into the DevOps pipeline early, everywhere, and at scale. Read how in this ebook

Topics:
devops ,docker ,deployment

Published at DZone with permission of Denny Zhang, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}