Skip to main content
Start tracking your Ruby
infrastructure
@sergey_kukunin
IT Rally 2018, Івано-Франківськ
What we are talking about
What’s wrong with
Capistrano?
Problems with classic approach
● Setup a new server after failure
● Scaling
● Deploy of new dependencies
● Setup a new instance for a feature
Infrastructure as Code
Without rocket science
Advantages of the approach
● Automatization
● Scalability
● Track your changes
● A way to define application
dependencies
● Unifies zoo of technologies
Docker + Ansible: easy to start
Docker
What Docker is
Docker is about isolation
Docker example
I’m in Ubuntu
docker run -it ubuntu bash
I’m in Centos
docker run -it centos bash
Docker is NOT a VM
Glossary
● Docker Image
● Docker Container
● Dockerfile
● Docker Volume
● Docker Network
● Docker Registry
How Docker works
A couple of keynotes
● Docker is a daemon
● Docker is a client-server application
● All containers share the same kernel
● Currently, Docker runs only on Linux kernel
Dockerfile
FROM ruby:2.5
RUN apt-get update && apt-get install
-y build-essential libpq-dev nodejs
RUN mkdir /app
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install --jobs 4
ADD . /app
RUN bundle exec rake assets:precompile
CMD rake server
Dockerfile
# builder stage
FROM ubuntu:16.04 as builder
RUN apt-get update && 
apt-get --no-install-recommends --yes install 
ca-certificates 
cmake 
g++ 
make 
pkg-config 
graphviz 
doxygen 
git 
curl 
libtool-bin 
autoconf 
automake
Dockerfile
autoconf 
automake
WORKDIR /usr/local
## Boost
ARG BOOST_VERSION=1_66_0
ARG BOOST_VERSION_DOT=1.66.0
ARG
BOOST_HASH=5721818253e6a0989583192f96782c4a98eb6204965316df9f5ad75819225ca9
RUN curl -s -L -o boost_${BOOST_VERSION}.tar.bz2
https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${B
OOST_VERSION}.tar.bz2 
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c 
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 
&& cd boost_${BOOST_VERSION} 
&& ./bootstrap.sh 
&& ./b2 --build-type=minimal link=static runtime-link=static --with-
Dockerfile
&& ./bootstrap.sh 
&& ./b2 --build-type=minimal link=static runtime-link=static --with-
chrono --with-date_time --with-filesystem --with-program_options --with-regex
--with-serialization --with-system --with-thread --with-locale
threading=multi threadapi=pthread cflags="-fPIC" cxxflags="-fPIC" stage
ENV BOOST_ROOT /usr/local/boost_${BOOST_VERSION}
# OpenSSL
ARG OPENSSL_VERSION=1.0.2n
ARG
OPENSSL_HASH=370babb75f278c39e0c50e8c4e7493bc0f18db6867478341a832a982fd15a8fe
RUN curl -s -O https://www.openssl.org/source/openssl-
${OPENSSL_VERSION}.tar.gz 
&& echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -
c 
&& tar -xzf openssl-${OPENSSL_VERSION}.tar.gz 
&& cd openssl-${OPENSSL_VERSION} 
&& ./Configure linux-x86_64 no-shared --static -fPIC
Dockerfile
&& tar -xzf openssl-${OPENSSL_VERSION}.tar.gz 
&& cd openssl-${OPENSSL_VERSION} 
&& ./Configure linux-x86_64 no-shared --static -fPIC 
&& make build_crypto build_ssl 
&& make install
ENV OPENSSL_ROOT_DIR=/usr/local/openssl-${OPENSSL_VERSION}
# ZMQ
ARG ZMQ_VERSION=v4.2.3
ARG ZMQ_HASH=3226b8ebddd9c6c738ba42986822c26418a49afb
RUN git clone https://github.com/zeromq/libzmq.git -b ${ZMQ_VERSION} 
&& cd libzmq 
&& test `git rev-parse HEAD` = ${ZMQ_HASH} || exit 1 
&& ./autogen.sh 
&& CFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure --enable-static --disable-
shared 
&& make 
&& make install
Dockerfile
&& make install 
&& ldconfig
# zmq.hpp
ARG CPPZMQ_HASH=6aa3ab686e916cb0e62df7fa7d12e0b13ae9fae6
RUN git clone https://github.com/zeromq/cppzmq.git -b ${ZMQ_VERSION} 
&& cd cppzmq 
&& test `git rev-parse HEAD` = ${CPPZMQ_HASH} || exit 1 
&& mv *.hpp /usr/local/include
# Readline
ARG READLINE_VERSION=7.0
ARG
READLINE_HASH=750d437185286f40a369e1e4f4764eda932b9459b5ec9a731628393dd3d3233
4
RUN curl -s -O https://ftp.gnu.org/gnu/readline/readline-
${READLINE_VERSION}.tar.gz 
&& echo "${READLINE_HASH} readline-${READLINE_VERSION}.tar.gz" |
Dockerfile
RUN curl -s -O https://ftp.gnu.org/gnu/readline/readline-
${READLINE_VERSION}.tar.gz 
&& echo "${READLINE_HASH} readline-${READLINE_VERSION}.tar.gz" |
sha256sum -c 
&& tar -xzf readline-${READLINE_VERSION}.tar.gz 
&& cd readline-${READLINE_VERSION} 
&& CFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure 
&& make 
&& make install
# Sodium
ARG SODIUM_VERSION=1.0.16
ARG SODIUM_HASH=675149b9b8b66ff44152553fb3ebf9858128363d
RUN git clone https://github.com/jedisct1/libsodium.git -b ${SODIUM_VERSION}

&& cd libsodium 
&& test `git rev-parse HEAD` = ${SODIUM_HASH} || exit 1 
&& ./autogen.sh
Dockerfile
&& cd libsodium 
&& test `git rev-parse HEAD` = ${SODIUM_HASH} || exit 1 
&& ./autogen.sh 
&& CFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure 
&& make 
&& make check 
&& make install
WORKDIR /src
COPY . .
ARG NPROC
RUN rm -rf build && 
if [ -z "$NPROC" ];then make -j$(nproc) release-static;else make -j$NPROC
release-static;fi
# runtime stage
FROM ubuntu:16.04
Dockerfile
# runtime stage
FROM ubuntu:16.04
RUN apt-get update && 
apt-get --no-install-recommends --yes install ca-certificates && 
apt-get clean && 
rm -rf /var/lib/apt
COPY --from=builder /src/build/release/bin/* /usr/local/bin/
# Contains the blockchain
VOLUME /root/.bitmonero
# Generate your wallet via accessing the container and run:
# cd /wallet
# monero-wallet-cli
VOLUME /wallet
Dockerfile
VOLUME /wallet
EXPOSE 18080
EXPOSE 18081
ENTRYPOINT ["monerod", "--p2p-bind-ip=0.0.0.0", "--p2p-bind-port=18080", "--
rpc-bind-ip=0.0.0.0", "--rpc-bind-port=18081", "--non-interactive", "--
confirm-external-bind"]
More keynotes
● Image is a stack of layered snapshots
● Image is read-only
● Container is immutable
● Distinguish the build time and the run time
Use cases
● A developer defines an exact application environment himself
● To resolve environment conflicts between applications
● Try and forget
● To run tests in parallel without interfering each other
● To define a unified interface to treat any application
Docker Registry
Questions?
Configuration
Management
Systems
Ansible
Why Ansible
It’s flexible
It’s so easy to start
Glossary: Module and Task
Glossary: Inventory and Group
Glossary: Playbook
Glossary: Variable
Glossary: Variable
Glossary: Variable
Glossary: Role
Glossary: Role
Glossary: Variables in Role
Glossary: Playbook
File templates
Glossary: Galaxy
A couple of keynotes
● Ansible is written on Python, but it’s YAML
● You define the desired state
● Ansible is declarative, but it has all constructions
● Docker removes the constraint of variety of recipes
● You can start with a single file
● You can build all architecture as you do in code
You can do OOP in Ansible
Combine it together
Do whatever you want
Cons
● Takes more time for single server setup
● Hard to make quick’n’dirty hacks
● Isolation makes some things hard
○ Zero downtime deploy
● WAT??? for classic admin
○ Need to pay more for DevOps
● Little problems
○ Ansible requires Python on a server
Further
Terraform
Docker Swarm
Kubernetes
Questions?
Thank you
for the listening