目标:创建一个nodejs网页服务
下载安装docker desktop
创建项目目录
选定目录创建项目文件,例如:
C:\docker_program\cross-border-logistics-chatbot
创建dockerfile文件
# 使用Node.js官方镜像
FROM node:18-alpine
# 设置工作目录
WORKDIR /app
# 复制package.json(先复制这个文件,利用Docker缓存)
COPY package.json .
# 安装依赖
RUN npm install
# 复制应用代码和HTML文件
COPY index.js .
COPY html/ ./html/
# 暴露端口
EXPOSE 3000
# 启动命令
CMD ["node", "index.js"]
检查文件,发现还需要package.json和index.js。
package.json是 Node.js 项目的核心配置文件,就像项目的"身份证"和"说明书"。
index.js是 Node.js 应用程序的入口文件,就像程序的"大脑"和"控制中心"。
创建package.json文件:
{
"name": "simple-agent",
"version": "1.0.0",
"description": "一个简单的智能体服务",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "node index.js"
},
"dependencies": {
"express": "^4.18.0"
}
}
创建index.js
javascript
const express = require('express');
const path = require('path');
const app = express();
const port = 3000;
// 中间件:解析JSON请求体
app.use(express.json());
// 静态文件服务 - 提供HTML文件
app.use(express.static(path.join(__dirname, 'html')));
// 根路径 - 重定向到index.html
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'html', 'index.html'));
});
// 健康检查接口
app.get('health', (req, res) => {
res.json({
status: 'healthy',
service: '智能体服务',
timestamp: new Date().toISOString(),
uptime: process.uptime()
});
});
// 简单的聊天接口
app.post('apichat', (req, res) => {
const { message } = req.body;
if (!message) {
return res.status(400).json({
error: '请提供message参数'
});
}
// 模拟智能回复
const responses = [
`你好!你说的是:${message}`,
`我收到了你的消息:${message}`,
`很有意思:${message},能告诉我更多吗?`,
`关于${message},你有什么具体问题?`
];
const randomResponse = responses[Math.floor(Math.random() * responses.length)];
res.json({
original_message: message,
reply: randomResponse,
timestamp: new Date().toISOString(),
message_id: Math.random().toString(36).substr(2, 9)
});
});
// 启动服务器
app.listen(port, '0.0.0.0', () => {
console.log('=================================');
console.log('🚀 智能体服务已启动!');
console.log(`📍 本地访问 http://localhost:${port}`);
console.log(`🌐 健康检查 http://localhost:${port}/health`);
console.log('=================================');
});
// 优雅关闭
process.on('SIGINT', () => {
console.log('\n正在关闭服务...');
process.exit(0);
});
在项目下创建一个文件夹存储网页,命名为html。
在html文件夹下创建index.html
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个 Docker 网页</title>
<style>
body {
font-family: Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
color: white;
}
.container {
text-align: center;
background: rgba(255, 255, 255, 0.1);
padding: 40px;
border-radius: 15px;
backdrop-filter: blur(10px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 2.5em;
margin-bottom: 20px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
p {
font-size: 1.2em;
opacity: 0.9;
}
.docker-logo {
font-size: 3em;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="docker-logo">🐳</div>
<h1>这是我的第一个 Docker 搭建的网页</h1>
<p>成功使用 Docker 容器运行静态网页!</p>
<p>服务器时间: <span id="datetime"></span></p>
</div>
<script>
// 显示当前时间
function updateDateTime() {
const now = new Date();
document.getElementById('datetime').textContent = now.toLocaleString('zh-CN');
}
updateDateTime();
setInterval(updateDateTime, 1000);
</script>
</body>
</html>
接下来开始创建Docker镜像(把项目和环境打包在一块)
在当前目录打开命令行,运行:
html
docker build -t my_first_docker_program:latest .
↑ ↑ ↑ ↑ ↑
命令 子命令 选项 镜像标签 当前目录
使用命令运行Docker容器
html
docker run -d -p 3000:3000 --name my_first_docker_program my_first_docker_program:latest
↑ ↑ ↑ ↑ ↑ ↑
命令 子命令 选项 端口映射 容器名称 镜像名称:标签
或者使用Docker Desktop软件内启动。
运行成功,打开浏览器验证:
html
http://localhost:3000