SlideShare a Scribd company logo
Ruby on Rails
& Docker
Why should I care?
Adam Hodowany
About me
• Adam Hodowany
• Ruby and JavaScript developer in Monterail
• @adhodak
Docker Less
DevOps Developer story
I wrote an app!
Now what?
$ bundle exec rails server -p 80
It is a joke. Please don’t do it.
Duh
But
($7 + $9) ÷ month
> UserAnswer.count
=> 158_565
http://giphy.com/gifs/ohdY5OaQmUmVW
VPS it is
Ruby on Rails and Docker - Why should I care?
Repeatability
Infrastructure as Code
Vagrant + Ansible
Vagrant
• “Development environments made easy”
• Virtual Machine without overhead
• Free, local VPS for testing provisioning scripts
• Local staging
# Vagrantfile
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest: 80, host: 8080
config.vm.network "forwarded_port", guest: 3000, host: 3030
end
$ vagrant up
# break things
$ vagrant destroy
$ vagrant up
Ansible
• Automation tool
• Configuration using .YML files
• No client on the server
# build-server.yml
---
- hosts: all
remote_user: "{{ deploy_user }}"
roles:
### Server provisioning roles:
- { role: linux-prereqs }
- { role: postgresql }
- { role: rbenv }
- { role: ruby }
- { role: nginx }
### Site specific roles:
- { role: prepare_site }
- { role: copy-env }
- create database
- copy database.yml
- copy nginx config
Docker
Docker:
your application in a
container
Image: KMJ at the German language Wikipedia
Container
1. Application
2. All dependencies
3. Common interface
4. ???
5. PROFIT
$ bundle exec rails server
$ php artisan serve
$ python manage.py runserver
$ docker run docker-image
How is it different from VM?
Virtual Machine: Docker:
https://www.docker.com/what-docker
# Dockerfile
FROM ruby:2.2.0
RUN apt-get update -qq && apt-get install -y build-essential nodejs && gem install bundler
ENV APP_HOME /myapp
RUN mkdir $APP_HOME
WORKDIR $APP_HOME
ADD Gemfile $APP_HOME/Gemfile
ADD Gemfile.lock $APP_HOME/Gemfile.lock
RUN bundle install
ADD . $APP_HOME
CMD ["bundle", "exec", "rails", "server", "--binding", "0.0.0.0"]
- Base Image
- Copy whole application to the image
|- Default “run” command
$ docker build -t my-project .
$ docker run -p 3000:3000 my-project
host:container
Linking containers
$ docker run -d --name db postgres
$ docker run --link db:db my-project
# config/database.yml
development:
host: db
...
Volumes
$ docker run -v /home/hodak/data:/data my-project
or: shared directories
(or files)
(but most likely directories)
host:container
Docker repositories
• Docker Hub
• Official
• Free public repositories
• Alternatives exist
• Self-hosted
• Installed with… Docker
or: GitHubs for Docker images
99 official repositories including:
nginx, redis, node, postgres,
elasticsearch, wordpress,
jenkins, ruby…
Maintained by projects creators
Thousands of unofficial,
public repositories
http://gph.is/VxbrxV
Docker in
Development
Docker Machine
Volumes are great
• My misconception: code always either in container,
or always out of it.
# Dockerfile
ADD . app_dir/
Makes sure app directory
is always in built image
Enables code reload for development
$ docker run -v $(pwd):/app_dir my-project
Docker Compose
$ docker build -t my-project .
$ docker run -d --name db postgres
$ docker run --link db:db -p "3000:3000" my-project
$ docker run -d --name db postgres
$ docker run --link db:db -p "3000:3000" --env-file .env
my-project
$ docker run -d --name db postgres
$ docker run --link db:db -p "3000:3000" --env-file .env -
v /home/hodak/code/my-project:/my-project my-project
$ docker run -d --name db postgres
$ docker run -d --name redis redis
$ docker run -d --name sidekiq --link redis:redis --link db:db --env-file
.env my-project bundle exec sidekiq
$ docker run --link db:db --link redis:redis -p "3000:3000" --env-file .env
-v /home/hodak/code/my-project:/my-project my-project
# docker-compose.yml
db:
image: postgres
web:
build: .
command: bundle exec rails server --binding 0.0.0.0
ports:
- "3000:3000"
links:
- db
volumes:
- .:/myapp
env_file: .env
$ docker-compose build
$ docker-compose up
# docker-compose.yml
db:
image: postgres
redis:
image: redis
sidekiq:
build: .
command: bundle exec sidekiq
volumes:
- .:/myapp
links:
- db
- redis
env_file: .env
web:
build: .
command: bundle exec rails server --binding 0.0.0.0
ports:
- "3000:3000"
links:
- db
- redis
volumes:
- .:/myapp
env_file: .env
Use Cases
• Ruby on Rails agency - meh?
• Microservices
• Especially in different technologies
• Working with Freelancers
Admesh
github.com/admesh/admesh
Ruby on Rails and Docker - Why should I care?
$ ./configure
$ make
$ make install
Ruby on Rails and Docker - Why should I care?
# Dockerfile
COPY ./lib/admesh-0.98.2.tar.gz $APP_HOME/admesh.tar.gz
RUN tar -zxvf admesh.tar.gz && 
cd $APP_HOME/admesh-0.98.2 && 
./configure && 
make && 
make install
Continuous Integration
with Docker
Typical Rails-CI setup
$ cp config/codeship.database.yml config/database.yml
$ rvm use 2.1.1
$ bundle install
$ export RAILS_ENV=test
$ bundle exec rake db:drop db:create db:structure:load
$ bundle exec rspec
Development CI
Ruby version
Bundler version
Ruby version
Bundler version
Development CI
Ruby version
Bundler version
Ruby version
Bundler version
Staging Production
Ruby version
Bundler version
Ruby version
Bundler version
• More tricky dependencies
• ImageMagick
• ADMesh
• …
Development CI Docker Repository
Dev
Build
Productio
n
Build
Staging Production
• Image that has proven itself
• No errors
• Specs passed
$ cp config/codeship.database.yml config/database.yml
$ rvm use 2.1.1
$ bundle install
$ export RAILS_ENV=test
$ bundle exec rake db:drop db:create db:structure:load
$ bundle exec rspec
- Start Postgres
|- Build production image
- Set up database
- Run specs
After specs pass:
Send image
to Docker Hub
# origin/master -> master
$ BRANCH_NAME=`echo $GIT_BRANCH | cut -d '/' -f 2-`
$ docker rm --force $(docker ps -aq) || echo "ok"
$ docker run -d --name db postgres
$ docker build -t my-project -f Dockerfile.prod .
$ docker run --link db:db -e RAILS_ENV=test my-project bundle exec rake db:create d
$ docker run --link db:db -e RAILS_ENV=test my-project bundle exec rspec
$ docker tag my-project hodak/my-project:$BRANCH_NAME
$ docker push hodak/my-project:$BRANCH_NAME
Docker in production
# build-server.yml
---
- hosts: all
remote_user: "{{ deploy_user }}"
roles:
### Server provisioning roles:
- { role: linux-prereqs }
- { role: postgresql }
- { role: rbenv }
- { role: ruby }
- { role: nginx }
### Site specific roles:
- { role: prepare_site }
- { role: copy-env }
# build-server.yml
---
- hosts: all
remote_user: "{{ deploy_user }}"
roles:
### Server provisioning roles:
- { role: linux-prereqs }
- { role: nginx }
- { role: docker }
### Site specific roles:
- { role: prepare_site }
- { role: copy-env }
- create database
- copy database.yml
- copy nginx config
• Still must configure nginx
• Pull image from Docker repository
• Not touching GitHub at all
• Synchronise starting containers
• Monitoring
Data-only container pattern
$ docker run --name dbdata postgres echo "Data-only container for
postgres"
$ docker run -d --volumes-from dbdata --name db postgres
docker-compose?
Just a script
#!/bin/bash
docker run --name dbdata postgres echo "Data-only container for
postgres" || echo "already started"
docker run -d --volumes-from dbdata --name db --restart=always
postgres || docker start db
docker pull hodak/my-project:master
docker tag hodak/my-project:master my-project
docker run --link db:db my-project bundle exec rake db:create
db:migrate
docker rm --force my-project || echo "not yet created"
docker run -d --link db:db --name my-project --restart=always --env-file
.env -p "8080:8080" my-project
Ansible
tasks:
- name: application container
docker:
name: my-project
image: hodak/my-project:master
state: reloaded
pull: always
links:
- "db:db"
ports:
- "8080:8080"
restart_policy: always
Custom deploy script
for Capistrano
upstart / systemd /
supervisor / monit
Is it worth it?
Thank you!
Questions?
We’re hiring join.hussa.rs

More Related Content

What's hot (20)

PDF
Agiles Peru 2019 - Infrastructure As Code
Mario IC
 
PPTX
Toolbox of a Ruby Team
Arto Artnik
 
PDF
Ansible at work
Bas Meijer
 
PPT
Learn basic ansible using docker
Larry Cai
 
PDF
Provisioning iOS CI Server with Ansible
Shashikant Jagtap
 
PPTX
Deploying Symfony2 app with Ansible
Roman Rodomansky
 
PPTX
Real World Experience of Running Docker in Development and Production
Ben Hall
 
PPTX
Real World Lessons on the Pain Points of Node.JS Application
Ben Hall
 
PDF
docker build with Ansible
Bas Meijer
 
PPTX
Lessons from running potentially malicious code inside Docker containers
Ben Hall
 
PPTX
Running .NET on Docker
Ben Hall
 
PPTX
Ansible: How to Get More Sleep and Require Less Coffee
Sarah Z
 
PPTX
Docker in production
Mateusz Kutyba
 
PPTX
The How and Why of Windows containers
Ben Hall
 
PDF
Docker在豆瓣的实践 刘天伟-20160709
Tianwei Liu
 
PDF
douban happyday docker for daeqaci
Tianwei Liu
 
PDF
Docker in practice
Jonathan Giannuzzi
 
PDF
以 Laravel 經驗開發 Hyperf 應用
Shengyou Fan
 
PDF
How Reconnix Is Using Docker
Russ Mckendrick
 
PPTX
Deploying Windows Containers on Windows Server 2016
Ben Hall
 
Agiles Peru 2019 - Infrastructure As Code
Mario IC
 
Toolbox of a Ruby Team
Arto Artnik
 
Ansible at work
Bas Meijer
 
Learn basic ansible using docker
Larry Cai
 
Provisioning iOS CI Server with Ansible
Shashikant Jagtap
 
Deploying Symfony2 app with Ansible
Roman Rodomansky
 
Real World Experience of Running Docker in Development and Production
Ben Hall
 
Real World Lessons on the Pain Points of Node.JS Application
Ben Hall
 
docker build with Ansible
Bas Meijer
 
Lessons from running potentially malicious code inside Docker containers
Ben Hall
 
Running .NET on Docker
Ben Hall
 
Ansible: How to Get More Sleep and Require Less Coffee
Sarah Z
 
Docker in production
Mateusz Kutyba
 
The How and Why of Windows containers
Ben Hall
 
Docker在豆瓣的实践 刘天伟-20160709
Tianwei Liu
 
douban happyday docker for daeqaci
Tianwei Liu
 
Docker in practice
Jonathan Giannuzzi
 
以 Laravel 經驗開發 Hyperf 應用
Shengyou Fan
 
How Reconnix Is Using Docker
Russ Mckendrick
 
Deploying Windows Containers on Windows Server 2016
Ben Hall
 

Similar to Ruby on Rails and Docker - Why should I care? (20)

PDF
Rails Applications with Docker
Laura Frank Tacho
 
ODP
Ruby and Docker on Rails
Muriel Salvan
 
PDF
Docker for Ruby Developers
Aptible
 
PDF
Ruby microservices with Docker - Sergii Koba
Ruby Meditation
 
PDF
Dockercon EU 2014
Rafe Colton
 
PPTX
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
Docker, Inc.
 
PDF
Docker as development environment
Bruno de Lima e Silva
 
PDF
Docker, the Future of DevOps
andersjanmyr
 
PDF
Docker For Ruby On Rails : Meaning, Benefits, & Use Cases
rorbitssoftware
 
PPTX
Docker - A Ruby Introduction
Tyler Johnston
 
PDF
Rails in docker
Andrew Klotz
 
PDF
How to dockerize rails application compose and rails tutorial
Katy Slemon
 
PDF
Intro to Docker for (Rails) Developers
Chris Johnson
 
PDF
Introduction to Docker
Luong Vo
 
PDF
Introducción a contenedores Docker
Software Guru
 
PDF
Docker at MoneyBird
Edwin Vlieg
 
PDF
ContainerDayVietnam2016: Dockerize a small business
Docker-Hanoi
 
PDF
Docker for the Rubyist
Brian DeHamer
 
PDF
Real-World Docker: 10 Things We've Learned
RightScale
 
PDF
Docker primer and tips
Samuel Chow
 
Rails Applications with Docker
Laura Frank Tacho
 
Ruby and Docker on Rails
Muriel Salvan
 
Docker for Ruby Developers
Aptible
 
Ruby microservices with Docker - Sergii Koba
Ruby Meditation
 
Dockercon EU 2014
Rafe Colton
 
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
Docker, Inc.
 
Docker as development environment
Bruno de Lima e Silva
 
Docker, the Future of DevOps
andersjanmyr
 
Docker For Ruby On Rails : Meaning, Benefits, & Use Cases
rorbitssoftware
 
Docker - A Ruby Introduction
Tyler Johnston
 
Rails in docker
Andrew Klotz
 
How to dockerize rails application compose and rails tutorial
Katy Slemon
 
Intro to Docker for (Rails) Developers
Chris Johnson
 
Introduction to Docker
Luong Vo
 
Introducción a contenedores Docker
Software Guru
 
Docker at MoneyBird
Edwin Vlieg
 
ContainerDayVietnam2016: Dockerize a small business
Docker-Hanoi
 
Docker for the Rubyist
Brian DeHamer
 
Real-World Docker: 10 Things We've Learned
RightScale
 
Docker primer and tips
Samuel Chow
 
Ad

Recently uploaded (20)

PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
PDF
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
PDF
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
DOCX
Cryptography Quiz: test your knowledge of this important security concept.
Rajni Bhardwaj Grover
 
PDF
What Makes Contify’s News API Stand Out: Key Features at a Glance
Contify
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PPTX
Designing Production-Ready AI Agents
Kunal Rai
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PDF
Advancing WebDriver BiDi support in WebKit
Igalia
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
Staying Human in a Machine- Accelerated World
Catalin Jora
 
PDF
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
Cryptography Quiz: test your knowledge of this important security concept.
Rajni Bhardwaj Grover
 
What Makes Contify’s News API Stand Out: Key Features at a Glance
Contify
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
Designing Production-Ready AI Agents
Kunal Rai
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
Advancing WebDriver BiDi support in WebKit
Igalia
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Staying Human in a Machine- Accelerated World
Catalin Jora
 
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
Ad

Ruby on Rails and Docker - Why should I care?

  • 1. Ruby on Rails & Docker Why should I care? Adam Hodowany
  • 2. About me • Adam Hodowany • Ruby and JavaScript developer in Monterail • @adhodak
  • 4. I wrote an app! Now what?
  • 5. $ bundle exec rails server -p 80 It is a joke. Please don’t do it.
  • 6. Duh
  • 7. But ($7 + $9) ÷ month
  • 15. Vagrant • “Development environments made easy” • Virtual Machine without overhead • Free, local VPS for testing provisioning scripts • Local staging
  • 16. # Vagrantfile Vagrant.configure(2) do |config| config.vm.box = "ubuntu/trusty64" config.vm.network "forwarded_port", guest: 80, host: 8080 config.vm.network "forwarded_port", guest: 3000, host: 3030 end $ vagrant up # break things $ vagrant destroy $ vagrant up
  • 17. Ansible • Automation tool • Configuration using .YML files • No client on the server
  • 18. # build-server.yml --- - hosts: all remote_user: "{{ deploy_user }}" roles: ### Server provisioning roles: - { role: linux-prereqs } - { role: postgresql } - { role: rbenv } - { role: ruby } - { role: nginx } ### Site specific roles: - { role: prepare_site } - { role: copy-env } - create database - copy database.yml - copy nginx config
  • 20. Docker: your application in a container Image: KMJ at the German language Wikipedia
  • 21. Container 1. Application 2. All dependencies 3. Common interface 4. ??? 5. PROFIT
  • 22. $ bundle exec rails server $ php artisan serve $ python manage.py runserver $ docker run docker-image
  • 23. How is it different from VM? Virtual Machine: Docker: https://www.docker.com/what-docker
  • 24. # Dockerfile FROM ruby:2.2.0 RUN apt-get update -qq && apt-get install -y build-essential nodejs && gem install bundler ENV APP_HOME /myapp RUN mkdir $APP_HOME WORKDIR $APP_HOME ADD Gemfile $APP_HOME/Gemfile ADD Gemfile.lock $APP_HOME/Gemfile.lock RUN bundle install ADD . $APP_HOME CMD ["bundle", "exec", "rails", "server", "--binding", "0.0.0.0"] - Base Image - Copy whole application to the image |- Default “run” command
  • 25. $ docker build -t my-project . $ docker run -p 3000:3000 my-project host:container
  • 26. Linking containers $ docker run -d --name db postgres $ docker run --link db:db my-project # config/database.yml development: host: db ...
  • 27. Volumes $ docker run -v /home/hodak/data:/data my-project or: shared directories (or files) (but most likely directories) host:container
  • 28. Docker repositories • Docker Hub • Official • Free public repositories • Alternatives exist • Self-hosted • Installed with… Docker or: GitHubs for Docker images
  • 29. 99 official repositories including: nginx, redis, node, postgres, elasticsearch, wordpress, jenkins, ruby… Maintained by projects creators
  • 30. Thousands of unofficial, public repositories http://gph.is/VxbrxV
  • 33. Volumes are great • My misconception: code always either in container, or always out of it. # Dockerfile ADD . app_dir/ Makes sure app directory is always in built image Enables code reload for development $ docker run -v $(pwd):/app_dir my-project
  • 34. Docker Compose $ docker build -t my-project . $ docker run -d --name db postgres $ docker run --link db:db -p "3000:3000" my-project
  • 35. $ docker run -d --name db postgres $ docker run --link db:db -p "3000:3000" --env-file .env my-project
  • 36. $ docker run -d --name db postgres $ docker run --link db:db -p "3000:3000" --env-file .env - v /home/hodak/code/my-project:/my-project my-project
  • 37. $ docker run -d --name db postgres $ docker run -d --name redis redis $ docker run -d --name sidekiq --link redis:redis --link db:db --env-file .env my-project bundle exec sidekiq $ docker run --link db:db --link redis:redis -p "3000:3000" --env-file .env -v /home/hodak/code/my-project:/my-project my-project
  • 38. # docker-compose.yml db: image: postgres web: build: . command: bundle exec rails server --binding 0.0.0.0 ports: - "3000:3000" links: - db volumes: - .:/myapp env_file: .env $ docker-compose build $ docker-compose up
  • 39. # docker-compose.yml db: image: postgres redis: image: redis sidekiq: build: . command: bundle exec sidekiq volumes: - .:/myapp links: - db - redis env_file: .env web: build: . command: bundle exec rails server --binding 0.0.0.0 ports: - "3000:3000" links: - db - redis volumes: - .:/myapp env_file: .env
  • 40. Use Cases • Ruby on Rails agency - meh? • Microservices • Especially in different technologies • Working with Freelancers
  • 43. $ ./configure $ make $ make install
  • 45. # Dockerfile COPY ./lib/admesh-0.98.2.tar.gz $APP_HOME/admesh.tar.gz RUN tar -zxvf admesh.tar.gz && cd $APP_HOME/admesh-0.98.2 && ./configure && make && make install
  • 47. Typical Rails-CI setup $ cp config/codeship.database.yml config/database.yml $ rvm use 2.1.1 $ bundle install $ export RAILS_ENV=test $ bundle exec rake db:drop db:create db:structure:load $ bundle exec rspec
  • 48. Development CI Ruby version Bundler version Ruby version Bundler version
  • 49. Development CI Ruby version Bundler version Ruby version Bundler version Staging Production Ruby version Bundler version Ruby version Bundler version
  • 50. • More tricky dependencies • ImageMagick • ADMesh • …
  • 51. Development CI Docker Repository Dev Build Productio n Build Staging Production
  • 52. • Image that has proven itself • No errors • Specs passed
  • 53. $ cp config/codeship.database.yml config/database.yml $ rvm use 2.1.1 $ bundle install $ export RAILS_ENV=test $ bundle exec rake db:drop db:create db:structure:load $ bundle exec rspec
  • 54. - Start Postgres |- Build production image - Set up database - Run specs After specs pass: Send image to Docker Hub # origin/master -> master $ BRANCH_NAME=`echo $GIT_BRANCH | cut -d '/' -f 2-` $ docker rm --force $(docker ps -aq) || echo "ok" $ docker run -d --name db postgres $ docker build -t my-project -f Dockerfile.prod . $ docker run --link db:db -e RAILS_ENV=test my-project bundle exec rake db:create d $ docker run --link db:db -e RAILS_ENV=test my-project bundle exec rspec $ docker tag my-project hodak/my-project:$BRANCH_NAME $ docker push hodak/my-project:$BRANCH_NAME
  • 56. # build-server.yml --- - hosts: all remote_user: "{{ deploy_user }}" roles: ### Server provisioning roles: - { role: linux-prereqs } - { role: postgresql } - { role: rbenv } - { role: ruby } - { role: nginx } ### Site specific roles: - { role: prepare_site } - { role: copy-env }
  • 57. # build-server.yml --- - hosts: all remote_user: "{{ deploy_user }}" roles: ### Server provisioning roles: - { role: linux-prereqs } - { role: nginx } - { role: docker } ### Site specific roles: - { role: prepare_site } - { role: copy-env } - create database - copy database.yml - copy nginx config
  • 58. • Still must configure nginx • Pull image from Docker repository • Not touching GitHub at all • Synchronise starting containers • Monitoring
  • 59. Data-only container pattern $ docker run --name dbdata postgres echo "Data-only container for postgres" $ docker run -d --volumes-from dbdata --name db postgres
  • 62. #!/bin/bash docker run --name dbdata postgres echo "Data-only container for postgres" || echo "already started" docker run -d --volumes-from dbdata --name db --restart=always postgres || docker start db docker pull hodak/my-project:master docker tag hodak/my-project:master my-project docker run --link db:db my-project bundle exec rake db:create db:migrate docker rm --force my-project || echo "not yet created" docker run -d --link db:db --name my-project --restart=always --env-file .env -p "8080:8080" my-project
  • 64. tasks: - name: application container docker: name: my-project image: hodak/my-project:master state: reloaded pull: always links: - "db:db" ports: - "8080:8080" restart_policy: always
  • 66. upstart / systemd / supervisor / monit
  • 67. Is it worth it?

Editor's Notes

  • #2: Hi everybody, I’d like to tell you something about Docker in context of developing ruby on rails application, sending it on continuous integration service and deploying it to the server.
  • #3: my name is Adam, work as ruby and javascript developer in Monterail
  • #4: before we begin with Docker, dev-ops-ish, developer story what got me to this point, got me interested with docker note not devops not as comfortable as should be, can be said about devops story from developer’s point of view It’s a story about my side project…
  • #5: I wrote an app! now what? decent developer people to use it, deploy knew better
  • #6: joke and not a very good one - everybody do with rails app
  • #7: of course one butt
  • #9: which I knew I would have app’s design state after couple of weeks, 200 records per user heroku pricing in mind
  • #10: I did a quick math
  • #11: decided to go the VPS road. don’t get me wrong about heroku, couple dozens of dollars all the cool, side projects, learn devops thing eventually for $5/month I got a decent VPS could do everything I wanted -> problem -> could -> had to and what was my next step?
  • #12: how to deploy rails app tons of tutorials chose passenger -> app server, nginx -> http server, capistrano -> deployment automation tool a lot more to choose from. find tutorial -> ssh -> steps -> deploy -> done -> right? big problem, kept bothering me
  • #13: repeatability of server environment what if again? whole process, good couple of hours first time, next time what ifs: server failed, staging, new project find tutorial month later? everything from beginning, new server? devops - pressure - no wonder if it looks like it. does it? more predictable?
  • #14: sleep better nothing like code, hacking on server, praying - automate the “server setup” part - what infrastructure as code is about
  • #15: These two tools allowed me to do it rather quickly and I can highly recommend both.
  • #16: - what is motto of Vagrant on their website I don’t buy, Docker is more useful I really like using Vagrant as “locally hosted servers” I can SSH to the local server, I can destroy and create new “server” in a matter of seconds, I can use Vagrant as a staging environment, to make sure that things like server provisioning, loading ENV variables, e-mail sending, assets precompilation etc. will work on production
  • #17: Finally something interesting, code! not a lot - setting vagrant is that easy my full config (what it does) can ssh, use like VPS this is how I work with it
  • #18: automation tool connects ssh, runs commands nice thing not the only solution, found to be the simplest
  • #19: configuration looks like; hosts -> user -> roles (sets of commands) roles - download / write own if access && user -> run on new server -> 5 minutes -> serve app what happens here? generic / site specific
  • #20: Getting to this part was very exciting for me. I could configure server and deploy my application in 5 minutes while, actually, just doing coffee. But I thought - can we do better? It still feels kind of complex. *click* hear about docker, thought -> what I need?
  • #21: in its simplest we can say cool and all, what means
  • #22: - what is container made of common interface
  • #23: what I mean by common interface image, any application, don’t care what made of, dependencies run, docker takes care don’t need xxx installed all your host needs to understand is docker
  • #24: how is it different / can’t we do it with vagrant image from docker website most important difference - VMs include whole operating system to deploy rails app, you need to ship it with whole ubuntu or debian server 50mb project, ship with 700mb operating system has to run on a server - which already has an operating system very heavy and requires a lot of resources running 3 virtual machines on my laptop would probably make it fly and I would end up with a drone containers, in contrast, share kernel with linux OS. while you can have your container using debian or ubuntu, it still shares kernel with its host OS application can use low level resources it needs from host os
  • #25: Docker file - only one needed Docker takes -> builds image based on it base - each begin, is based on. ruby -> debian; inheritance run commands - debian, access to commands add -> copy whole app directory cmd -> when container starts what to do with such file?
  • #26: build -> create image, pull base, run commands run -> run, create container this case -> bundle exec rails s - technically all needed, rails started - won’t work - db
  • #27: could install on computer, better use docker (no dependencies) link containers, have connection d flag, name, image name rails config, instead of localhost
  • #28: besides linking, volumes shared, between host OS and docker container files, probably won’t this is how you run a container with volume magically shared
  • #29: not strictly docker concept, important part of ecosystem share built images, “cloud” several options
  • #30: screenshot, docker hub
  • #31: besides official projects - search unofficial, public repositories postgres, over 2000 this is kind of madness, most likely don’t want to when project doesn’t have official -> likely to find trusting second parties
  • #32: know roughly what docker is and how to configure use cases, where can help us offer in CI and production, most widely used in development
  • #33: as said earlier, shares kernel with host os -> linux dependent mac and windows users docker core team has you covered part of official docker ecosystem virtual box + docker machine -> magic -> docker, access to commands
  • #34: in development, volumes are great thought with docker you had to ssh to container, install vim or whatever and not use your day-to-day development environment in docker file can copy whole application directory during build when running in development, you can use volumes
  • #35: one more, official tool from docker ecosystem back to linking example, 2 images (db, app) app -> depends on having db, must start db every time - imagine we had to load ENV VARIABLES
  • #36: specify with —env-file option starting getting harder oh wait, VOLUMES
  • #37: getting ridiculous might as well go crazy assume, hypothetically, SIDEKIQ
  • #38: every time started work script fortunately, can do better interface for that and it’s called DOCKER COMPOSE
  • #39: configure with - of course - YML file is YML JavaScript of DevOps world? starts our application and database
  • #40: this starts the example with sidekiq commit it team members
  • #41: agency like ours, monterail no windows, 2 linux, macs, almost all projects RoR no docker-based development any time soon nevertheless easily think of some cases where it would be great microservices, java developers don’t need to have ruby installed freelance front-end developer, windows, spend a day
  • #42: personal case, side project user upload files, STL format, 3D models show info -> volume, size, triangles library, CLI, written in C
  • #43: I fell in love with this project after reading its readme, where you can find benchmarks from 1996
  • #44: how to install admesh? easy, nothing fancy, right?
  • #45: except, when you have to run it on windows we are in a point where we think about hiring freelance front-end developer afraid we’ll find good developer running windows no experience with virtual machines and ubuntu technicality, not related to core of her work
  • #46: docker fixes dockerize application and always have access to admesh command admesh exotic easily imagemagick
  • #47: my favourite part of this setup see big potential in docker approach
  • #48: typical rails CI setup (say what is shown) ASSUMPTION ruby is installed with rvm is fine, we’re used to it BUT can’t easily swap ci server
  • #49: some problem I see two, separate environments - Development and CI assume the same set up
  • #50: - doesn’t scale well might say that I’m overreacting about the bundler version until it matters, worked on a project, bundler security issue, 6 ruby on rails services - God forbid other non-trivial dependencies, like ImageMagick
  • #51: or admesh based per project, doesn’t happen often rails app works in a void
  • #52: with Docker. beware, some serious keynote animation magic work in development, use docker -> push to GitHub -> triggers CI CI -> Dockerfile -> PRODUCTION READY image (assets precompilation, production gems) -> run specs specs pass -> send to Docker Repository sits in Docker Repository, ready to be used no environment ruby, bundler versions, only understand docker CI process guarantees all images in repository passed our tests
  • #53: what are gains can send straight to production old process - specs pass in CI env, not production
  • #54: reminder how CI config looked like change it using Docker?
  • #55: Setup part -> branch name to variable -> clear leftover docker images - start with clean slate (go with slides)
  • #56: - quickly see how to deploy docker images
  • #57: what changes in provisioning reminder, ansible setup can simplify SERVER ONLY NEEDS TO UNDERSTAND DOCKER
  • #58: don’t need ruby or postgres on our server technically, we don’t need nginx, too, as we could use nginx from docker, but I kind of felt better with it there is a slight problem we didn’t have before - we can’t create database by running db:create rake task. but we can move this command to run on every deploy - if the database already exists, nothing happens
  • #59: what changes in deploy, and what stays the same still nginx instead of GitHub instead of starting database / redis processes still monitor, make sure app or db gets up when it dies
  • #60: important pattern using postgres in docker container in production decouple postgres engine - running in a postgres container - from postgres data (show - image exits immediately - no wasted resources) similar to using volumes, don’t have to make sure directory exist - enhances portability
  • #61: remember, we still have to run at least 2 containers - database and our app need to synchronise it somehow my first thought was to run it with docker-compose, but, from what I read, it’s an anti pattern and docker-compose is better left on development
  • #63: you can see the —restart=always option. docker mechanism to restart containers, when they exit note, that we pull the newest image from docker repository - not touching github at all
  • #64: can use ansible for deploy has built-in docker commands
  • #65: ansible task could look like this
  • #67: - from what I know it’s better to use external tool for starting and monitoring processes for anything but the most simple containers, so you can use any such tool