Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
docker workshop cheat sheet #2 - microservices

cheat sheet - simply copy-paste

Prerequisites

Google Campus Tel-Aviv

  • WiFi is Campus-Guest password is Elc0Campus

bootstrap

  • workshop Vagrantfile
    git clone https://gist.github.com/dfece549c22ddd3eccad workshop
    test that it works:
    cd workshop
    vagrant up
    vagrant ssh
    on the vm shell:
    docker --version
    should display:
    Docker version 1.4.1, build 5bc2ff8

microservices <=== takes a long time

Download additional docker images -

for image in registry pragrium/consul pragrium/registrator \
             golang python ruby scratch; do
    docker pull $image
done

code snippets

service discovery service
  1. edit boot2docker service defaults

    sudo vi /var/lib/boot2docker/profile
  2. add extra arguments for docker daemon

    EXTRA_ARGS="\
    --dns 172.17.42.1 \
    --dns 8.8.8.8 \
    --dns-search service.consul \
    "
  3. restart docker

    sudo /etc/init.d/docker stop
    sudo /etc/init.d/docker start
    
  4. start consul

    docker run -d \
     -p 8400:8400 \
     -p 8500:8500 \
     -p 8600:53/udp \
     -h node1 --name consul \
     progrium/consul \
     -server -bootstrap \
     -advertise 172.17.0.1
    
  5. start registrator

    docker run -d \
      -e DOCKER_HOST=tcp://172.17.42.1:2375 \
      -h registrator --name registrator \
      progrium/registrator \
      consul://172.17.42.1:8500
    
  6. create a simple service

    docker run -ti --rm \
      -p 9000:9000 \
      -e SERVICE_NAME="webserver" \
      -e SERVICE_TAGS="master" \
      -h web1 --name webserver \
      busybox \
      /bin/sh
    
  7. reload consul web ui http://localhost:60085/ui/

polyglot REST APIs
  1. ruby
run Proc.new { |env|
  [ 200,
    {'Content-Type' => 'text/html'},
    [ "Hello world!" ]
  ]
}
docker run -ti ruby /bin/bash
gem install rack
cat > app.rb
# copy from above
^D
rackup app.rb
  1. python
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return ["Hello World!"]
 
if __name__ == "__main__":
    from wsgiref.simple_server import make_server
    httpd = make_server('', 8080, application)
    httpd.serve_forever()
docker run -ti python /bin/bash
cat > app.py
# copy from above
^D
python app.py
  1. GO language
package main
 
import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Printf(w, "Hello World!")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}
docker run -ti golang /bin/bash
cat > app.go
# copy from above
^D
go run app.go
  1. python + redis
from redis import Redis
 
def application(env, start_response):
  redis = Redis(host='redis', port=6379)
  redis.incr('hits') # increment
  start_response('200 OK', [('Content-Type','text/html')])
  return ['Hello World! I have been seen %s times.' % redis.get('hits')]
 
if __name__ == "__main__":
  from wsgiref.simple_server import make_server
  httpd = make_server('', 8080, application)
  httpd.serve_forever()
docker run -d --name redis --host redis redis
docker run -ti --link redis:redis golang /bin/bash
cat > app.go
# copy from above
^D
go run app.go
composing & SSI
  1. ssi.go the SSI engine
package main

import (
    "log"
    "net/http"
    "io/ioutil"
    "html/template"
)

func ssi(url string) template.HTML {
    log.Print("SSI GET ", url)
    resp, err := http.Get(url)
    if err != nil { log.Panic("SSI GET error: ", url, err) }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil { log.Panic("SSI HTTP GET body read error: ", url, err) }
    return template.HTML(body)
}

func ssiHandler(w http.ResponseWriter, r *http.Request) {
    funcMap := template.FuncMap { "ssi": ssi, }
    tmpl, err := template.New("root").Funcs(funcMap).ParseGlob("*.html")
    if err != nil { log.Fatal("template parsing error: ", err) }
    err = tmpl.ExecuteTemplate(w, "combiner.html", "")
    if err != nil { log.Fatal("template executing error: ", err) }
}

func main() {
    http.HandleFunc("/", ssiHandler)
    log.Print("Started, serving at 8080.")
    err := http.ListenAndServe(":8080", nil)
    if err != nil { log.Fatal("net/http listen and serve error: ", err) }
}
  1. combiner.html the global web layout
<!doctype html>
<html>
    <body>
        <div style="width:50%;float:left">
            {{ ssi "http://plus.google.com" }}
        </div>
        <div style="width:50%;float:right">
            {{ ssi "http://www.facebook.com" }}
        </div>
    </body>
</html>

bonus: docker registry

  1. create a private docker registry
docker run -d -p 5000:5000 --name registry \
  -e MIRROR_SOURCE=https://registry-1.docker.io \
  -e MIRROR_SOURCE_INDEX=https://index.docker.io \
  -e DEBUG=false \
  -e LOGLEVEL=info \
  -e STANDALONE=false \
  -e SEARCH_BACKEND= \
  -e DISABLE_TOKEN_AUTH=true \
  -e STANDALONE=true \
  registry
  1. push an image to the private registry
docker tag registry 127.0.0.1:5000/registry
docker push 127.0.0.1:5000/registry
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment