feat: 添加 Docker 部署支持

- Dockerfile (多阶段构建,生产优化)
  - 基于 node:18-alpine
  - 非 root 用户运行(安全)
  - 健康检查配置

- docker-compose.yml
  - 一键部署配置
  - 网络隔离
  - 自动重启策略

- .dockerignore
  - 排除不必要文件
  - 优化镜像大小

- .env.example
  - 环境变量模板

- 更新 README.md
  - Docker 部署文档
  - 常用命令示例
  - 生产环境配置
This commit is contained in:
Coding Expert
2026-03-23 09:51:26 +08:00
parent 8e25bf51b8
commit 4dc8350fca
5 changed files with 269 additions and 0 deletions

47
.dockerignore Normal file
View 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
View File

@@ -0,0 +1,11 @@
# 环境变量配置
# 复制此文件为 .env 并根据需要修改
# 服务端口
PORT=3000
# 运行环境
NODE_ENV=production
# Docker 网络配置(可选)
# DOCKER_NETWORK=ip-network

44
Dockerfile Normal file
View 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
View File

@@ -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 # 前端客户端库
├── index.html # 示例页面
├── package.json # 项目配置
├── Dockerfile # Docker 镜像配置
├── docker-compose.yml # Docker Compose 配置
├── .dockerignore # Docker 忽略配置
├── .env.example # 环境变量示例
├── .gitignore # Git 忽略配置
├── start.bat # Windows 启动脚本
├── start.sh # Linux 启动脚本

29
docker-compose.yml Normal file
View 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