使用Docker讓你的開發環境變單純

如果要MySQL資料庫

docker run --name database -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1234 -d mysql

// 第二個資料庫
docker run --name database2 -p 3307:3306 -e MYSQL_ROOT_PASSWORD=1234 -d mysql:5.6
  • 取得container的IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' database
  • 執行命令
docker exec -it database mysql -u root -p

使用docker-compose 來組合服務

  • MongoDB
// docker-compose.yaml
version: '3.3'
services:
  mongo:
    image: 'mongo:latest'
    container_name: 'mongo'
    ports:
      - '27100:27017'
  • 建立環境
// 同目錄下
docker-compose up -d --build

// 指定目錄
docker-compose up -d --build -f ./docker-compose.yaml

// 觀看目前執行container
docker-compose ps

MongoDB & Go

version: '3.3'
services:
  api:
    container_name: 'api'
    build: './api'
    ports:
      - '8080:8080'
    volumes:
      - './api:/go/src/app'
    depends_on:
      - 'mongo'
  mongo:
    image: 'mongo:latest'
    container_name: 'mongo'
    ports:
      - '27100:27017'
  • 建立Go 應用系統環境
// 建立Go程式目錄
mkdir api && cd api

// 建立 Dockerfile
FROM golang:1.8

WORKDIR /go/src/app
COPY . .

RUN go get github.com/pilu/fresh
RUN go-wrapper download
RUN go-wrapper install

CMD [ "fresh" ]
  • 建立main.go 程式
package main

import (
  "encoding/json"
  "io/ioutil"
  "log"
  "net/http"
  "os"
  "time"
  "github.com/rs/cors"
  "github.com/gorilla/mux"
  "gopkg.in/mgo.v2"
)

type Post struct {
  Text      string    `json:"text" bson:"text"`
  CreatedAt time.Time `json:"createdAt" bson:"created_at"`
}

var posts *mgo.Collection

func main() {
  // Connect to mongo
  session, err := mgo.Dial("mongo:27017")
  if err != nil {
    log.Fatalln(err)
    log.Fatalln("mongo err")
    os.Exit(1)
  }
  defer session.Close()
  session.SetMode(mgo.Monotonic, true)
  // Get posts collection
  posts = session.DB("app").C("posts")

  // Set up routes
  r := mux.NewRouter()
  r.HandleFunc("/posts", createPost).
    Methods("POST")
  http.ListenAndServe(":8080", cors.AllowAll().Handler(r))
  log.Println("Listening on port 8080...")
}

func createPost(w http.ResponseWriter, r *http.Request) {
  // Read body
  data, err := ioutil.ReadAll(r.Body)
  if err != nil {
    responseError(w, err.Error(), http.StatusBadRequest)
    return
  }
  // Read post
  post := &Post{}
  err = json.Unmarshal(data, post)
  if err != nil {
    responseError(w, err.Error(), http.StatusBadRequest)
    return
  }
  post.CreatedAt = time.Now().UTC()
  // Insert new post
  if err := posts.Insert(post); err != nil {
    responseError(w, err.Error(), http.StatusInternalServerError)
    return
  }
  responseJSON(w, post)
}

func responseError(w http.ResponseWriter, message string, code int) {
  w.Header().Set("Content-Type", "application/json")
  w.WriteHeader(code)
  json.NewEncoder(w).Encode(map[string]string{"error": message})
}

func responseJSON(w http.ResponseWriter, data interface{}) {
  w.Header().Set("Content-Type", "application/json")
  json.NewEncoder(w).Encode(data)
}
  • 增加測試程式 main_test.go
package main

import "testing"

func TestSanity(t *testing.T) {
  t.Log("Has sanity")
}

// 執行測試
docker-compose run api go test -v
  • 重建container
docker-compose up -d --build

增加web server Nginx

  • docker-compose.yml
web:
  container_name: 'web'
  image: 'nginx:latest'
  ports:
    - '8081:80'
  volumes:
    - './web:/usr/share/nginx/html'
  depends_on:
    - 'api'
  • 建立web目錄
mkdir web && cd web

// Dockerfile
FROM nginx
COPY . /usr/share/nginx/html
  • 建立index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Dockerized Posts</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
  <h1>Dockerized Posts</h1>
  <form id="form">
    <input type="text" placeholder="New post..." id="post-input">
  </form>
  <div id="posts"></div>
  <script>
    $(document).ready(function() {
      $.get('http://localhost:8080/posts', function(posts) {
        $list = $('#posts');
        for (var i = 0; i < posts.length; i++) {
          $list.append('<p>' + posts[i].text + '</p>');
        }
      });
      $('#form').submit(function(event) {
        event.preventDefault();
        var text = $('#post-input').val();
        $.post('http://localhost:8080/posts', JSON.stringify({text: text}), function() {
          location.reload();
        });
      });
    });
  </script>
</body>
</html>
  • 重建docker-compose
docker-compose up -d --build