DevOps: Docker: Build locally
New to a team? New to a project? No need to spend all day or days fetching dependencies to make sure you have the configuration just right so the target application will run on your local computer. Docker and Docker Compose to the rescue. Docker provides the mechanism to have a build script for the target application. Docker Compose provides a higher level build to take care of standard infrastructure dependencies such as postgresql and redis. Performing the build using Docker and Docker Compose always for quick deployment of the application locally. Of course there is a necessary step of applying an application database snapshot to your local instance of Postgresql.
The Dockerfile:
FROM ruby:2.1.9-slim
ENV DEBIAN_FRONTEND noniteractive
COPY ./script/nodejs_setup_6.x.sh /tmp/nodejs_setup_6.x.sh
RUN chmod +x /tmp/nodejs_setup_6.x.sh && /tmp/nodejs_setup_6.x.sh
# nodejs automatically runs `apt-get update` so there's no need to run it again here
RUN apt-get install -y \
apt-transport-https \
build-essential \
emacs24-nox \
emacs-goodies-el \
git-core \
imagemagick \
libbz2-dev \
libcurl4-openssl-dev \
libncurses-dev \
libexpat-dev \
libffi-dev \
libpq-dev \
libreadline-dev \
libsqlite3-dev \
libssl-dev \
libxml2-dev \
libxslt1-dev \
libyaml-dev \
logrotate \
nodejs \
openjdk-7-jre-headless \
python-software-properties \
sqlite3 \
ssh \
supervisor \
texinfo \
vim \
zlib1g-dev \
--fix-missing --no-install-recommends \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN mkdir -p /hammerhead
WORKDIR /hammerhead
# add options to gemrc
RUN echo "gem: --no-document --no-ri --no-rdoc" > ~/.gemrc
COPY Gemfile Gemfile.lock /hammerhead/
COPY engines/ /hammerhead/engines/
RUN gem install bundler --no-ri --no-rdoc && bundle install --jobs 5 --retry 3
ENV SECRET_KEY_BASE $(openssl rand -base64 32)
RUN \
mkdir -p log && \
mkdir -p tmp/cache && \
mkdir -p tmp/pids && \
mkdir -p tmp/sockets && \
mkdir -p public && \
chmod -R a+rw log tmp public
# run puma
CMD bundle exec puma -C config/puma.rb
The Docker Compose configuration:
version: '2'
services:
web:
build:
context: .
dockerfile: Dockerfile
env_file:
- config/application.yml
command: bundle exec puma -C config/puma.rb
working_dir: /hammerhead
environment:
PORT: 3000
DATABASE_URL: 'postgres://postgres:@postgres:5432/hammerhead_local'
RAILS_ENV: 'local'
REDIS_URL: 'redis://redis:6379'
ports:
- '3000:3000'
links:
- postgres
- redis
volumes_from:
- postgres
redis:
image: redis:3.2-alpine
ports:
- '6379:6379'
postgres:
image: postgres:9.6
volumes:
- '.:/hammerhead'
Finally the exerpt from the application README file for putting it all together locally:
#### Grab files from AWS S3
You will need access to AWS S3. From there navigate to the hammerhead_local bucket. And copy these guys:
2017-04-20.dump copy to: /. (project root)
application.yml copy to: /config/
## Docker and Docker Compose Installation
### Clear unwanted containers Only needed on repeat attempts.
$ docker rm $(docker ps -a -q)
### Clear dangling images Only needed on repeat attempts.
$ docker rmi $(docker images -q -f dangling=true)
### Now the good stuff Create.
$ docker-compose create
Build.
$ docker-compose build
Start.
$ docker-compose start
If you get some sort of network error (but only if you get an error) with start try the up command..
$ docker-compose up
This will fire a non-daemon process that we do not want, but will probably solve the network issue. After it does its thing and the terminal is staring at you, kill the proces by Ctrl-C.
Now try the Start. Again.
$ docker-compose start
Check for your container processes.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f40e4ad0ce01 hammerhead_web "bundle exec puma ..." About an hour ago Up About an hour 0.0.0.0:3000->3000/tcp hammerhead_web_1
19761c628c84 postgres:9.6 "docker-entrypoint..." About an hour ago Up About an hour 5432/tcp hammerhead_postgres_1
fd7d3e7b44bd redis:3.2-alpine "docker-entrypoint..." About an hour ago Up About an hour 0.0.0.0:6379->6379/tcp hammerhead_redis_1
Now lets address the db. First create it.
$ docker-compose exec web bundle exec rake db:create
Remember that file you copied to the project root a few steps back? Time to use it to load the database.
$ docker-compose exec postgres pg_restore -v -O -c -d 'postgres://postgres@postgres:5432/hammerhead_local' /hammerhead/2017-04-20.dump
When this completes, you can now hit the url for your local on port 3000 served by Puma
Now lets do a little bit of cleanup, we no longer need the snapshot so be gone with it!
$ rm 2017-04-20.dump
Your are done. Can you say favorite beverage time?