GVKun编程网logo

一步步学会用docker部署应用(nodejs版)(docker部署nodejs项目)

11

针对一步步学会用docker部署应用(nodejs版)和docker部署nodejs项目这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Doceker部署Node.js、Docker-入门(

针对一步步学会用docker部署应用(nodejs版)docker部署nodejs项目这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Doceker部署Node.js、Docker - 入门(二),docker&nodeJs制作镜像与本地部署、Docker中怎么使用dockerfile启动node.js应用、Docker学习(三)java应用docker部署等相关知识,希望可以帮助到你。

本文目录一览:

一步步学会用docker部署应用(nodejs版)(docker部署nodejs项目)

一步步学会用docker部署应用(nodejs版)(docker部署nodejs项目)

一步步学会用docker部署应用

docker是一种虚拟化技术,可以在内核层隔离资源。因此对于上层应用而言,采用docker技术可以达到类似于虚拟机的沙盒环境。这大大简化了应用部署,让运维人员无需陷入无止境繁琐的依赖环境及系统配置中;另一方面,容器技术也可以充分利用硬件资源,做到资源共享。

本文将采用docker技术部署一个简单的nodejs应用,它包括一个简单的前置网关nginx、redis服务器以及业务服务器。同时使用dockerfile配置特定镜像,采用docker-compose进行容器编排,解决依赖、网络等问题。

docker基础

本文默认机器已安装docker环境,即可以使用docker和docker-compose服务,如果本地没有安装,则参考:

  1. 安装docker及docker-compose,可参考 Install Docker Compose

  2. docker compose 技术可以查看官方文档 Docker Compose

docker源

默认docker采用官方镜像,国内用户下载镜像速度较慢,为了更好的体验,建议切换源。 OSX系统通过添加 ~/.docker/daemon.json文件,

{
  "registry-mirrors": ["http://f1361db2.m.daocloud.io/"]
}

即可,镜像源地址可替换,随后重启docker服务即可。

linux系统通过修改 /etc/docker/daemon.josn文件,一样可以替换源。

docker简单操作

源切换完毕之后,就可以尝试简单的容器操作。 首先,运行一个简单的容器:

docker run -it node:8-slim node

run命令,根据某个版本的node镜像运行容器,同时执行 “node”命令,进入node命令行交互模式。

docker run -d node:8-slim node

执行 -d 选项,让容器以daemon进程运行,同时返回容器的hash值。根据该hash值,我们可以通过命令行进入运行的容器查看相关状态:

docker exec -it hashcode bash

hashcode可以通过

docker ps -l

找到对应容器的hashcode

关于镜像的选择以及版本的确定,可以通过访问官方 https://hub.docker.com/ 搜索,根据结果寻找 official image使用,当然也可根据下载量和star数量进行选择。

对于镜像的tag,则根据业务需求进行判断是否需要完整版的系统。如nodejs镜像,仅仅需要node基础环境而不需要其他的系统预装命令,因此选择了 node:<version>-slim 版本。

Dockerfile

从源下载的镜像大多数不满足实际的使用需求,因此需要定制镜像。镜像定制可以通过运行容器安装环境,最后提交为镜像:

docker run -it node:8-slim bash
root@ff05391b4cf8:/# echo helloworld > /home/text
root@ff05391b4cf8:/# exit
docker commit ff05391b4cf8 node-hello

然后运行该镜像即可。

另一种镜像定制可以通过Dockerfile的形式完成。Dockerfile是容器运行的配置文件,每次执行命令都会生成一个镜像,直到所有环境都已设置完毕。

Dockerfile文件中可以执行命令定制化镜像,如 “FROM、COPY、ADD、ENV、EXPOSE、RUN、CMD”等,具体dockerfile的配置可参考相关文档。

Dockerfile完成后,进行构建镜像:

docker build -t node:custom:v1 .

镜像构建成功后即可运行容器。

docker-compose

关于docker-compose,将在下文示例中进行说明。

示例:搭建nodejs应用

本文所有代码已开源至github

docker-compose.yml

在docker-compose.yml中配置相关服务节点,同时在每个服务节点中配置相关的镜像、网络、环境、磁盘映射等元信息,也可指定具体Dockerfile文件构建镜像使用。

version: ''3''
services:
  nginx:
    image: nginx:latest
    ports:
      - 80:80
    restart: always  
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - /tmp/logs:/var/log/nginx

  redis-server:
    image: redis:latest
    ports:
      - 6479:6379
    restart: always

  app:
    build: ./
    volumes:
      - ./:/usr/local/app
    restart: always  
    working_dir: /usr/local/app
    ports:
      - 8090:8090
    command: node server/server.js
    depends_on:
      - redis-server
    links:
      - redis-server:rd

redis服务器

首先搭建一个单节点缓存服务,采用官方提供的redis最新版镜像,无需构建。

version: ''3''
services:
  redis-server:
    image: redis:latest
    ports:
      - 6479:6379
    restart: always

关于version具体信息,可参考Compose and Docker compatibility matrix找到对应docker引擎匹配的版本格式。 在services下,创建了一个名为 redis-server 的服务,它采用最新的redis官方镜像,并通过宿主机的6479端口向外提供服务。并设置自动重启功能。

此时,在宿主机上可以通过6479端口使用该缓存服务。

web应用

使用node.js的koa、koa-router可快速搭建web服务器。在本节中,创建一个8090端口的服务器,同时提供两个功能:1. 简单查询单个key的缓存 2. 流水线查询多个key的缓存

docker-compose.yml

services:
  app:
    build: ./
    volumes:
      - ./:/usr/local/app
    restart: always  
    working_dir: /usr/local/app
    ports:
      - 8090:8090
    command: node server/server.js
    depends_on:
      - redis-server
    links:
      - redis-server:rd

此处创建一个app服务,它使用当前目录下的Dockerfile构建后的镜像,同时通过 volumes 配置磁盘映射,将当前目录下所有文件映射至容器的/usr/local/app,并制定为运行时目录;同时映射宿主机的8090端口,最后执行node server/server.js命令运行服务器。

通过depends_on设置app服务的依赖,等待 redis-server 服务启动后再启动app服务;通过links设置容器间网络连接,在app服务中,可通过别名 rd 访问redis-server。

Dockerfile

FROM node:8-slim
COPY ./ /usr/local/app
WORKDIR /usr/local/app
RUN npm i --registry=https://registry.npm.taobao.org
ENV NODE_ENV dev
EXPOSE 8090  

指定的Dockerfile则做了初始化npm的操作。

web-server sourcecode

const Koa = require(''koa'');
const Router = require(''koa-router'');
const redis = require(''redis'');
const { promisify } = require(''util'');


let app = new Koa();
let router = new Router();
let redisClient = createRedisClient({
    // ip为docker-compose.yml配置的redis-server别名 rd,可在应用所在容器查看dns配置
    ip: ''rd'',
    port: 6379,
    prefix: '''',
    db: 1,
    password: null
});

function createRedisClient({port, ip, prefix, db}) {
    let client = redis.createClient(port, ip, {
        prefix,
        db,
        no_ready_check: true
    });
    
    client.on(''reconnecting'', (err)=>{
        console.warn(`redis client reconnecting, delay ${err.delay}ms and attempt ${err.attempt}`);
    });
    
    client.on(''error'', function (err) {
        console.error(''Redis error!'',err);
    });
    
    client.on(''ready'', function() {
        console.info(`redis初始化完成,就绪: ${ip}:${port}/${db}`);
    });
    return client;
}

function execReturnPromise(cmd, args) {
    return new Promise((res,rej)=>{
        redisClient.send_command(cmd, args, (e,reply)=>{
            if(e){
                rej(e);
            }else{
                res(reply);
            }
        });
    });
}

function batchReturnPromise() {
    return new Promise((res,rej)=>{
        let b = redisClient.batch();
        b.exec = promisify(b.exec);
        res(b);
    });
}


router.get(''/'', async (ctx, next) => {
    await execReturnPromise(''set'',[''testkey'',''helloworld'']);
    let ret = await execReturnPromise(''get'',[''testkey'']);
    ctx.body = {
        status: ''ok'',
        result: ret,
    };
});

router.get(''/batch'', async (ctx, next) => {
    await execReturnPromise(''set'',[''testkey'',''helloworld, batch!'']);
    let batch = await batchReturnPromise();
    for(let i=0;i < 10;i++){
        batch.get(''testkey'');
    }
    let ret = await batch.exec();
    ctx.body = {
        status: ''ok'',
        result: ret,
    };
});

app
  .use(router.routes())
  .use(router.allowedMethods())
  .listen(8090);

需要注意的是,在web服务所在的容器中,通过别名 rd 访问缓存服务。

此时,运行命令 docker-compose up后,即可通过 http://127.0.0.1:8090/ http://127.0.0.1:8090/batch 访问这两个缓存服务。

转发

目前可以通过宿主机的8090端口访问服务,为了此后web服务的可扩展性,需要在前端加入转发层。实例中使用nginx进行转发:

services:
  nginx:
    image: nginx:latest
    ports:
      - 80:80
    restart: always  
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - /tmp/logs:/var/log/nginx

采用最新版的nginx官方镜像,向宿主机暴露80端口,通过在本地配置nginx的抓发规则文件,映射至容器的nginx配置目录下实现快速高效的测试。

运行与扩展

默认单节点下,直接运行

docker-compose up -d

即可运行服务。

如果服务节点需要扩展,可通过

docker-compose up -d --scale app=3

扩展为3个web服务器,同时nginx转发规则需要修改:

upstream app_server { # 设置server集群,负载均衡关键指令
    server docker-web-examples_app_1:8090; # 设置具体server,
    server docker-web-examples_app_2:8090;
    server docker-web-examples_app_3:8090;
}

server {
    listen 80;
    charset utf-8;

    location / {
        proxy_pass http://app_server;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Forwarded-Host $server_name;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

app_server内部的各个服务器名称为docker-web-examples_app_1,format为“${path}${service}${number}”,

即第一部分为 docker-compose.yml所在目录名称,如果在根目录则为应用名称; 第二部分为扩展的服务名; 第三部分为扩展序号

通过设置nginx的配置的log_format中upstream_addr变量,可观察到负载均衡已生效。

http{
    log_format  main  ''$remote_addr:$upstream_addr - $remote_user [$time_local] "$request" ''
                      ''$status $body_bytes_sent "$http_referer" ''
                      ''"$http_user_agent" "$http_x_forwarded_for"'';
}

参考

docker官方文档

docker-compose.yml 配置文件编写详解

Dockerfile实践

Doceker部署Node.js

Doceker部署Node.js

前言

    项目中会用到node做中间层,部署node则是用到了docker,在这里总结、记录下部署要点和步骤;关于docker的介绍和安装这里就不赘述了,网上也有很多相关的教程和文章了,需要可自行搜索查看。

项目结构
`-- docker-node
    |-- data
    |-- server
        |-- app.js
        |-- Dockerfile
        |-- process.yml
        |-- package.json
    |-- docker-compose.yml

1、创建Node.js程序

app.js

const express = require(''express'');
const app = express();

app.get(''/'', (req, res) => res.send(''hello world!''));

app.listen(3008);

2、创建Dockerfile

FROM node:8.9-alpine

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

RUN npm set registry https://registry.npm.taobao.org/

RUN npm install 

CMD ["./node_modules/pm2/bin/pm2-docker", "process.yml"]

从Dockerfile中可以看到我们是通过pm2-docker运行node应用的,利用PM2我们可以监听文件变化,达到应用重启、日志分存等效果;这里我们需要一个process.yml的配置文件,相关用法可以查看PM2文档。

process.yml

apps:
  - script   : ''app.js''
    name     : ''dokcer-node''
    exec_mode: ''fork''
    watch    : true
    instances: 1
    log_date_format : ''YYYY-MM-DD HH:mm Z''
    ignore_watch: [''node_modules'']

3、创建docker-compose.yml

生产环境上我们用到往往不只一个容器,我们可以通过一个配置文件来管理多个Docker容器,然后使用docker-compose来启动,停止、重启应用。

docker-compose.yml

version: "3.0"
services:
  server_node:
    container_name: server-node
    build: 
      context: ./server
    volumes:
      - ./server:/usr/src/app
    ports:
      - "3008:3008"
    environment:
      - TZ=Asia/Shanghai

  portainer:
    image: portainer/portainer:1.11.4
    container_name: portainer
    expose:
      - "9000"
    ports:
      - "9000:9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./data/portainer:/data
    environment:
      - TZ=Asia/Shanghai

4、启动容器

上述几个文件创建完毕,我们执行下面的命令,则会创建我们的镜像并且启动容器

$ docker-compose -f docker-compose.yml up -d

5、测试

1、访问本地的3008端口
图片描述

2、测试当代码变化,node自动重启功能,我们把"hello world!"改为"restart!!!!",再次刷新页面
图片描述

3、利用Portainer管理容器;可视化的界面相比命令行来说,我们可以很方便、快速查看容器日志、容器配置、状态、以及对进行重启、删除等操作;我们访问本地9000端口即可(docker-compese.yml中配置),结果如下。
图片描述

Docker - 入门(二),docker&nodeJs制作镜像与本地部署

Docker - 入门(二),docker&nodeJs制作镜像与本地部署

在熟悉docker基本命令与运作逻辑后,尝试实战。

目标:制作一个nodejs服务镜像,并使用nginx反向代理,在本地跑通。

本次项目配置与工具构成:

  1. node后端:使用阿里的 Egg.js 脚手架
  2. db:mongodb
  3. nginx
  4. NoSqlBooster for MongoDB,一个mongodb可视化工具
  5. postman 一个可以发起网络请求的工具,用于测试

注:本机操作系统为 macOS

本文主讲docker部分,其余知识面仅描述部分

准备工作:

  1. docker镜像:nginx:latest、node:10.15.3、mongo:latest
  2. docker-compose可用
  3. Egg.js脚手架初始化后端项目,命名为 egg-center

项目配置

Egg.js

安装egg-mongoose库,以便连接mongodb。

数据库配置,修改./config/config.default.js

  config.mongoose = {
    clients: {
      center: {
        url: ''mongodb://你本地的内网ip:27017/example'',
        options: {
          dbName: ''center'', // 数据库名,自己取
          user: '''', // 连接数据库的账号,默认为空
          pass: '''', // 连接数据库的账号,默认为空
        }
      }
    }
  }
接下来写一个后台用户管理系统

在 ./app/controller 下新增对应的控制器、在./app/model下新增对应的表结构。

然后写几个简单的接口,修改:./app/router.js,定义路由:

''use strict''

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app
  router.get(''/'', controller.home.index)

  /* 新增用户 */
  router.post(''/api/admin/user'', controller.admin.user.create)
  
  /* 用户列表 */
  router.get(''/api/admin/user'', controller.admin.user.index)
  
  ...略
}

本地启动服务测试: npm run dev
本地使用 postman 调通接口,造些测试数据。

修改package.json

"start": "egg-scripts start --deamon --title=egg-server-egg-center",

修改为:

"start": "egg-scripts start --title=egg-server-egg-center",

删除出--deamon,我们是在docker里跑项目,所以需要node服务跑在docker前台。

配置Dockerfile

Egg.js根目录(./)下新增文件:

  1. Dockerfile // Egg.js镜像制作的配置文件
  2. docker-compose.yml // Egg.js和nginx容器的配置
  3. mongodb-compose.yml // mongodb容器的配置
  4. nginx.conf // nginx配置文件

我们本次部署不使用jenkins,采用较为简单的部署方式。

解释下为什么要把mongodb的配置单独写:
1.绝大部分情况,数据库都是不关闭的,而业务服务器和nginx是会随着版本迭代等影响重启,所以将mongodb的配置单独拎出来
2.业务服务会依赖mongodb启动,若写在同一个docker-compose文件里会出现异步问题,即mongodb还未完全启动至ready状态,node服务已经启动连接数据库报错了。

接下来看文件内容。

Dockerfile:

FROM node:10.15.3 # 使用node:10.15.3镜像
RUN mkdir -p /egg-center # 在容器中新建目录文件夹 egg-center
WORKDIR /egg-center # 将 /egg-center 设置为默认工作目录
COPY package.json /egg-center/package.json
RUN yarn --production # 先copy package.json文件至容器,并安装依赖
COPY . /egg-center # 再copy代码至容器。也可以部分先后直接copy整个代码
EXPOSE 7006 # 暴露7006端口

docker-compose.yml:

version: ''3''
services:
  nginx:
    image: nginx:latest # 使用nginx:latest镜像
    ports:
      - 8080:8080 # 宿主机端口:容器端口
    volumes:
      - "/Users/liaoxinyu/JsProject/eggJsProject/server/egg-center/nginx.conf:/etc/nginx/conf.d/nginx.conf" # 挂载nginx配置文件
  egg-center:
    build:
      context: . # 以Dockerfile文件配置 build
    ports:
      - 7006:7006 # 宿主机端口:容器端口,用于nginx转发
    command: ["npm", "start"] # 启动服务

配置mongodb容器,修改mongodb-compose.yml:

version: ''3''
services:
  mongodb:
    image: mongo:latest # 使用mongo:latest镜像
    ports:
      - 27017:27017 # 宿主机端口:容器端口
    volumes:
      - "/Users/liaoxinyu/db/mongodb/data:/data/db/" # 挂载数据库目录至本地,若不挂载,容器关闭后数据丢失。

修改nginx.conf:

upstream api {
    server 10.10.1.31:7006;
} # 后端服务容器 端口:ip

server {
    listen         8080; # 监听8080端口,docker-compose里做的映射
    server_name    localhost; # 本地配置就直接用localhost了,线上的话改成域名或公网ip

    location /api {
        # /api前缀的请求,全部转发至Egg.js服务
        proxy_pass http://api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location / {
        # 可写多个location,转发至不同的服务或静态资源路由
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri /index.html;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

启动项目:
1.先启动数据库:docker-compose -f mongodb-compose.yml up
2.数据库完全启动后,启动Egg.js服务与nginx:docker-compose up

验证:
1.使用 NoSqlBooster for MongoDB 连接数据库,配置很简单,配置ip:port,查看数据库内容
2.使用 postman 请求 http://localhost:8080/api/admin/user,这里发的请求是直接发到nginx代理的8080上。 由nginx转发至业务服务端口7006。

线上服务器就直接请求域名了,且不对外公开业务服务器的公网ip:端口。

结束

附:使用nginx - docker镜像部署服务器,配置https,附带java后端部署例子

Docker中怎么使用dockerfile启动node.js应用

Docker中怎么使用dockerfile启动node.js应用

这篇文章主要介绍“Docker中怎么使用dockerfile启动node.js应用”,在日常操作中,相信很多人在Docker中怎么使用dockerfile启动node.js应用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Docker中怎么使用dockerfile启动node.js应用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

编写 dockerfile

以 express 自动创建的目录为例,目录结构如下:

├── /bin
│  └── www
├── /node_modules
├── /public
├── /routes
├── /views
├── package-lock.json
├── package.json
├── ecosystem.config.js
├── app.js
└── dockerfile

在项目目录下新建 dockerfile 文件

from node:10.15
maintainer sunhengzhe@foxmail.com
copy . /app/
workdir /app
run npm install pm2 -g
expose 8003
cmd ["pm2-runtime", "ecosystem.config.js"]
  • from 指定基础镜像为 node 的 10.15 版本(node 官方版本可)

  • maintainer 说明镜像的维护者

  • copy 命令将宿主机的文件拷贝到镜像中,格式为 copy [--chown=<user>:<group>] <源路径>... <目标路径>,这里将项目目录下的所有文件都拷贝到镜像中的 /app 目录下。如果目标路径不存在,docker 将自动创建。

  • workdir 用来指定工作目录,即是 cmd 执行所在的目录。

  • run 命令用来执行 shell 命令,这里用来安装 pm2

  • expose 命令用来 声明 运行时容器提供服务端口,但要注意运行时并不会开启这个端口的服务。这个命令主要是帮助使用者理解这个镜像服务的守护端口,以方便配置映射;另外在使用随机端口映射时,会自动随机映射 expose 的端口

  • cmd 是默认的容器主进程的启动命令

构建镜像

在项目目录下执行

docker build -t express-app:v1 .

如果构建成功,查看镜像列表

docker images

应该会输出镜像 express-app:v1

Docker中怎么使用dockerfile启动node.js应用

运行容器

docker run -d -p 8003:3000 --name="express-app" express-app:v1

docker run 是 docker create 和 docker start 两个命令的简写。

  • -d 即 --detach,代表让容器后台运行。

  • -p 指定宿主机和容器的端口映射,左边为宿主机的端口,右边为容器的端口,也就是说访问宿主机的 8003 端口,会映射到容器内的 3000 端口。

  • --name 设置容器别名,如果不指定,docker 会随机生成一个名字,比如 tender_swirles 之类的。

执行

docker ps

正常展示如下

Docker中怎么使用dockerfile启动node.js应用

添加 -a 参数可以查看所有已启动容器。

进入容器

如果要进入容器进行操作,执行下面命令

docker exec -it express-app bash

Docker中怎么使用dockerfile启动node.js应用

-i 与 -t 一般结合使用,-i 启动交互模式,-t 指定需要分配终端,可以自行尝试不传其中一个的效果。

与 exec 类似的还有 attach 命令,命令为 docker attach express-app,但从这个 stdin 中 exit,会导致容器的停止,所以推荐使用 exec 命令。

关闭操作

停止容器

docker stop express-app

删除容器

docker rm express-app

如果删除时容器还在运行,需要加上 -f 参数

删除镜像

docker rmi express-app:v1

到此,关于“Docker中怎么使用dockerfile启动node.js应用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注小编网站,小编会继续努力为大家带来更多实用的文章!

Docker学习(三)java应用docker部署

Docker学习(三)java应用docker部署

我们之前写的java微服务部署服务器都比较麻烦,需要先在服务器装好java,配置好环境变量,然后上传war,jar包到服务器部署。尤其是之前没有使用springboot的时候还要安装tomact,今天就来说说使用docker部署。

准备java服务

pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.mike</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

启动类:

package com.mike.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

编写一个简单的api接口:

package com.mike.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class Hello {
    
    @GetMapping("/say/{word}")
    public String say(@PathVariable("word") String word) {
        return String.format("heelo,%s", word);
    }
}

编写dockerfile

Dockerfile:

FROM java:8
MAINTAINER mike 342746156@qq.com
COPY target/demo-0.0.1-SNAPSHOT.jar hello.jar
ENTRYPOINT ["java","-jar","/hello.jar"]
EXPOSE 8080

Dockerfile 指定了构建docker镜像的步骤。

FROM:第一层我们需要一个jdk,我们申明使用 java:8, docker引擎会帮我们自动从公共仓库下载,并当道我们的运行容器环境中。

MAINTAINER: 申明了作者,可以不写

COPY:把maven打包好的jar添加到容器中并重命名为 hello.jar

ENTRYPOINT: 要执行的命令以及参数。 使用java -jar 启动我们的应用

EXPOSE:暴漏容器中的8080端口。这样我们就可以映射宿主机的端口到8080端口,从而访问容器中的应用了

开始制作镜像

我们首先要在工程目录使用mvn install 生成应用的jar包,在target目录下会有生成的jar包。本地maven仓库中也有我们的jar包。

现在开始制作镜像。在Dockerfile所在目录执行docker命令:

docker build -t mike-hello .

注意 . 表示当前目录,不可少。这样我们的镜像就制作成功了。运行docker 命令:

docker images

就可以看到我们构建好的镜像,但是我们的应用还没有启动起来。接下来就用这个镜像启动一个容器运行我们的应用

启动镜像

运行docker命令:

docker run -d -p 127.0.0.1:8080:8080 mike-hello

-d声明后台守护进程的方式运行, -p声明宿主机和容器内部的端口映射,将宿主机本地的8080端口映射到容器内部8080端口,在制作镜像的时候我们就将8080端口暴漏出来了。现在运行docker命令:

docker ps

就可以看到当前启动的容器,就会看到我们的应用了。现在测试一下,在宿主机上访问:http://localhost:8080/api/say/docker

看到返回消息: heelo,docker。测试成功

现在我们进入容器内部看看:

docker exec -ti 我们的容器id bash

这样就可以查看容器中的目录,使用curl命令测试下容器内部我们的应用

curl http://localhost:8080/api/say/docker

一样可以看到我们的消息正常返回,现在如果你想在部署一个,那么就很简单了:

docker run -d -p 127.0.0.1:8081:8080 mike-hello
docker run -d -p 127.0.0.1:8082:8080 mike-hello
docker run -d -p 127.0.0.1:8083:8080 mike-hello

 总结

docker简化了我们的应用部署,只要制作好了镜像,你想部署多少,都是一个命令就搞定,不用去在重复配置一次应用环境。而且借助私有仓库,你可以直接在其他多个服务器也依靠一条命令居马上启动一个应用。现在我们已经简单掌握了如何去使用docker,但是构建部署还是要自己去输命令搞,还是有点麻烦,我们只想写完自己的代码上传代码到仓库,剩下的就一键搞定。那么下节课就来使用jenkins来实现CICD,彻底解放你。

欢迎关注我的公中号:mike啥都想搞,一起交流学习

mike啥都想搞

我们今天的关于一步步学会用docker部署应用(nodejs版)docker部署nodejs项目的分享已经告一段落,感谢您的关注,如果您想了解更多关于Doceker部署Node.js、Docker - 入门(二),docker&nodeJs制作镜像与本地部署、Docker中怎么使用dockerfile启动node.js应用、Docker学习(三)java应用docker部署的相关信息,请在本站查询。

本文标签: