diff --git a/Dockerfile b/Dockerfile index 0404521..e7cd630 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,10 @@ # 多阶段构建 -FROM golang:1.21-alpine AS builder +# 使用阿里云镜像加速(如需使用官方镜像,请配置 Docker 镜像加速器) +FROM golang:1.24-alpine AS builder + +# 设置 Go 代理(中国大陆用户) +ENV GOPROXY=https://goproxy.cn,direct +ENV GOSUMDB=sum.golang.google.cn # 设置工作目录 WORKDIR /app @@ -20,6 +25,7 @@ COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o main src/main.go # 最终镜像 +# 使用阿里云镜像加速(如需使用官方镜像,请配置 Docker 镜像加速器) FROM alpine:latest # 安装必要的包 @@ -47,11 +53,11 @@ RUN chown -R appuser:appgroup /app USER appuser # 暴露端口 -EXPOSE 8080 +EXPOSE 1234 # 健康检查 HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1 + CMD wget --no-verbose --tries=1 --spider http://localhost:1234/health || exit 1 # 启动应用 CMD ["./main"] diff --git a/Makefile b/Makefile index bd44e73..12e46ed 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ GOVET := go vet # Docker 相关变量 DOCKER := docker -DOCKER_COMPOSE := docker-compose +DOCKER_COMPOSE := $(DOCKER) compose # 默认目标 .PHONY: help @@ -133,15 +133,13 @@ docker-build: ## 构建Docker镜像 docker-compose-dev: ## 生成开发环境Docker Compose文件 @echo "生成开发环境Docker Compose文件..." @mkdir -p $(DOCKER_DIR) - @echo "version: '3.8'" > $(DOCKER_DIR)/docker-compose.dev.yml - @echo "" >> $(DOCKER_DIR)/docker-compose.dev.yml - @echo "services:" >> $(DOCKER_DIR)/docker-compose.dev.yml + @echo "services:" > $(DOCKER_DIR)/docker-compose.dev.yml @echo " yinli-api:" >> $(DOCKER_DIR)/docker-compose.dev.yml @echo " build:" >> $(DOCKER_DIR)/docker-compose.dev.yml @echo " context: .." >> $(DOCKER_DIR)/docker-compose.dev.yml @echo " dockerfile: Dockerfile" >> $(DOCKER_DIR)/docker-compose.dev.yml @echo " ports:" >> $(DOCKER_DIR)/docker-compose.dev.yml - @echo " - \"8080:8080\"" >> $(DOCKER_DIR)/docker-compose.dev.yml + @echo " - \"1234:1234\"" >> $(DOCKER_DIR)/docker-compose.dev.yml @echo " environment:" >> $(DOCKER_DIR)/docker-compose.dev.yml @echo " - APP_ENV=dev" >> $(DOCKER_DIR)/docker-compose.dev.yml @echo " depends_on:" >> $(DOCKER_DIR)/docker-compose.dev.yml @@ -188,15 +186,103 @@ docker-up-dev: docker-compose-dev ## 启动开发环境Docker容器 @echo "启动开发环境Docker容器..." cd $(DOCKER_DIR) && $(DOCKER_COMPOSE) -f docker-compose.dev.yml up -d +.PHONY: docker-up-stage +docker-up-stage: ## 启动预发布环境Docker容器 + @echo "启动预发布环境Docker容器..." + cd $(DOCKER_DIR) && $(DOCKER_COMPOSE) -f docker-compose.stage.yml up -d + +.PHONY: docker-up-prod +docker-up-prod: ## 启动生产环境Docker容器 + @echo "启动生产环境Docker容器..." + @echo "警告: 请确保已设置 MYSQL_ROOT_PASSWORD 和 REDIS_PASSWORD 环境变量" + cd $(DOCKER_DIR) && $(DOCKER_COMPOSE) -f docker-compose.prod.yml up -d + .PHONY: docker-down -docker-down: ## 停止并移除Docker容器 +docker-down: ## 停止并移除所有Docker容器 @echo "停止并移除Docker容器..." - cd $(DOCKER_DIR) && $(DOCKER_COMPOSE) down + @cd $(DOCKER_DIR) && \ + OUTPUT=$$($(DOCKER_COMPOSE) -f docker-compose.dev.yml -f docker-compose.stage.yml -f docker-compose.prod.yml down --remove-orphans 2>&1); \ + echo "$$OUTPUT"; \ + if echo "$$OUTPUT" | grep -q "permission denied"; then \ + echo ""; \ + echo "⚠️ 检测到权限错误,自动重启 rootless Docker 服务并重试..."; \ + systemctl --user restart docker >/dev/null 2>&1 || true; \ + sleep 3; \ + echo "重试停止容器..."; \ + $(DOCKER_COMPOSE) -f docker-compose.dev.yml -f docker-compose.stage.yml -f docker-compose.prod.yml down --remove-orphans 2>&1 || { \ + echo ""; \ + echo "❌ 仍然失败,请手动执行: systemctl --user restart docker && make docker-down"; \ + exit 0; \ + }; \ + fi + +.PHONY: docker-down-dev +docker-down-dev: ## 停止并移除开发环境Docker容器 + @echo "停止并移除开发环境Docker容器..." + @cd $(DOCKER_DIR) && $(DOCKER_COMPOSE) -f docker-compose.dev.yml down --remove-orphans 2>&1 || { \ + echo ""; \ + echo "⚠️ 如果遇到权限错误(permission denied),容器可能由 root 用户创建。"; \ + echo " 请手动执行: sudo docker compose -f docker/docker-compose.dev.yml down"; \ + exit 0; \ + } + +.PHONY: docker-down-stage +docker-down-stage: ## 停止并移除预发布环境Docker容器 + @echo "停止并移除预发布环境Docker容器..." + @cd $(DOCKER_DIR) && \ + OUTPUT=$$($(DOCKER_COMPOSE) -f docker-compose.stage.yml down --remove-orphans 2>&1); \ + echo "$$OUTPUT"; \ + if echo "$$OUTPUT" | grep -q "permission denied"; then \ + echo ""; \ + echo "⚠️ 检测到权限错误,自动重启 rootless Docker 服务并重试..."; \ + systemctl --user restart docker >/dev/null 2>&1 || true; \ + sleep 3; \ + echo "重试停止容器..."; \ + $(DOCKER_COMPOSE) -f docker-compose.stage.yml down --remove-orphans 2>&1 || { \ + echo ""; \ + echo "❌ 仍然失败,请手动执行: systemctl --user restart docker && make docker-down-stage"; \ + exit 0; \ + }; \ + fi + +.PHONY: docker-down-prod +docker-down-prod: ## 停止并移除生产环境Docker容器 + @echo "停止并移除生产环境Docker容器..." + @cd $(DOCKER_DIR) && \ + if ! $(DOCKER_COMPOSE) -f docker-compose.prod.yml down --remove-orphans 2>&1 | tee /dev/stderr | grep -q "permission denied"; then \ + :; \ + else \ + echo ""; \ + echo "⚠️ 检测到权限错误,自动重启 rootless Docker 服务并重试..."; \ + systemctl --user restart docker >/dev/null 2>&1 || true; \ + sleep 3; \ + echo "重试停止容器..."; \ + $(DOCKER_COMPOSE) -f docker-compose.prod.yml down --remove-orphans 2>&1 || { \ + echo ""; \ + echo "❌ 仍然失败,请手动执行: systemctl --user restart docker && make docker-down-prod"; \ + exit 0; \ + }; \ + fi .PHONY: docker-logs -docker-logs: ## 查看Docker容器日志 - @echo "查看Docker容器日志..." - cd $(DOCKER_DIR) && $(DOCKER_COMPOSE) logs -f +docker-logs: ## 查看开发环境Docker容器日志 + @echo "查看开发环境Docker容器日志..." + cd $(DOCKER_DIR) && $(DOCKER_COMPOSE) -f docker-compose.dev.yml logs -f + +.PHONY: docker-logs-stage +docker-logs-stage: ## 查看预发布环境Docker容器日志 + @echo "查看预发布环境Docker容器日志..." + cd $(DOCKER_DIR) && $(DOCKER_COMPOSE) -f docker-compose.stage.yml logs -f + +.PHONY: docker-logs-prod +docker-logs-prod: ## 查看生产环境Docker容器日志 + @echo "查看生产环境Docker容器日志..." + cd $(DOCKER_DIR) && $(DOCKER_COMPOSE) -f docker-compose.prod.yml logs -f + +.PHONY: docker-ps +docker-ps: ## 查看所有Docker容器状态 + @echo "查看所有Docker容器状态..." + cd $(DOCKER_DIR) && $(DOCKER_COMPOSE) -f docker-compose.dev.yml -f docker-compose.stage.yml -f docker-compose.prod.yml ps # 清理 .PHONY: clean diff --git a/PROJECT_SUMMARY.md b/PROJECT_SUMMARY.md index be8ba19..6631844 100644 --- a/PROJECT_SUMMARY.md +++ b/PROJECT_SUMMARY.md @@ -81,12 +81,48 @@ make dev ``` ### 2. Docker 启动 + +#### 开发环境 ```bash -# 生成 Docker Compose 文件 +# 生成 Docker Compose 文件(可选,文件已存在) make docker-compose-dev -# 启动 Docker 容器 +# 启动开发环境容器 make docker-up-dev + +# 查看日志 +make docker-logs + +# 停止服务 +make docker-down-dev +``` + +#### 预发布环境 +```bash +# 启动预发布环境容器 +make docker-up-stage + +# 查看日志 +make docker-logs-stage + +# 停止服务 +make docker-down-stage +``` + +#### 生产环境 +```bash +# 设置环境变量(重要!) +export MYSQL_ROOT_PASSWORD=your_secure_password +export REDIS_PASSWORD=your_redis_password + +# 启动生产环境容器 +make docker-up-prod + +# 查看日志 +make docker-logs-prod + +# 停止服务 +make docker-down-prod ``` ### 3. 运行测试 @@ -204,9 +240,15 @@ make dev ### 生产环境 ```bash +# 设置环境变量 +export MYSQL_ROOT_PASSWORD=your_secure_password +export REDIS_PASSWORD=your_redis_password + # 使用 Docker 部署 -make docker-compose-prod make docker-up-prod + +# 查看日志 +make docker-logs-prod ``` ## 📝 下一步建议 diff --git a/README.md b/README.md index b61a87b..69c9e71 100644 --- a/README.md +++ b/README.md @@ -94,16 +94,164 @@ make dev ### Docker 部署 -1. **生成 Docker Compose 文件** +项目支持三种环境的 Docker Compose 部署:dev(开发)、stage(预发布)、prod(生产)。 + +#### Docker 镜像配置(中国大陆用户) + +如果在中国大陆使用 Docker,建议配置镜像加速器以提高镜像拉取速度。项目使用官方镜像名称(如 `mysql:8.0`、`redis:7-alpine`),通过配置的 Docker 镜像加速器自动加速拉取。 + +**方法1:配置 Docker 镜像加速器(推荐)** + +根据 Docker 运行模式选择配置位置: + +**标准 Docker(需要 root 权限):** + +编辑或创建 `/etc/docker/daemon.json` 文件: + +```bash +sudo mkdir -p /etc/docker +sudo tee /etc/docker/daemon.json <<-'EOF' +{ + "registry-mirrors": [ + "https://docker.m.daocloud.io", + "https://dockerproxy.com", + "https://docker.nju.edu.cn" + ] +} +EOF +sudo systemctl daemon-reload +sudo systemctl restart docker +``` + +**Rootless Docker(无需 root 权限):** + +编辑或创建 `~/.config/docker/daemon.json` 文件: + +```bash +mkdir -p ~/.config/docker +cat > ~/.config/docker/daemon.json <<-'EOF' +{ + "registry-mirrors": [ + "https://docker.m.daocloud.io", + "https://dockerproxy.com", + "https://docker.nju.edu.cn" + ] +} +EOF +``` + +然后重启 rootless Docker(**重要:配置后必须重启才能生效**): + +```bash +# 方法1:重启 rootless Docker 服务 +systemctl --user restart docker + +# 方法2:如果使用 dockerd-rootless,需要重启用户服务 +pkill -HUP dockerd +# 或者重启整个 rootless Docker +systemctl --user stop docker.socket +systemctl --user start docker.socket +``` + +验证配置: + +```bash +docker info | grep -A 10 "Registry Mirrors" +``` + +如果看到配置的镜像源列表,说明配置成功。 + +**方法2:使用环境变量(临时)** + +```bash +# 设置 Docker 镜像代理 +export DOCKER_REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com +``` + +**常用国内镜像源(按推荐顺序):** +- DaoCloud:`https://docker.m.daocloud.io` ⭐ 推荐 +- Docker 代理:`https://dockerproxy.com` +- 南京大学:`https://docker.nju.edu.cn` +- 上海交大:`https://docker.mirrors.sjtug.sjtu.edu.cn` +- 阿里云:`https://registry.cn-hangzhou.aliyuncs.com`(需要登录) +- 中科大:`https://docker.mirrors.ustc.edu.cn`(可能不稳定) +- 网易:`https://hub-mirror.c.163.com`(可能不稳定) + +**重要提示:** +- 项目使用官方镜像名称(如 `mysql:8.0`、`redis:7-alpine`),通过配置的 Docker 镜像加速器自动加速 +- 如果镜像加速器配置正确,Docker 会自动从配置的镜像源拉取镜像 +- 如果遇到镜像拉取失败,请确保已重启 Docker 服务使配置生效:`sudo systemctl restart docker` +- **Go 模块下载**:Dockerfile 中已配置使用国内 Go 代理(`GOPROXY=https://goproxy.cn,direct`),无需额外配置 + +#### 开发环境部署 + +1. **生成 Docker Compose 文件(可选,文件已存在)** ```bash make docker-compose-dev ``` -2. **启动服务** +2. **启动开发环境服务** ```bash make docker-up-dev ``` +3. **查看日志** +```bash +make docker-logs +``` + +4. **停止服务** +```bash +make docker-down-dev +``` + +#### 预发布环境部署 + +1. **启动预发布环境服务** +```bash +make docker-up-stage +``` + +2. **查看日志** +```bash +make docker-logs-stage +``` + +3. **停止服务** +```bash +make docker-down-stage +``` + +**注意:** 预发布环境使用不同的端口映射(MySQL: 3307, Redis: 6380),避免与开发环境冲突。 + +#### 生产环境部署 + +1. **设置环境变量(重要!)** +```bash +export MYSQL_ROOT_PASSWORD=your_secure_password +export REDIS_PASSWORD=your_redis_password +``` + +2. **启动生产环境服务** +```bash +make docker-up-prod +``` + +3. **查看日志** +```bash +make docker-logs-prod +``` + +4. **停止服务** +```bash +make docker-down-prod +``` + +**注意:** +- 生产环境使用不同的端口映射(MySQL: 3308, Redis: 6381) +- 生产环境配置了健康检查和自动重启策略 +- 请务必在生产环境部署前修改配置文件中的敏感信息(JWT密钥、数据库密码等) + ## 📋 可用命令 ### 开发命令 @@ -149,12 +297,19 @@ make docs-serve # 启动文档服务器 ### Docker 操作 ```bash -make docker-build # 构建 Docker 镜像 -make docker-up-dev # 启动开发环境容器 -make docker-up-stage # 启动预发布环境容器 -make docker-up-prod # 启动生产环境容器 -make docker-down # 停止容器 -make docker-logs # 查看容器日志 +make docker-build # 构建 Docker 镜像 +make docker-compose-dev # 生成开发环境 Docker Compose 文件 +make docker-up-dev # 启动开发环境容器 +make docker-up-stage # 启动预发布环境容器 +make docker-up-prod # 启动生产环境容器 +make docker-down # 停止所有容器 +make docker-down-dev # 停止开发环境容器 +make docker-down-stage # 停止预发布环境容器 +make docker-down-prod # 停止生产环境容器 +make docker-logs # 查看开发环境容器日志 +make docker-logs-stage # 查看预发布环境容器日志 +make docker-logs-prod # 查看生产环境容器日志 +make docker-ps # 查看所有容器状态 ``` ## 🔧 配置说明 @@ -386,8 +541,15 @@ make build 3. **使用 Docker 部署** ```bash -make docker-compose-prod +# 设置环境变量 +export MYSQL_ROOT_PASSWORD=your_secure_password +export REDIS_PASSWORD=your_redis_password + +# 启动生产环境 make docker-up-prod + +# 查看日志 +make docker-logs-prod ``` ### 环境变量 @@ -451,4 +613,157 @@ A: 1. 在 `src/handler` 中添加处理函数 A: 在 `src/middleware` 目录下创建新的中间件文件,参考现有中间件的实现。 ### Q: 如何部署到生产环境? -A: 使用 `make docker-compose-prod` 生成生产环境配置,然后使用 `make docker-up-prod` 部署。 +A: +1. 设置环境变量: + ```bash + export MYSQL_ROOT_PASSWORD=your_secure_password + export REDIS_PASSWORD=your_redis_password + ``` +2. 修改 `config/prod.yaml` 中的敏感配置(JWT密钥等) +3. 启动生产环境: + ```bash + make docker-up-prod + ``` +4. 查看日志: + ```bash + make docker-logs-prod + ``` + +### Q: Docker Compose 支持哪些环境? +A: 项目支持三种环境的 Docker Compose 部署: +- **dev**: 开发环境,端口映射 MySQL:3306, Redis:6379 +- **stage**: 预发布环境,端口映射 MySQL:3307, Redis:6380 +- **prod**: 生产环境,端口映射 MySQL:3308, Redis:6381,包含健康检查和自动重启 + +### Q: Docker 镜像拉取失败怎么办? +A: 如果在中国大陆遇到镜像拉取超时或失败,可以: +1. **配置 Docker 镜像加速器**(推荐): + ```bash + sudo mkdir -p /etc/docker + sudo tee /etc/docker/daemon.json <<-'EOF' + { + "registry-mirrors": [ + "https://docker.m.daocloud.io", + "https://dockerproxy.com", + "https://docker.nju.edu.cn" + ] + } + EOF + sudo systemctl daemon-reload + sudo systemctl restart docker + ``` + + **重要:配置后必须重启 Docker 服务才能生效!** + + 验证配置: + ```bash + docker info | grep -A 10 "Registry Mirrors" + ``` + 如果看到镜像源列表,说明配置成功。 + +2. **Rootless Docker 配置**: + - 如果使用 rootless Docker(`docker version` 显示 `Context: rootless`),配置文件位置为 `~/.config/docker/daemon.json` + - 配置后重启:`systemctl --user restart docker` + - 验证:`docker info | grep -A 10 "Registry Mirrors"` + +3. **使用官方镜像名称**:项目使用官方镜像名称(如 `mysql:8.0`、`redis:7-alpine`),通过配置的 Docker 镜像加速器自动加速拉取 + +4. **Go 模块下载失败**: + - Dockerfile 中已配置使用国内 Go 代理(`GOPROXY=https://goproxy.cn,direct`) + - 如果仍然失败,可以在 Dockerfile 中修改 GOPROXY 环境变量: + ```dockerfile + ENV GOPROXY=https://goproxy.cn,https://goproxy.io,direct + ``` + - 常用 Go 代理:`https://goproxy.cn`、`https://goproxy.io`、`https://mirrors.aliyun.com/goproxy/` + +5. **检查网络连接**:确保能够访问镜像仓库 + - 测试镜像源:`curl -I https://docker.m.daocloud.io/v2/` + - 如果镜像加速器配置已生效但仍失败,可能是网络问题,可以稍后重试 + +6. **如果镜像加速器仍未生效**: + - 检查配置文件格式是否正确(JSON 格式) + - 标准 Docker:检查 `/etc/docker/daemon.json` + - Rootless Docker:检查 `~/.config/docker/daemon.json` + - 确认已重启 Docker 服务 + - 检查 Docker 服务状态:`sudo systemctl status docker` 或 `systemctl --user status docker` + +### Q: Docker 权限错误(permission denied)怎么办? +A: 如果遇到 `Error response from daemon: cannot stop container: permission denied` 错误,可能的原因和解决方法: + +1. **Docker 上下文不匹配**(常见原因): + 如果系统同时安装了标准 Docker 和 rootless Docker,容器可能由不同的上下文创建。 + + ```bash + # 查看当前 Docker 上下文 + docker context show + + # 查看所有可用的上下文 + docker context ls + + # 如果容器是由标准 Docker 创建的,切换到 default 上下文 + docker context use default + + # 然后尝试停止容器 + docker stop docker-mysql-1 + + # 如果需要切换回 rootless + docker context use rootless + ``` + + **提示**:如果容器是通过 `sudo docker compose` 创建的,通常需要使用 `default` 上下文;如果通过普通用户创建的,可能使用 `rootless` 上下文。 + +2. **临时解决方案(使用 sudo)**: + ```bash + # 停止并删除容器 + sudo docker stop docker-mysql-1 + sudo docker rm docker-mysql-1 + + # 或使用 docker compose + sudo docker compose -f docker/docker-compose.stage.yml down + ``` + +3. **永久解决方案(推荐)**:将用户添加到 `docker` 组 + ```bash + # 将当前用户添加到 docker 组 + sudo usermod -aG docker $USER + + # 重新登录或执行以下命令使组权限生效 + newgrp docker + + # 验证是否成功 + groups | grep docker + ``` + + **注意**:添加到 docker 组后,需要: + - 重新登录系统,或 + - 执行 `newgrp docker` 命令,或 + - 重新打开终端 + + 之后就可以不使用 `sudo` 直接操作 Docker 了。 + +4. **检查 Docker socket 权限**: + ```bash + ls -la /var/run/docker.sock + ``` + 应该显示类似:`srw-rw---- 1 root docker`,表示 `docker` 组有读写权限。 + +5. **如果使用 rootless Docker**: + - Rootless Docker 不需要 sudo,但需要确保 Docker 服务正在运行 + - 检查服务状态:`systemctl --user status docker` + - 启动服务:`systemctl --user start docker` + - 注意:rootless Docker 和标准 Docker 创建的容器是隔离的,不能互相管理 + - **如果遇到权限错误,可以尝试**: + ```bash + # 方法1:重启 rootless Docker 服务(推荐) + systemctl --user restart docker + # 等待几秒后,再尝试停止容器 + docker stop docker-mysql-1 + + # 方法2:使用 docker kill 强制停止 + docker kill docker-mysql-1 + docker rm docker-mysql-1 + + # 方法3:检查并修复 rootless Docker socket 权限 + ls -la /run/user/$(id -u)/docker.sock + # 应该显示类似:srw-rw---T 1 table ... + ``` diff --git a/config/prod.yaml b/config/prod.yaml index 71864a9..01f698d 100644 --- a/config/prod.yaml +++ b/config/prod.yaml @@ -3,7 +3,7 @@ server: mode: release database: - host: localhost + host: mysql # Docker环境使用服务名,本地环境使用localhost port: 3306 username: root password: sasasasa @@ -15,7 +15,7 @@ database: maxOpenConns: 500 redis: - host: localhost + host: redis # Docker环境使用服务名,本地环境使用localhost port: 6379 password: "" db: 2 diff --git a/config/stage.yaml b/config/stage.yaml index 21077c2..eb143cd 100644 --- a/config/stage.yaml +++ b/config/stage.yaml @@ -3,7 +3,7 @@ server: mode: release database: - host: localhost + host: mysql # Docker环境使用服务名,本地环境使用localhost port: 3306 username: root password: sasasasa @@ -15,7 +15,7 @@ database: maxOpenConns: 200 redis: - host: localhost + host: redis # Docker环境使用服务名,本地环境使用localhost port: 6379 password: "" db: 1 diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index d09b3bb..d336594 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -1,12 +1,10 @@ -version: '3.8' - services: yinli-api: build: context: .. dockerfile: Dockerfile ports: - - "8080:8080" + - "1234:1234" environment: - APP_ENV=dev depends_on: @@ -29,6 +27,9 @@ services: - ../sql:/docker-entrypoint-initdb.d:ro networks: - yinli-network + stop_grace_period: 60s + stop_signal: SIGTERM + init: true redis: image: redis:7-alpine diff --git a/docker/docker-compose.prod.yml b/docker/docker-compose.prod.yml new file mode 100644 index 0000000..156075c --- /dev/null +++ b/docker/docker-compose.prod.yml @@ -0,0 +1,71 @@ +services: + yinli-api: + build: + context: .. + dockerfile: Dockerfile + ports: + - "1234:1234" + environment: + - APP_ENV=prod + depends_on: + - mysql + - redis + volumes: + - ../config:/app/config:ro + networks: + - yinli-network + restart: always + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:1234/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + mysql: + image: mysql:8.0 + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: yinli + ports: + - "3308:3306" + volumes: + - mysql_prod_data:/var/lib/mysql + - ../sql:/docker-entrypoint-initdb.d:ro + networks: + - yinli-network + restart: always + stop_grace_period: 60s + stop_signal: SIGTERM + init: true + command: --default-authentication-plugin=mysql_native_password + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis:7-alpine + ports: + - "6381:6379" + volumes: + - redis_prod_data:/data + networks: + - yinli-network + restart: always + command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-} + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + mysql_prod_data: + redis_prod_data: + +networks: + yinli-network: + driver: bridge + diff --git a/docker/docker-compose.stage.yml b/docker/docker-compose.stage.yml new file mode 100644 index 0000000..a04e20c --- /dev/null +++ b/docker/docker-compose.stage.yml @@ -0,0 +1,55 @@ +services: + yinli-api: + build: + context: .. + dockerfile: Dockerfile + ports: + - "1234:1234" + environment: + - APP_ENV=stage + depends_on: + - mysql + - redis + volumes: + - ../config:/app/config:ro + networks: + - yinli-network + restart: unless-stopped + + mysql: + image: mysql:8.0 + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-sasasasa} + MYSQL_DATABASE: yinli + ports: + - "3307:3306" + volumes: + - mysql_stage_data:/var/lib/mysql + - ../sql:/docker-entrypoint-initdb.d:ro + networks: + - yinli-network + restart: unless-stopped + stop_grace_period: 60s + stop_signal: SIGTERM + init: true + command: --default-authentication-plugin=mysql_native_password + + redis: + image: redis:7-alpine + ports: + - "6380:6379" + volumes: + - redis_stage_data:/data + networks: + - yinli-network + restart: unless-stopped + command: redis-server --appendonly yes + +volumes: + mysql_stage_data: + redis_stage_data: + +networks: + yinli-network: + driver: bridge +