构建自己的docker镜像node.js

学习资源:

构建自己的 Docker 镜像_哔哩哔哩_bilibili

针对其中的一些比较困难的点写篇文章。

以下是对app.js的注释:

// 使用 Koa 框架搭建 Node.js 应用的示例代码

// 这两行代码引入了 koa 模块,并创建了一个新的 Koa 应用实例,在node_modules文件夹中已经安装了koa库
// 正常自己创建一个项目时,运行npm install命令后,npm会查看package.json文件,然后下载所有需要的包到node_modules目录中。
// 一般不会分享node_modules文件夹(因为很大),一般会给出package.json文件,使用者自己npm install安装依赖
let Koa = require('koa');
let app = new Koa();

// 引入redis日志库(注释部分)
// const redis = require('redis');
// let rds = redis.createClient({url: "redis://redis:6379"});
// rds.on('connect', ()=> console.log('redis connect ok'))
// rds.connect();

// log4js用于配置日志
let log4js = require('log4js');
// 从log4js.json文件中读取配置信息
log4js.configure('./log4js.json');
// 所有级别为DEBUG或以上的日志都会被记录
log4js.level = 'DEBUG';
let logger = log4js.getLogger('app');

// 引入路由
let Router = require('koa-router');
let router = new Router;


// 定义路由
// 根路径 (/) 的所有 HTTP 方法 (GET, POST, PUT, DELETE 等) 的请求,都会执行这个异步函数
router.all('/', async ctx =>{
	// 记录一条日志信息,表示收到对根路径的请求
    logger.info('on index page')
	ctx.body = `index page`
});

// 对于 /hello/:name 路径的所有 HTTP 方法的请求,都会执行这个异步函数
router.all('/hello/:name', async ctx =>{
	let name = ctx.params.name
    logger.info('on hello page')
	ctx.body = `hello ${name ? name : 'world'}`
});
///

// router.all('/redis', async ctx =>{
// 	let count = await rds.incr("count")
// 	logger.info(`on test redis page, count ${count}`)
// 	ctx.body = `on test redis page, 44 count ${count} `
// });

app.use(router.routes());

let port = process.env.PORT || 8080;
try{
	app.listen(8080);
	logger.info('Server started successfully and listened on '+ port +'\n'+'http://localhost:'+port);
}catch(err){
	console.error(err);
}

使用了JavaScript的koa库框架搭建web服务器。从作者的github网站上下载项目后,之所以能直接在本地运行,是因为作者已经把node_modules文件夹(依赖安装)也一同放在了github的项目中了,因此不需要本地电脑上额外npm安装koa库,也可以直接在app.js中require库web框架koa。

整体代码比较简单,重点就是定义两个http方法的函数,检测到"/"任意http方法(GET, POST, PUT, DELETE 等),都将执行一个异步函数。最后就是容器的端口号为8080。

再看一下dockerfile:

#FROM:指定基础镜像。基础镜像是构建新镜像的基础,它包含了运行应用程序所需的操作系统和环境。
FROM node:11

#维护者信息
MAINTAINER easydoc.net

# 复制代码,将文件或目录添加到镜像中。
ADD . /app

# 设置容器启动后的默认运行目录
WORKDIR /app

# EXPOSE:指定容器对外暴露的端口。
# ENV:设置环境变量。

# 运行命令,安装依赖
# RUN 命令可以有多个,但是可以用 && 连接多个命令来减少层级。
# 例如 RUN npm install && cd /app && mkdir logs
RUN npm install --registry=https://registry.npmmirror.com

# CMD:指定容器启动后要执行的命令。
# CMD 指令只能一个,是容器启动后执行的命令,算是程序的入口。
# 如果还需要运行其他命令可以用 && 连接,也可以写成一个shell脚本去执行。
# 例如 CMD cd /app && ./start.sh,切换到app目录,./表明在当前目录下执行start.sh
CMD node app.js

FROM指定基础镜像,ADD将文件添加到镜像中,代码里的"."是添加了全部的文件,也可用COPY。其次WORKDIR设置默认运行目录。

由于是docker镜像,因此需要让docker安装依赖,RUN命令npm install安装package.json文件中的全部依赖,--registry指定国内镜像源加速。作者视频的taobao云证书过期,此处换成国内npm镜像站。

正常普通的js项目中,发布者一般不会把node_modules文件夹一并上传,因为依赖很大。一般会给出一个package.json文件,执行npm install命令就会自动安装package.json文件中的全部依赖,在dockerfile文件中的RUN npm install就已经实现了这一功能。

最后CMD指令执行文件运行。CMD 指令只能一个,指定容器启动后要执行的命令。例如 CMD cd /app && ./start.sh,切换到app目录,./表明在当前目录下执行start.sh。

看一下package.json文件中的依赖:

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "dependencies": {
    "koa": "^2.13.1",
    "log4js": "^3.0.6",
    "redis": "^4.0.0-rc.3",
    "mongodb": "^3.6.9",
    "koa-websocket": "^6.0.0",
    "koa-router": "^7.4.0"
  },
  "scripts": {
    "start": "cross-env PORT=8080 node app"
  },
  "author": "",
  "license": "ISC"
}

可以看到koa等依赖包的版本都被写入。

看到docker-compose.yml文件中:

version: "3.7"

services:
  app:
    build: ./
    ports:
      - 80:8080
    volumes:
      - ./:/app
    environment:
      - TZ=Asia/Shanghai
  redis:
    image: redis:5.0.13
    volumes:
      - redis:/data
    environment:
      - TZ=Asia/Shanghai

volumes:
  redis:

port端口从本机80映射到容器8080,这与作者最后的命令相违背,可是也能运行成功:

 docker run -p 9090:8080 --name test-hello2 test:v1

可见作者是将本机9090端口映射到容器8080端口上。而这样也能成功的原因是:当你访问主机的9090端口时,请求将被转发到容器的8080端口上,因为已经指定了,因此没有影响。

再举个例子详细讲解端口的这一问题:

docker run -p 8080:80 my-node-app

此代码8080端口为宿主机端口,80端口为docker容器端口。

外部设备想访问docker容器上构建的应用,需要访问的是http://<宿主机IP地址>:8080,在通过宿主机上的配置,宿主主机将自己的8080端口映射到docker容器的80端口。

下面开始部署:

builid镜像,test是镜像的名字,v1是版本号:

docker build -t test:v1 .

可在docker中看到新的镜像test:

执行结果如下:

PS D:\docker project\javascript-json\test-docker-main> docker build -t test:v1 .
[+] Building 41.5s (9/9) FINISHED                                                                        docker:default
 => [internal] load build definition from dockerfile                                                               0.0s
 => => transferring dockerfile: 1.02kB                                                                             0.0s
 => [internal] load metadata for docker.io/library/node:11                                                        24.4s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 74B                                                                                   0.0s
 => [internal] load build context                                                                                  0.0s
 => => transferring context: 2.13kB                                                                                0.0s
 => CACHED [1/4] FROM docker.io/library/node:11@sha256:67ca28addce8ae818b144114a9376a6603aba09069b7313618d37b3858  0.0s
 => [2/4] ADD . /app                                                                                               0.0s
 => [3/4] WORKDIR /app                                                                                             0.1s
 => [4/4] RUN npm install --registry=https://registry.npmmirror.com                                               16.3s
 => exporting to image                                                                                             0.4s
 => => exporting layers                                                                                            0.4s
 => => writing image sha256:aaca618375e243ff3d75204c585bd3039d844af9c9ac0441dc922b5aca7d474c                       0.0s
 => => naming to docker.io/library/test:v1                                                                         0.0s

View build details: docker-desktop://dashboard/build/default/default/rn5hv5c0x6m0r72ku001izv57

What's Next?
  View a summary of image vulnerabilities and recommendations → docker scout quickview
PS D:\docker project\javascript-json\test-docker-main>其次执行命令:

其次执行命令:

docker run -p 9090:8080 --name test-hello2 test:v1

原作者一开始忽略了8080:8080端口占用的情况,以及test-hello与自己上传的docker镜像相冲突名字重复的情况。

运行结果如下:

PS D:\docker project\javascript-json\test-docker-main> docker run -p 9090:8080 --name test-hello2 test:v1
[2024-05-08T11:34:15.500] [INFO] app - Server started successfully and listened on 8080
http://localhost:8080
[2024-05-08T11:35:44.270] [INFO] app - on index page
[2024-05-08T11:36:22.788] [INFO] app - on index page
[2024-05-08T11:36:59.060] [INFO] app - on index page
[2024-05-08T11:36:59.285] [INFO] app - on index page
[2024-05-08T11:36:59.491] [INFO] app - on index page
[2024-05-08T11:36:59.717] [INFO] app - on index page
[2024-05-08T11:37:00.425] [INFO] app - on index page
[2024-05-08T11:37:01.006] [INFO] app - on index page
[2024-05-08T11:37:01.504] [INFO] app - on index page

最后的很多条:[2024-05-08T11:37:01.504] [INFO] app - on index page是因为我不断在本地地址上访问localhost:9090并且不断刷新。在docker中也会被记录。

docker中的logs记录:

powershell中的记录:

docker搭建自己的镜像上传成功,使用成功。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/604013.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTTP常见面试题(二)

3.1 HTTP 常见面试题 HTTP特性 HTTP 常见到版本有 HTTP/1.1&#xff0c;HTTP/2.0&#xff0c;HTTP/3.0&#xff0c;不同版本的 HTTP 特性是不一样的。 HTTP/1.1 的优点有哪些&#xff1f; HTTP 最突出的优点是「简单、灵活和易于扩展、应用广泛和跨平台」。 1. 简单 HTTP…

关于行进线路。

https://map.tianditu.gov.cn/ 作者&#xff1a;Chockhugh 链接&#xff1a;https://www.zhihu.com/question/20545559/answer/494685117 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 以50km&#xff0c;几乎全是…

C#字符串格式化

数值规范 也可写成int money 368; money .ToString("C"); string.Format("金额&#xff1a;{0:C}", 368); > 368.00 string.Format("科学计数法&#xff1a;{0:C}", 12000.1); > 1.200001…

【软件测试】用例篇 -- 详解

一、测试用例的基本要素 测试用例&#xff08;Test Case&#xff09;是为了实施测试而向被测试的系统提供的一组集合&#xff0c;这组集合包含&#xff1a;测试环境、操作步骤、测试数据、预期结果等要素。&#xff08;注意&#xff1a;不需要执行结果&#xff0c;因为执行结果…

【Qt 学习笔记】Qt常用控件 | 输入类控件 | Dial的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 输入类控件 | Dial的使用及说明 文章编号&#xff1a;Qt…

kafka系列一:初识kafka

概述 kafka是由scala语言编写的一个分布式且具备高可用、高性能、可持久化、可水平扩展、支持流数据处理等众多特性的消息系统&#xff0c;常活跃于大数据生态中&#xff0c;而且大名鼎鼎的rocketmq就是参考了kafka的设计原理。 目前越来越多的开源分布式中间件都支持与kafka集…

Mysql:Before start of result set

解决方法&#xff1a;使用resultSet.getString&#xff08;&#xff09;之前一定要调用resultSet.next() ResultSet resultSet statement1.executeQuery();while (resultSet.next()){String username1 resultSet.getString("username");int id1 resultSet.getInt…

【C++】---继承

【C】---继承 一、继承的概念及定义1、继承的概念2、定义语法格式3、继承基类成员访问方式的变化 二、基类 和 派生类 的对象之间的赋值转换1、赋值规则2、切片&#xff08;1&#xff09;子类对象 赋值 给 父类对象&#xff08;2&#xff09;子类对象 赋值 给 父类指针&#xf…

windows11忘记登录密码怎么办?

STEP1&#xff1a;进入Win RE界面 1.按住shift不要松手,点击重新启动&#xff0c;进入WINRE界面 2.选择疑难解答 选择高级选项 点击命令提示符 STEP2:替换utilman 1.输入以下代码查看所在windows所在盘 diskpart list volume exit 2.根据所在盘输入命令&#xff08;以C盘为…

数据结构与算法(5)队列的基本操作

#include<stdio.h> #include<stdlib.h> #include<stdbool.h> typedef int ElemType; #define MaxSize 10//队列的定义 typedef struct SqQueue {ElemType data[MaxSize];int front, rear;//front为头指针&#xff0c;rear为尾指针。这里并不是真正的“指针”…

Java | Spring框架 | @Autowired与@Resource

在Spring框架中&#xff0c;依赖注入是一种核心概念&#xff0c;它允许开发者将对象的创建和对象之间的依赖关系的管理交给框架来处理。这样做的目的是为了提高代码的模块化和可测试性。 Spring提供了多种方式来实现依赖注入&#xff0c;其中最常用的方式是通过注解。在本文中…

mysql数据库---操作数据库跟表的命令总结

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文着重整理mysql管理库跟表的指令。 不涉及增删查改等指令 其实本篇主要是我做好笔记格式 用的时候直接复制粘贴的 所以排版大多是为了快速找功能来排的 方便大家快速找目标语法 数据库的简介 一个数据库系…

[Redis] 使用布隆过滤器和分布式锁实现用户注册

布隆过滤器&#xff08;Bloom Filter&#xff09;是一种数据结构&#xff0c;用于快速判断一个元素是否可能存在于一个集合中。它通过使用多个哈希函数和一个位数组来表示一个集合&#xff0c;当一个元素被加入到集合时&#xff0c;通过哈希函数计算出多个哈希值&#xff0c;并…

Hypack 2024 简体中文资源完整翻译汉化已经全部完成

Hypack 2024 简体中文资源完整翻译汉化已经全部完成 Hypack 2024&#xff0c;资源汉化共翻译11065条。毕竟涉及测绘、水文、疏浚等专业术语太多&#xff0c;翻译有很多理解不正确的地方&#xff0c;望各位专业人员指正。 压缩包内包含Hypack 2024、Hypack 2022、Hypack 2021、…

什么样的行业适合做私域?

私域营销适用于各种行业&#xff0c;但以下几个行业尤其适合进行私域营销&#xff1a; 1、零售行业&#xff1a;私域营销可以帮助零售企业建立与顾客的直接联系&#xff0c;提高顾客忠诚度和复购率。通过私域营销&#xff0c;零售企业可以进行个性化推荐、定制化服务&#xff…

JavaWeb--11MySQL(3)-- 多表设计

MySQL&#xff08;3&#xff09;-- 多表设计 1 一对多&#xff08;多对一&#xff09;2 一对一3 多对多 各个表结构之间也存在着各种联系&#xff0c;基本上分为三种&#xff1a; 一对多(多对一)多对多一对一 1 一对多&#xff08;多对一&#xff09; 一对多关系实现&#x…

【Java】IO流:字节流 字符流 缓冲流

接续上文&#xff0c;在这篇文章将继续介绍在Java中关于文件操作的一些内容【Java】文件操作 文章目录 一、“流”的概念1.“流”的分类1.1输入流和输出流1.2字节流和字符流 字节和字符的区别&#xff1f;为什么要有字符流&#xff1f;1.3节点流和处理流 字符流自带缓冲区&…

【Linux——Centos7安装RabbitMQ】 RabbitMQ无法连接

到这一步是基本已经装好了&#xff0c;现在是在开放端口&#xff0c;我这个报错是因为我的防火墙是处于关闭状态&#xff0c;所以在开放端口时会报防火墙为运行&#xff0c;把防火墙打开&#xff0c;在开放端口&#xff0c;就可以访问到了 重启防火墙&#xff1a; systemctl …

【无标题】基于GIS、Python机器学习技术的地质灾害风险评价、易发性分析与信息化建库及灾后重建中的实践技术

理解地质灾害形成机理与成灾模式&#xff1b;从空间数据处理、信息化指标空间数据库构建、致灾因子提取&#xff0c;空间分析、危险性评价与制图分析等方面掌握GIS在灾害危险性评价中的方法&#xff1b;运用地质灾害危险性评价原理和技术方法 原文链接&#xff1a;基于GIS、Py…

DeepSeek API文档:创建对话补全的指南

DeepSeek平台不仅提供了一个用户友好的聊天界面&#xff0c;还为开发者提供了强大的API接口&#xff0c;使他们能够创建和集成智能对话补全功能。以下是关于如何使用DeepSeek API创建对话补全的详细介绍。 DeepSeek API概述 DeepSeek的API允许开发者通过编程方式与DeepSeek的…
最新文章