feat: 添加 Docker 部署支持
- Dockerfile (多阶段构建,生产优化) - 基于 node:18-alpine - 非 root 用户运行(安全) - 健康检查配置 - docker-compose.yml - 一键部署配置 - 网络隔离 - 自动重启策略 - .dockerignore - 排除不必要文件 - 优化镜像大小 - .env.example - 环境变量模板 - 更新 README.md - Docker 部署文档 - 常用命令示例 - 生产环境配置
This commit is contained in:
47
.dockerignore
Normal file
47
.dockerignore
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# 依赖
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# 日志
|
||||||
|
logs/
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# 系统文件
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
desktop.ini
|
||||||
|
|
||||||
|
# 编辑器
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# 环境变量
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.production
|
||||||
|
|
||||||
|
# 临时文件
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
*.tmp
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
docker-compose.override.yml
|
||||||
|
.docker/
|
||||||
|
|
||||||
|
# Git
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# 文档
|
||||||
|
*.md
|
||||||
|
!README.md
|
||||||
|
|
||||||
|
# 启动脚本
|
||||||
|
start.bat
|
||||||
|
start.sh
|
||||||
11
.env.example
Normal file
11
.env.example
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# 环境变量配置
|
||||||
|
# 复制此文件为 .env 并根据需要修改
|
||||||
|
|
||||||
|
# 服务端口
|
||||||
|
PORT=3000
|
||||||
|
|
||||||
|
# 运行环境
|
||||||
|
NODE_ENV=production
|
||||||
|
|
||||||
|
# Docker 网络配置(可选)
|
||||||
|
# DOCKER_NETWORK=ip-network
|
||||||
44
Dockerfile
Normal file
44
Dockerfile
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# 多阶段构建 - 生产环境镜像
|
||||||
|
FROM node:18-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 复制 package 文件
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
RUN npm ci --only=production && npm cache clean --force
|
||||||
|
|
||||||
|
# 复制源代码
|
||||||
|
COPY server.js ./
|
||||||
|
COPY ip-service.js ./
|
||||||
|
COPY index.html ./
|
||||||
|
|
||||||
|
# 生产环境镜像
|
||||||
|
FROM node:18-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 创建非 root 用户(安全最佳实践)
|
||||||
|
RUN addgroup -g 1001 -S nodejs && \
|
||||||
|
adduser -S nodejs -u 1001
|
||||||
|
|
||||||
|
# 从 builder 阶段复制依赖和代码
|
||||||
|
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
|
||||||
|
COPY --chown=nodejs:nodejs server.js ./
|
||||||
|
COPY --chown=nodejs:nodejs ip-service.js ./
|
||||||
|
COPY --chown=nodejs:nodejs index.html ./
|
||||||
|
COPY --chown=nodejs:nodejs package.json ./
|
||||||
|
|
||||||
|
# 切换到非 root 用户
|
||||||
|
USER nodejs
|
||||||
|
|
||||||
|
# 暴露端口
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# 健康检查
|
||||||
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||||
|
CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
CMD ["node", "server.js"]
|
||||||
138
README.md
138
README.md
@@ -197,6 +197,140 @@ server {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Docker 部署(推荐)
|
||||||
|
|
||||||
|
### 方式一:Docker Compose(最简单)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 克隆项目
|
||||||
|
git clone http://git.joywaygames.cn:3000/daoqi/ip-service.git
|
||||||
|
cd ip-service
|
||||||
|
|
||||||
|
# 2. 构建并启动
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# 3. 查看状态
|
||||||
|
docker-compose ps
|
||||||
|
|
||||||
|
# 4. 查看日志
|
||||||
|
docker-compose logs -f
|
||||||
|
|
||||||
|
# 5. 测试
|
||||||
|
curl http://localhost:3000/api/get-ip
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方式二:纯 Docker 命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 构建镜像
|
||||||
|
docker build -t ip-service:latest .
|
||||||
|
|
||||||
|
# 2. 运行容器
|
||||||
|
docker run -d \
|
||||||
|
--name ip-service \
|
||||||
|
-p 3000:3000 \
|
||||||
|
--restart unless-stopped \
|
||||||
|
-e NODE_ENV=production \
|
||||||
|
ip-service:latest
|
||||||
|
|
||||||
|
# 3. 查看状态
|
||||||
|
docker ps
|
||||||
|
|
||||||
|
# 4. 查看日志
|
||||||
|
docker logs -f ip-service
|
||||||
|
|
||||||
|
# 5. 测试
|
||||||
|
curl http://localhost:3000/api/get-ip
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方式三:生产环境部署(带 Nginx)
|
||||||
|
|
||||||
|
创建 `docker-compose.prod.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
ip-service:
|
||||||
|
build: .
|
||||||
|
container_name: ip-service
|
||||||
|
restart: unless-stopped
|
||||||
|
expose:
|
||||||
|
- "3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
networks:
|
||||||
|
- app-network
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: nginx
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
|
- ./ssl:/etc/nginx/ssl:ro
|
||||||
|
depends_on:
|
||||||
|
- ip-service
|
||||||
|
networks:
|
||||||
|
- app-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
app-network:
|
||||||
|
driver: bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
启动:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose -f docker-compose.prod.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker 常用命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 启动
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# 停止
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# 重启
|
||||||
|
docker-compose restart
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
docker-compose logs -f
|
||||||
|
|
||||||
|
# 重新构建
|
||||||
|
docker-compose build --no-cache
|
||||||
|
|
||||||
|
# 进入容器
|
||||||
|
docker-compose exec ip-service sh
|
||||||
|
|
||||||
|
# 查看资源使用
|
||||||
|
docker stats ip-service
|
||||||
|
|
||||||
|
# 清理(删除容器和镜像)
|
||||||
|
docker-compose down --rmi all
|
||||||
|
```
|
||||||
|
|
||||||
|
### 更新部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 拉取最新代码
|
||||||
|
git pull origin master
|
||||||
|
|
||||||
|
# 2. 重新构建并启动
|
||||||
|
docker-compose up -d --build
|
||||||
|
|
||||||
|
# 3. 清理旧镜像
|
||||||
|
docker image prune -f
|
||||||
|
```
|
||||||
|
|
||||||
## 配置
|
## 配置
|
||||||
|
|
||||||
### 环境变量
|
### 环境变量
|
||||||
@@ -221,6 +355,10 @@ ip-service/
|
|||||||
├── ip-service.js # 前端客户端库
|
├── ip-service.js # 前端客户端库
|
||||||
├── index.html # 示例页面
|
├── index.html # 示例页面
|
||||||
├── package.json # 项目配置
|
├── package.json # 项目配置
|
||||||
|
├── Dockerfile # Docker 镜像配置
|
||||||
|
├── docker-compose.yml # Docker Compose 配置
|
||||||
|
├── .dockerignore # Docker 忽略配置
|
||||||
|
├── .env.example # 环境变量示例
|
||||||
├── .gitignore # Git 忽略配置
|
├── .gitignore # Git 忽略配置
|
||||||
├── start.bat # Windows 启动脚本
|
├── start.bat # Windows 启动脚本
|
||||||
├── start.sh # Linux 启动脚本
|
├── start.sh # Linux 启动脚本
|
||||||
|
|||||||
29
docker-compose.yml
Normal file
29
docker-compose.yml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
ip-service:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: ip-service
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- PORT=3000
|
||||||
|
volumes:
|
||||||
|
# 可选:挂载日志目录
|
||||||
|
- ./logs:/app/logs
|
||||||
|
networks:
|
||||||
|
- ip-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
networks:
|
||||||
|
ip-network:
|
||||||
|
driver: bridge
|
||||||
Reference in New Issue
Block a user