fundon / fundon.github.io

Fundon's Moving Castle
https://fundon.viz.rs
MIT License
20 stars 3 forks source link

Using Docker Compose in Node.js Project #19

Open fundon opened 8 years ago

fundon commented 8 years ago

Why use Docker Compose?

Published on Medium.

Docker 到底有什么优点吸引我们?

说了这么多,那就让我们玩起来!

0. Install Docker Tools

$ brew install docker docker-machine docker-compose
$ docker help

NOTE:

$ mkdir docker-express-mongoose-reis-example
$ cd docker-express-mongoose-redis-example
$ npm init
$ npm i express express-session connect-redis ioredis mongoose --save
$ touch server.js 

_server.js_

// Import modules
const express = require('express')
const session = require('express-session')
const ioredis = require('ioredis')
const RedisStore = require('connect-redis')(session)
const mongoose = require('mongoose')

// Create App
const app = express()

// Redis Client
const client = ioredis.createClient(6379, process.env.REDIS_PORT_6379_TCP_ADDR)

// Compose Schema
const ComposeSchema = new mongoose.Schema({
  name:  String,
  build: String,
  ports: [String]
})

// Compose Model
const Compose = mongoose.model('Compose', ComposeSchema) 

// Create Session
app.use(session({
  store: new RedisStore({ client }),
  secret: 'Dream'
}))

// Routes for redis
app.get('/redis', (req, res) => {
  res.send('Redis is live!')
})
app.get('/redis/set', (req, res) => {
  client.set('key', 'Redis is live!');
  res.send(`It's redis.`)
})
app.get('/redis/get', (req, res) => {
  client.get('key').then(result => {
    res.send(result || 'Nothing!')
  })
})

// Routes for redis
app.get('/mongoose', (req, res) => {
  res.send('Mongoose is live!')
})
app.get('/mongoose/set', (req, res) => {
  var c = new Compose({
    name: 'docker',
    build: '.',
    ports: ['3000:3000']
  })

  c.save().then(() => {
      res.send(`It's mongoose.`);
    })
})
app.get('/mongoose/get', (req, res) => {
  Compose
    .find({ name: 'docker' })
    .then((result) => {
      res.send(result)
    })
})

app.use((req, res) => {
  res.send('Hello Docker, Express, Mongoose, Redis!')
})

mongoose.connect(`mongodb://${process.env.MONGO_PORT_27017_TCP_ADDR}`, (err) => {
  if (err) throw err

  // Start App
  app.listen(process.env.PORT || 3000)
})

_package.json_

{
  "name": "docker-express-mongoose-redis-example",
  "private": true,
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "connect-redis": "^3.0.1",
    "express": "^4.13.3",
    "express-session": "^1.11.3",
    "ioredis": "^1.9.1",
    "mongoose": "^4.2.0"
  }
}

2. Machine:在 virtualbox 中创建 Docker Host

$ # 查看命令行帮助
$ docker-machine
$ # 创建 Docker Host
$ docker-machine create -d virtualbox dev
$ # 启动
$ docker-machine start dev
$ # 查看 dev IP
$ docker-machine ip dev
$ # 查看 dev 环境变量
$ docker-machine env dev
$ # 设置环境变量
$ eval "$(docker-machine env dev)"

3. Compose:定义及操作

为项目创建 Dockerfile
$ cd docker-express-mongoose-redis-example
$ touch Dockerfile

_Dockerfile_

FROM mhart/alpine-node
# FROM mhart/alpine-node:base
# FROM mhart/alpine-node:base-0.10

WORKDIR /src
ADD . .

# If you have native dependencies, you'll need extra tools
RUN apk add --update make gcc g++ python

# If you need npm, don't use a base tag
RUN npm install

# If you had native dependencies you can now remove build tools
RUN apk del make gcc g++ python && \
  rm -rf /tmp/* /var/cache/apk/* /root/.npm /root/.node-gyp

EXPOSE 3000
CMD ["npm", "start"]
创建 docker-compose.yml 来组合 Node.js, Redis, Mongodb 服务
$ cd docker-express-mongoose-redis-example
$ touch docker-compose.yml

_Dockerfile_

app:
  build: .
  volumes:
    - .:/src
  links:
    - mongo
    - redis
  ports:
    - 3000:3000

redis:
  image: redis

mongo:
  image: mongo
$ # 查看命令行帮助
$ docker-compose
$ # 创建
$ docker-compose build
$ # 启动 app, redis, mongo 等服务,特点是常驻前台
$ docker-compose up
$ # 也可以通过 `start` 启动,特点是常驻在后台
$ docker-compose start
$ # 停止服务
$ docker-compose stop
$ # 输出日志
$ docker-compose logs
测试、访问我们的服务 :rocket:
$ open "http://$(docker-machine ip dev):3000"
$ open "http://$(docker-machine ip dev):3000/redis"
$ open "http://$(docker-machine ip dev):3000/redis/set"
$ open "http://$(docker-machine ip dev):3000/redis/get"
$ open "http://$(docker-machine ip dev):3000/mongoose"
$ open "http://$(docker-machine ip dev):3000/mongoose/set"
$ open "http://$(docker-machine ip dev):3000/mongoose/get"

关闭服务,休息下

$ docker-compose stop
$ docker-machine stop dev

NOTE:

Vargant 是一款不错的工具,可以帮助我们快速搭建各种服务环境,也能团队之间进行分享,现在基于它的工具链也越来越丰富,感兴趣也可以一试。

“自己动手,丰衣足食” - 不依赖环境构建工具,自己搭,时间精力充足的化,不妨一试,会收获更多。

最后

Docker 可玩的不仅仅如此,还可以打包、发布容器应用到线上,构建自己的 Paas(dokku) 服务等。

Docker Compose 也可以有更高级玩法。

Enjoy!

{
  github: '@fundon',
  email: 'cfddream#gmail.com',
  twitter: '@_fundon'
}

Relates

fundon commented 8 years ago

@i5ting 抱歉,文章来得太晚了,周内搞定。 :rocket:

i5ting commented 8 years ago

棒棒哒~

fundon commented 8 years ago

@i5ting 有空帮忙,review 下。thanks

TengfeiQi commented 8 years ago

👍