Skip to content

Templates: Normal Project

Jordon Bedwell edited this page Apr 28, 2016 · 2 revisions

Docker Template has the ability to turn your application (project) into a Docker repository. This is only supported by the Normal template and you must have a Dockerfile and docker/template.yml (opts file.) For it to recognize your app as Docker Template Normal Project.

Dockerfile

Just like any Docker image, you have a Dockerfile, it can be transformed using variables and other stuff on a per-tag/group basis because we run all your Dockerfile's through ERB before creating your context for Docker.

Variables

  • @metadata: A Metadata class holding all of the opts.yml data.
  • You have full access to Ruby and it's context from within ERB as well.

Example

Lets build an image that takes a Rails project and builds it into a Docker image with Ubuntu. This image uses the default base image of envygeeks/ubuntu:latest which provides runit in place of other run systems and provides extra stuff.

The Layout

  • docker/
    • template.yml
    • copy/all/etc/startup3.d/rails
      • run
      • finish
  • Dockerfile

The Base Project.

For this, we will use Discourse, everybody loves Discourse now days, lets take Discourse, add a Dockerfile, and package it into our own Docker image without doing anything more than that!

git clone [email protected]:discourse/discourse.git
cd discourse && mkdir docker && touch Dockerfile
touch docker/template.yml

template.yml (Metadata)

/docker/template.yml

maintainer: Your Name <[email protected]>
user: random
tags: 
  latest: normal

#

development_packages:
  all:
    - libffi-dev
    - libssl-dev
    - libyaml-dev
    - libreadline6-dev
    - build-essential
    - libxslt1-dev
    - libxml2-dev
    - libpq-dev
    - ruby-dev

#

packages:
  all:
    - libxml2
    - libyaml-0-2
    - imagemagick
    - libreadline6
    - libjpeg-turbo-progs
    - postgresql-client
    - ghostscript
    - libxslt1.1
    - gifsicle
    - jhead
    - ruby
    - git

#

env:
  all:
    RAILS_ENV: production
    UNICORN_SIDEKIQS: 1
    DISCOURSE_DB_PORT: 5432
    DISCOURSE_DB_USER: discourse
    DISCOURSE_DB_HOST: postgresql
    DISCOURSE_DB_NAME: discourse
    DISCOURSE_REDIS_HOST: redis
    DISCOURSE_REDIS_PORT: 6379
    UNICORN_ENABLE_OOBGC: 0
    UNICORN_WORKERS: 2

The Dockerfile

MAINTAINER <% @metadata.maintainer %>
FROM <%= @metadata.image %>
COPY project /opt/discourse
ENV <%= @metadata.env %>
RUN \
  apt-get update && \
  apt-get install --no-install-recommends -y <%= @metadata.packages %> && \
  apt-get install --no-install-recommends -y <%= @metadata.development_packages %> && \
  gem install bundler --no-document && \

  groupadd -rg 620 discourse && \
  useradd  -u  620 -g 620 -rMd /home/discourse discourse && \
  docker-helper create-dir discourse:discourse /opt/discourse  && \
  docker-helper create-dir discourse:discourse /home/discourse && \
  cd /opt/discourse && \

  rm -rf .git && \
  cd /opt/discourse && \
  export FORCE_BUNDLE=true && \
  mkdir -p /usr/share/ruby && \
  echo "<%= @metadata.gems %>" > /usr/share/ruby/default-gems && \
  export BUNDLE_ARGS="-j128 --without=development:test --enable-shared" && \
  docker-helper install-users-gems && \

  docker-helper enable-stdout-logger && \
  docker-helper apt-clean <%= @metadata.development_packages %> && \
  docker-helper cleanup && \

  chown -R discourse:discourse /opt/discourse && \
  for f in production.log unicorn.stderr.log unicorn.stdout.log; do \
    ln -sf /opt/discourse/log/$f /etc/stdout.d/$f; \
  done

COPY copy /
VOLUME <%= @metadata.volumes %>
EXPOSE 3000

/docker/copy/all/etc/startup3.d/discourse/run

#!/bin/sh
set -e

if [ -f /etc/startup3.d/discourse/supervise/error ]; then
  echo "Refusing to start because there was an error."
  sleep 36864
fi

cd /opt/discourse
chpst -u discourse:discourse config/unicorn_launcher \
  -E production -c config/unicorn.conf.rb &

pid=$!; count=0
while [ ! -f tmp/pids/unicorn.pid ] && [ "$count" -lt 24 ]; do
  count=$(echo "$(($count+1))")
  sleep 1
done

if [ ! -f tmp/pids/unicorn.pid ]; then
  touch /etc/startup3.d/discourse/supervise/error
  echo "There was an error starting rails."
  exit 1
else
  while ! tail /etc/stdout.d/production.log >/dev/null; do
    sleep 0.1
  done; wait \
    $pid
fi

/docker/copy/all/etc/startup3.d/discourse/finish

#!/bin/sh
set -e

cd /opt/discourse
if [ -f tmp/pids/unicorn.pid ]; then
  kill "$(
    cat tmp/pids/unicorn.pid
  )"
fi

Building

docker-template build

Running

Please note, we've provided no PostgreSQL and no Redis, this image will require you attach those images separately like we do with our production images. For this reason, we normally also provide docker/compose.yml so users can boot it all up at once.

docker-template run --rm -it random/discourse