Docker from Local Development

to Production

ECCENTRIC DEVELOPER

Oscar Fanelli

Engineering Manager

Zend Framework / Symfony

ReactJS

Meetup

JetBrains IDEs

No Man's Sky

42

Why Docker?

MAMP

  • Ready to use in few minutes
  • What if I don't need MySQL?
  • Lightweight?
  • What about reproducing the production environment?

Brew

  • You can configure any service at will
  • What about a specific version of a specific service?
  • What about reproducing the production environment?
  • What if I update OSX?

brew update && brew upgrade...

% /usr/local/bin/gpg1
dyld: Library not loaded: /usr/local/opt/libusb-compat/lib/libusb-0.1.4.dylib
  Referenced from: /usr/local/bin/gpg1
  Reason: image not found
[1]    41295 trace trap  /usr/local/bin/gpg1
error: unable to unlink old '.gitignore' (Permission denied)
error: unable to create file .travis.yml (Permission denied)
error: unable to create file .yardopts (Permission denied)
error: unable to unlink old 'CODEOFCONDUCT.md' (Permission denied) ...
npm ERR! Darwin 13.3.0
npm ERR! argv "node" "/Users/user/.node/bin/npm" "update" "-g"
npm ERR! node v0.10.32
npm ERR! npm  v2.0.0
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package npmconf does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer npm-registry-client@3.2.2 wants npmconf@^2.1.0

Vagrant

  • 100% configurable
  • It's possible to reproduce the production environment
  • Is it fast?
  • Time needed to setup everything?

Docker

  • Containers and images
  • Shared Kernel
  • No hypervisor (no overhead)
  • Better performances
  • Using only resources you really need

Docker

Dockerfile

  • Configuration file
  • Contains instructions to:
    • Install and configure services
    • Expose ports
  • Easy to learn
  • Maintainable
  • Extendible
  • Good also for those who are pretencious
FROM ubuntu:16.04

MAINTAINER Oscar Fanelli <oscar.fanelli@gmail.com>

ENV PROJECT_PATH=/var/www \
    DEBIAN_FRONTEND=noninteractive

# Utilities, Apache, PHP, and supplementary programs
RUN apt-get update -q && apt-get upgrade && apt-get install -yqq --force-yes \
    npm \
    git \
    wget \
    apache2 \
    libapache2-mod-php \
    php \
    php-curl \
    php-mysql \
    php-redis \
    php-xml

# Apache mods
RUN a2enmod rewrite expires headers

# PHP.ini file: enable <? ?> tags and quiet logging
RUN sed -i "s/short_open_tag = .*/short_open_tag = On/" $PHP_INI && \
    sed -i "s/memory_limit = .*/memory_limit = 256M/" $PHP_INI

# VirtualHost
COPY config/docker/apache-virtualhost.conf /etc/apache2/sites-available/000-default.conf

# Port to expose
EXPOSE 80

# Copy site into place
COPY . $PROJECT_PATH
WORKDIR $PROJECT_PATH

# Start apache
CMD /usr/sbin/apache2ctl -D FOREGROUND

Docker Compose

  • Containers configuration
  • Manages environment variables
  • Mounts volumes
  • Ports
  • ...
version: '2'

services:

  db:
    image: mysql:5.7.17
    volumes:
      - "./.data/db:/var/lib/mysql"
    environment:
      MYSQL_ROOT_PASSWORD: secret
    expose:
      - "3306"

  redis:
    image: redis

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    depends_on:
      - db

  web:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ".:/var/www/"
    depends_on:
      - db
      - redis
    env_file: .env

working in a big company?

docker-compose up -d

USE CASE

Upgrade from PHP 5.6 to 7.0

Docker in local

vs

Docker in production

# docker-compose.override.yml
version: '3'

services:
  nginx-proxy:
    image: jwilder/nginx-proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./config/docker/nginx-proxy/certs:/etc/nginx/certs:ro

  mysql:
    environment:
      MYSQL_ROOT_PASSWORD: secret

  web:
    build:
      context: .
      dockerfile: ./config/docker/web/dev/Dockerfile
    volumes:
      - .:/usr/share/nginx:cached
      - ./config/docker/web/dev/php.conf:/usr/local/etc/php-fpm.d/zz-log.conf:ro
    env_file: .env

  nginx:
    image: nginx:1.13
    volumes:
      - ./config/docker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./public:/usr/share/nginx/public:ro
    environment:
      - VIRTUAL_HOST=*.spotistats.dev

Needs

  • Uptime guaranteed
  • Performance
  • Scalability
  • Load balancing
  • Monitoring & Logging
  • Routing (es: port 80/443)

how to simplify?

Kubernetes

de facto standard

TRY THIS AT HOME

Rancher

WHAT?

  • Infrastructure management
  • Built on top of Kubernetes
  • Encrypted connection between configured hosts
  • Parallelisation of containers on multiple machines
  • Continuous deployment
  • Environment variables
  • Certificates (https)
  • Integrated with LOT of third party services

Continuous Deployment

TEST & BUILD

CODE & PUSH

PRIVATE REPOSITORY

DEPLOY & RUN

Deployment Flow

Don't panic.

oscar.fanelli@gmail.com

@nesis

@pensiero

Docker from Local Development to Production

By Oscar Fanelli

Docker from Local Development to Production

  • 1,090