有一个node应用,部署在多个容器中,需要用到redis存储,同时我想要将node应用和redis独立开来,然后用Nginx在最前端负载均衡这些应用。
1 Nginx container
可以得到如下架构图:
有两种方法可以构建该连接,一:从空白的操作镜像(如:Ubuntu、Debian等)开始构建;二:从一个预先构建好的镜像;这里选择使用一个Redis镜像、一个Nginx镜像和一个基于Ubuntu的node镜像
Redis container
从官方Docker Hub中下载Redis镜像,构建一个Redis容器,端口默认6379
docker run -d --name redis -p 6379:6379 redis
***Dockerfile ***:
# Set the base image to Ubuntu
FROM ubuntu
# File Author / Maintainer
MAINTAINER InfiniteRain
# Update the repository and install Redis Server
RUN apt-get update && apt-get install -y redis-server
# Expose Redis port 6379
EXPOSE 6379
# Run Redis Server
ENTRYPOINT ["/usr/bin/redis-server"]
Node container
从Node镜像中生成一个node容器,同时在应用中指定6379端口为redis侦听的端口。
index.js
var express = require('express'),
http = require('http'),
redis = require('redis');
var app = express();
console.log(process.env.REDIS_PORT_6379_TCP_ADDR + ':' + process.env.REDIS_PORT_6379_TCP_PORT);
var client = redis.createClient('6379', 'redis');
app.get('/', function(req, res, next) {
client.incr('counter', function(err, counter) {
if(err) return next(err);
res.send('This page has been viewed ' + counter + ' times!, HOSTNAME:' + process.env.HOSTNAME);
http.createServer(app).listen(process.env.PORT || 8080, function() {
console.log('Listening on port ' + (process.env.PORT || 8080));
***Dockerfile ***:
# Set the base image to Ubuntu
FROM ubuntu
# File Author / Maintainer
MAINTAINER InfiniteRain
# Install Node.js and other dependencies
RUN apt-get update && \
apt-get -y install curl && \
curl -sL https://deb.nodesource.com/setup_8.x | sudo bash - && \
apt-get -y install python build-essential nodejs
# Install nodemon
RUN npm install -g nodemon
# Provides cached layer for node_modules
ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /src && cp -a /tmp/node_modules /src/
# Define working directory
WORKDIR /src
ADD . /src
# Expose port
EXPOSE 8080
# Run app using nodemon
CMD ["nodemon", "/src/index.js"]
使用Dockerfile构建一个镜像
docker build -t infinite/node .
创建一个Node容器,指定8080端口,并且连接redis容器
docker run -d --name node -p 8080 --link redis:redis infinite/node
依照上述方法创建三个相同的容器 node1、node2、node3
Nginx container
同样从Docker Hub中拉取镜像,并生成一个名为infinite/nginx的容器
Nginx中关于负载均衡的配置
nginx.conf
worker_processes 4;
events { worker_connections 1024; }
http {
upstream node-app {
least_conn;
server node1:8080 weight=10 max_fails=3 fail_timeout=30s;
server node2:8080 weight=10 max_fails=3 fail_timeout=30s;
server node3:8080 weight=10 max_fails=3 fail_timeout=30s;
server {
listen 80;
location / {
proxy_pass http://node-app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
Dockerfile
# Set nginx base image
FROM nginx
# File Author / Maintainer
MAINTAINER InfiniteRain
# Copy custom configuration file from the current directory
COPY nginx.conf /etc/nginx/nginx.conf
docker build -t infinite/nginx .
docker run -d --name nginx -p 80:80 --link node:node infinite/nginx
使用Docker Compose组合应用程序
docker-compose.yml
nginx:
build: ./nginx
links:
- node1:node1
- node2:node2
- node3:node3
ports:
- "80:80"
node1:
build: ./node
links:
- redis
ports:
- "8080"
node2:
build: ./node
links:
- redis
ports:
- "8080"
node3:
build: ./node
links:
- redis
ports:
- "8080"
redis:
image: redis
ports:
- "6379"
上述YAML文件为各个容器定义了名称,指定了Dockerfile文件,同时还包括了容器之间的连接关系。只需要一个命令docker-compose up
就可以建好这五个容器了。最后文件结构如图: