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 # 前端客户端库
|
||||
├── 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
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