使用docker-compose.yml来部署node项目

3,715 阅读4分钟

一、使用docker-compose.ymlDockerfile构建项目

  • 1、项目基本介绍

    使用express框架的路由访问views目录下的静态文件

  • 2、项目的基本结构

    .
    ├── Dockerfile
    ├── README.md
    ├── docker-compose.yml
    ├── index.js
    ├── package-lock.json
    ├── package.json
    └── views
        ├── index.html
        └── other.html
    
  • 3、index.js文件代码

    const express = require('express')
    const app = express()
    const router = express.Router()
    
    const path = __dirname + '/views/'
    const port = 8080
    
    router.use(function (req, res, next) {
      console.log('/' + req.method)
      next()
    })
    
    router.get('/', function (req, res) {
      res.sendFile(path + 'index.html')
    })
    
    router.get('/other', function (req, res) {
      res.sendFile(path + 'other.html')
    })
    
    app.use(express.static(path))
    app.use('/', router)
    
    app.listen(port, function () {
      console.log(`Example app listening on port ${port}!`)
    })
    
  • 4、Dockerfile文件内容

    FROM node:9.0
    COPY . /app
    WORKDIR /app
    RUN npm install --registry=https://registry.npm.taobao.org
    EXPOSE 8080
    CMD node index.js
    
  • 5、docker-compose.yml文件内容

    version: '3'
    
    services: 
      nodejs: 
       # 指定以当前目录下的Dockerfile文件打包成镜像
        build: 
          context: .
          dockerfile: Dockerfile
        image: nodejs
        container_name: nodejs
        restart: unless-stopped
        ports: 
          - "8080:8080"
        networks: 
          - app-network
    
    networks:
      app-network:
        driver: bridge
    
    • image:指定镜像
    • restart: 重启规则
    • prots: 暴露端口
    • networks: 加入网络
  • 6、测试运行容器,然后访问8080端口

    docker-compose up -d --build
    

二、结合nginx代理到node服务

  • 1、上面项目中创建一个nginx-conf/nginx.conf的文件

    server {
      listen 80;
      listen [::]:80;
      server_tokens off;
    
      # 可以修改为自己的域名
      server_name location;
    
      # 访问 / 访问的目录
      location / {
        root /var/www/html;
        index index.html index.htm;
      }
      # 反向代理到node服务
      location /nodejs {
        # 这里 nodejs 是 node 容器名
        proxy_pass http://nodejs:8080/nodejs;
      }
    }
    
    
  • 2、修改docker-compose.yml文件

    version: '3'
    
    services: 
      nodejs: 
        # 指定以当前目录下的Dockerfile文件打包成镜像
        build: 
          context: .
          dockerfile: Dockerfile
        image: nodejs
        container_name: nodejs
        restart: unless-stopped
        # ports: 
        #   - "8080:8080"
        networks: 
          - app-network
      
      # 新增静态服务器
      webServer:
        image: nginx:stable-alpine
        container_name: webServer
        restart: unless-stopped
        ports: 
          - "80:80"
        # 数据卷,将本地的文件与docker容器中的目录关联起来
        volumes: 
          - ./web:/var/www/html
          - ./nginx-conf:/etc/nginx/conf.d
        depends_on: 
          - nodejs
        networks: 
          - app-network
    
    networks:
      app-network:
        driver: bridge
    
  • 3、修改index.js文件(主要是考虑nginx反向代理上写的路径)

    ...
    router.get('/nodejs', function (req, res) {
      res.sendFile(path + 'index.html')
    })
    
    router.get('/nodejs/other', function (req, res) {
      res.sendFile(path + 'other.html')
    })
    ...
    
  • 4、删除之前的镜像,重新生成镜像

    docker-compose up -d --build
    
  • 5、查看日志

    docker-compose  logs -f
    
  • 6、在web/index.html文件中随便输入点东西,localhost可以访问到,访问localhost/nodejs/other可以到代理的nodejs服务

三、连接mysql

  • 1、修改docker-compose.yml文件,添加mysql配置

    version: '3'
    
    services: 
      nodejs: 
        # 指定以当前目录下的Dockerfile文件打包成镜像
        build: 
          context: .
          dockerfile: Dockerfile
        image: nodejs
        container_name: nodejs
        restart: unless-stopped
        # ports: 
        #   - "8080:8080"
        # 本次新增的
        depends_on:
          - db
        networks: 
          - app-network
      
      # 新增静态服务器
      webServer:
        image: nginx:stable-alpine
        container_name: webServer
        restart: unless-stopped
        ports: 
          - "80:80"
        # 数据卷,将本地的文件与docker容器中的目录关联起来
        volumes: 
          - ./web:/var/www/html
          - ./nginx-conf:/etc/nginx/conf.d
        depends_on: 
          - nodejs
        networks: 
          - app-network
      # 连接数据库(本次新增的)
      db:
        image:  mysql:5.7 #daocloud.io/library/mysql:8
        container_name: db
        restart: unless-stopped
        ports: 
          - "3306:3306"
        environment: 
          - MYSQL_ROOT_PASSWORD=123456
          - MYSQL_USER=test1 # 创建一个test1的用户
          - MYSQL_PASSWORD=test1 # test1用户密码
          - MYSQL_DATABASE=nodeApp
          - TZ=Asia/Shanghai # 设置时区
        volumes: 
          - ./mysql/data:/var/lib/mysql                                                                             
          - ./mysql/conf:/etc/mysql/conf.d                                                                          
          - ./mysql/logs:/log    
          - ./mysql/init:/docker-entrypoint-initdb.d                                                                                   
        command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
        # command: --default-authentication-plugin=mysql_native_password #这行代码解决无法访问的问题
    
        networks: 
          - app-network
    
    networks:
      app-network:
        driver: bridge
    
  • 2、在本项目下创建mysql及对应的目录结构

  • 3、在index.js配置数据库连接

    const mysql = require('mysql')
    const connection = mysql.createConnection({
      host: 'db',
      port: 3306,
      // 也可以直接用root用户
      user: 'root',
      password: '123456',
      database: 'nodeApp'
    })
    
  • 4、定义访问的路由

    router.get('/nodejs/mysql', function (req, res) {
      connection.query('select 1 + 1 as total', function (err, results, fields) {
        if (err) {
          console.log(err)
          res.end(JSON.stringify(err))
        }
        console.log('测试代码')
        res.end('total' + results[0].total)
      })
    })
    
  • 5、测试

  • 6、补充说明,查找镜像可以去国内镜像仓库

四、关于docker-compose.yml部署mysql的几点补充

  • 1、如果使用的mysql版本比较高要开启mysql/init里面的授权

    -- mysql5.7以上的版本授权
    use mysql;
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; 
    flush privileges; 
    
  • 2、如果你node代码里面不是用root用户连接也要授权

    -- 非root用户授权
    use mysql;
    ALTER USER 'test1'@'%' IDENTIFIED WITH mysql_native_password BY 'test1';
    flush privileges;
    

五、使用自己的镜像

  • 1、阿里私人镜像

  • 2、在上面创建一个自己的镜像(必须先创建)

  • 3、将项目中的Dockerfileindex.js及依赖包拷贝到一个单独的文件夹下,并且可以创建一个.dockerignore文件

    ➜  test1 tree .
    .
    ├── Dockerfile
    ├── index.js
    ├── package-lock.json
    └── package.json
    
    0 directories, 4 files
    
    .idea
    .node_modules
    node_modules
    .vscode
    
  • 4、使用命令生成镜像

    docker build -t kuangshp/node_express . 
    
  • 5、查看本地生成的镜像

  • 6、将本地镜像发布到阿里云私人仓库

    # 在自己的阿里云docker私人仓库那边可以查看自己的
    sudo docker login --username=xxx@163.com registry.cn-shanghai.aliyuncs.com
    sudo docker tag [ImageId] registry.cn-shanghai.aliyuncs.com/xx/node_express:[镜像版本号]
    sudo docker push registry.cn-shanghai.aliyuncs.com/xx/node_express:[镜像版本号]
    
  • 7、修改docker-compose.yml中的配置

    version: '3'
    
    services: 
      nodejs: 
        # 指定以当前目录下的Dockerfile文件打包成镜像
        # build: 
        #   context: .
        #   dockerfile: Dockerfile
        image: registry.cn-shanghai.aliyuncs.com/kuangshp/node_express:latest
        # image: nodejs
        container_name: nodejs
        restart: unless-stopped
        # ports: 
        #   - "8080:8080"
        depends_on:
          - db
        networks: 
          - app-network
      
      # 新增静态服务器
      webServer:
        image: nginx:stable-alpine
        container_name: webServer
        restart: unless-stopped
        ports: 
          - "80:80"
        # 数据卷,将本地的文件与docker容器中的目录关联起来
        volumes: 
          - ./web:/var/www/html
          - ./nginx-conf:/etc/nginx/conf.d
        depends_on: 
          - nodejs
        networks: 
          - app-network
      # 连接数据库
      db:
        image:  mysql:5.7 #daocloud.io/library/mysql:8
        container_name: db
        restart: unless-stopped
        ports: 
          - "3306:3306"
        environment: 
          - MYSQL_ROOT_PASSWORD=123456
          - MYSQL_USER=test1 # 创建一个test1的用户
          - MYSQL_PASSWORD=test1 # test1用户密码
          - MYSQL_DATABASE=nodeApp
          - TZ=Asia/Shanghai # 设置时区
        volumes: 
          - ./mysql/data:/var/lib/mysql                                                                             
          - ./mysql/conf:/etc/mysql/conf.d                                                                          
          - ./mysql/logs:/log    
          - ./mysql/init:/docker-entrypoint-initdb.d                                                                                   
        command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
        # command: --default-authentication-plugin=mysql_native_password #这行代码解决无法访问的问题
    
        networks: 
          - app-network
    
    networks:
      app-network:
        driver: bridge
    
  • 8、运行

    docker-compose up -d --build