With Docker Compose
Physical Objects
Docker Containers
$ docker pull redis
$ docker run -dP redis
f965bea89b312e77184a9b59b2d41827d99c34de97d179420d77...
$ docker ps -l
CONTAINER ID IMAGE PORTS
f965bea89b31 redis 0.0.0.0:32769->6379/tcp
version: '2'
services:
rust:
image: contraption/rust
ports:
- 3500:3500
links:
- redis
working_dir: /rust/projects/rusty_redis
entrypoint: ./target/debug/rusty_redis
clojure:
image: contraption/clojure
links:
- rabbitmq
- redis
working_dir: /root/projects/bringing_clojure
entrypoint: lein run
golang:
image: contraption/golang
links:
- rabbitmq
working_dir: /projects/gofire
entrypoint: go run gofire.go
redis:
image: redis
rabbitmq:
image: rabbitmq
Fast
Safe
Systems
$ docker run -it --entrypoint '/bin/sh' scorpil/rust
# container running...
$ mkdir -p projects/hello_world
$ cd projects/hello_world
$ nano main.rs
fn main() {
println!("Hello, World!");
}
$ rustc main.rs
$ ./main
Hello, World!
extern crate redis;
use redis::Commands;
use std::net::{TcpListener, TcpStream};
use std::thread;
use std::io::prelude::*;
use std::io::BufReader;
fn handle_client(mut stream: TcpStream) -> redis::RedisResult<()> {
let client = try!(redis::Client::open("redis://redis/"));
let con = try!(client.get_connection());
let mut buffer = String::new();
let mut reader = BufReader::new(stream);
while reader.read_line(&mut buffer).unwrap() > 0 {
let s = format!("{}, Rust!", buffer.trim());
println!("Received string: {} ..", s);
buffer.clear();
let _ = try!(con.set("rusty_key", s));
}
Ok(())
}
fn main() {
let listener = TcpListener::bind("0.0.0.0:3500").unwrap();
// accept connections and process them, spawning a new thread for each one
for stream in listener.incoming() {
match stream {
Ok(stream) => {
thread::spawn(move|| {
println!("Client connected!");
let _ = handle_client(stream);
});
}
Err(e) => {
println!("client errored! {}", e);
}
}
}
// close the socket server
drop(listener);
Store Key
Publish
Functional
Simple
Fast
$ docker run -it clojure
# container running...
$ mkdir -p projects
$ cd projects
$ lein new app hello_world
$ cd hello_world
$ lein run
Hello, World!
(ns bringing-clojure.core
(:gen-class))
(defn -main
"I don't do a whole lot ... yet."
[& args]
(println "Hello, World!"))
(ns bringing-clojure.core
(:require [taoensso.carmine :as car :refer (wcar)])
(:require [langohr.core :as rmq])
(:require [langohr.channel :as lch])
(:require [langohr.queue :as lq])
(:require [langohr.basic :as lb])
(:gen-class))
;; redis setup
(def redis-conn {:pool {} :spec {:uri "redis://redis/"}})
(defmacro wcar* [& body] `(car/wcar redis-conn ~@body))
;; data passing
(defn feed-rabbit
[v]
(let [conn (rmq/connect {:host "rabbitmq"})
ch (lch/open conn)
qname "go-rabbit"]
(lq/declare ch qname {:exclusive false :auto-delete true})
(lb/publish ch "" qname (format "%s Clojure!" v) {:content-type "text/plain"})
(rmq/close ch)
(rmq/close conn)))
(defn fetch-rusty-key
[]
(if-let [v (wcar* (car/get "rusty_key"))]
(do
(wcar* (car/set "rusty_key" nil))
v)))
;; main
(defn -main
"setup, poll redis, feed rabbit, rise-and-repeat."
[& args]
(while true
(Thread/sleep 10)
(if-let [v (fetch-rusty-key)]
(do
(println "found rusty value!" v)
(feed-rabbit v)))))
Portable
Concurrent
Fast
$ docker run -it golang
# container running...
$ mkdir -p projects/hello_world
$ cd projects/hello_world
$ nano hello_world.go
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
$ go run hello_world.go
Hello, World!
package main
import (
"log"
"time"
"github.com/streadway/amqp"
)
func main() {
log.Printf(" [*] Go-ing to sleep ")
time.Sleep(10000 * time.Millisecond)
log.Printf(" [*] Time to get to work!")
conn, _ := amqp.Dial("amqp://guest:guest@rabbitmq/")
defer conn.Close()
ch, _ := conn.Channel()
defer ch.Close()
q, _ := ch.QueueDeclare(
"go-rabbit", // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
msgs, _ := ch.Consume(
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
forever := make(chan bool)
go func() {
for d := range msgs {
log.Printf("Received a message: %s", d.Body)
}
}()
log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
<-forever
}
Honorable Mentions