From edebac1f9d71597bb3eb60a5f33e577523da732e Mon Sep 17 00:00:00 2001 From: sugar1569 Date: Wed, 18 Mar 2026 13:05:07 +0800 Subject: [PATCH] =?UTF-8?q?feat(docker):=20=E6=B7=BB=E5=8A=A0=20Docker=20?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E8=84=9A=E6=9C=AC=E5=92=8C=20Makefile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- help/docker/Makefile | 627 +++++++++++++++++++++++++++++++++ help/docker/README.md | 165 ++++++++- help/docker/docker-compose.yml | 9 +- help/docker/run.sh | 430 ++++++++++++++++++++++ 4 files changed, 1225 insertions(+), 6 deletions(-) create mode 100644 help/docker/Makefile create mode 100644 help/docker/run.sh diff --git a/help/docker/Makefile b/help/docker/Makefile new file mode 100644 index 000000000..dd4cd2a57 --- /dev/null +++ b/help/docker/Makefile @@ -0,0 +1,627 @@ +# CRMEB Docker Makefile +# 提供便捷的 Docker 环境管理命令 + +SHELL := /bin/bash +COMPOSE_FILE ?= docker-compose.yml +COMPOSE_COMMAND := docker-compose -f $(COMPOSE_FILE) + +# 颜色定义 +RED := \033[0;31m +GREEN := \033[0;32m +YELLOW := \033[1;33m +CYAN := \033[0;36m +NC := \033[0m + +# ==================== 从 docker-compose.yml 自动读取配置 ==================== + +# 提取服务块的函数(只匹配到下一个服务或网络定义) +# MySQL 配置 +MYSQL_CONTAINER := $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep 'container_name:' | awk '{print $$2}') +MYSQL_IMAGE := $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep 'image:' | awk '{print $$2}') +MYSQL_PORT_OUT := $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep ':3306"' | sed 's/.*"\([0-9]*\):.*/\1/') +MYSQL_ROOT_PWD := $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep 'MYSQL_ROOT_PASSWORD:' | awk '{print $$2}') +MYSQL_USER := $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep 'MYSQL_USER:' | awk '{print $$2}') +MYSQL_PWD := $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep 'MYSQL_PASSWORD:' | awk '{print $$2}') +MYSQL_DB := $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep 'MYSQL_DATABASE:' | awk '{print $$2}') +MYSQL_IP := $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep 'ipv4_address:' | awk '{print $$2}') +# MySQL内部端口(从端口映射提取) +MYSQL_PORT_IN := $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep -E ':[0-9]+"' | head -1 | sed 's/.*:\([0-9]*\)".*/\1/') +# MySQL数据目录映射 +MYSQL_DATA_LOCAL := $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep '/var/lib/mysql' | sed 's/.*- *\([^:]*\):.*/\1/') +MYSQL_DATA_CONTAINER := /var/lib/mysql +# MySQL日志目录映射 +MYSQL_LOG_LOCAL := $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep '/var/log/mysql' | sed 's/.*- *\([^:]*\):.*/\1/') +MYSQL_LOG_CONTAINER := /var/log/mysql +# MySQL配置文件目录(可选,如果未映射则显示默认路径) +MYSQL_CONF_LOCAL := $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep '/etc/mysql' | sed 's/.*- *\([^:]*\):.*/\1/') +MYSQL_CONF_CONTAINER := $(or $(shell sed -n '/^[[:space:]]*mysql:/,/^[[:space:]]*redis:/p' $(COMPOSE_FILE) | grep '/etc/mysql' | sed 's/.*:\([^ ]*\).*/\1/'),/etc/mysql/conf.d/my.cnf) + +# Redis 配置 +REDIS_CONTAINER := $(shell sed -n '/^[[:space:]]*redis:/,/^[[:space:]]*phpfpm:/p' $(COMPOSE_FILE) | grep 'container_name:' | awk '{print $$2}') +REDIS_IMAGE := $(shell sed -n '/^[[:space:]]*redis:/,/^[[:space:]]*phpfpm:/p' $(COMPOSE_FILE) | grep 'image:' | awk '{print $$2}') +REDIS_PORT_OUT := $(shell sed -n '/^[[:space:]]*redis:/,/^[[:space:]]*phpfpm:/p' $(COMPOSE_FILE) | grep ':6379"' | sed 's/.*"\([0-9]*\):.*/\1/') +REDIS_PWD := $(shell sed -n '/^[[:space:]]*redis:/,/^[[:space:]]*phpfpm:/p' $(COMPOSE_FILE) | grep 'REDIS_PASSWORD:' | awk '{print $$2}') +REDIS_IP := $(shell sed -n '/^[[:space:]]*redis:/,/^[[:space:]]*phpfpm:/p' $(COMPOSE_FILE) | grep 'ipv4_address:' | awk '{print $$2}') +# Redis内部端口 +REDIS_PORT_IN := $(shell sed -n '/^[[:space:]]*redis:/,/^[[:space:]]*phpfpm:/p' $(COMPOSE_FILE) | grep -E ':[0-9]+"' | head -1 | sed 's/.*:\([0-9]*\)".*/\1/') +# Redis配置文件(可选) +REDIS_CONF_LOCAL := $(shell sed -n '/^[[:space:]]*redis:/,/^[[:space:]]*phpfpm:/p' $(COMPOSE_FILE) | grep 'redis.conf' | sed 's/.*- *\([^:]*\):.*/\1/') +REDIS_CONF_CONTAINER := $(or $(shell sed -n '/^[[:space:]]*redis:/,/^[[:space:]]*phpfpm:/p' $(COMPOSE_FILE) | grep 'redis.conf' | sed 's/.*:\([^ ]*\).*/\1/'),/usr/local/etc/redis/redis.conf) + +# PHP 配置 +PHP_CONTAINER := $(shell sed -n '/^[[:space:]]*phpfpm:/,/^[[:space:]]*nginx:/p' $(COMPOSE_FILE) | grep 'container_name:' | awk '{print $$2}') +PHP_IMAGE := $(shell sed -n '/^[[:space:]]*phpfpm:/,/^[[:space:]]*nginx:/p' $(COMPOSE_FILE) | grep 'image:' | awk '{print $$2}') +PHP_IP := $(shell sed -n '/^[[:space:]]*phpfpm:/,/^[[:space:]]*nginx:/p' $(COMPOSE_FILE) | grep 'ipv4_address:' | awk '{print $$2}') +PHP_PORT_9000 := $(shell sed -n '/^[[:space:]]*phpfpm:/,/^[[:space:]]*nginx:/p' $(COMPOSE_FILE) | grep ':9000"' | sed 's/.*"\([0-9]*\):.*/\1/') +PHP_PORT_40001 := $(shell sed -n '/^[[:space:]]*phpfpm:/,/^[[:space:]]*nginx:/p' $(COMPOSE_FILE) | grep ':40001"' | sed 's/.*"\([0-9]*\):.*/\1/') +PHP_PORT_40002 := $(shell sed -n '/^[[:space:]]*phpfpm:/,/^[[:space:]]*nginx:/p' $(COMPOSE_FILE) | grep ':40002"' | sed 's/.*"\([0-9]*\):.*/\1/') +# PHP内部端口 +PHP_PORT_9000_IN := $(shell sed -n '/^[[:space:]]*phpfpm:/,/^[[:space:]]*nginx:/p' $(COMPOSE_FILE) | grep ':9000"' | sed 's/.*:\([0-9]*\)".*/\1/') +PHP_PORT_40001_IN := $(shell sed -n '/^[[:space:]]*phpfpm:/,/^[[:space:]]*nginx:/p' $(COMPOSE_FILE) | grep ':40001"' | sed 's/.*:\([0-9]*\)".*/\1/') +PHP_PORT_40002_IN := $(shell sed -n '/^[[:space:]]*phpfpm:/,/^[[:space:]]*nginx:/p' $(COMPOSE_FILE) | grep ':40002"' | sed 's/.*:\([0-9]*\)".*/\1/') +# PHP目录映射 +PHP_APP_LOCAL := $(shell sed -n '/^[[:space:]]*phpfpm:/,/^[[:space:]]*nginx:/p' $(COMPOSE_FILE) | grep ':/var/www$$' | sed 's/.*- *\([^:]*\):.*/\1/' | head -1) +PHP_APP_CONTAINER := /var/www +PHP_RUNTIME_LOCAL := $(shell sed -n '/^[[:space:]]*phpfpm:/,/^[[:space:]]*nginx:/p' $(COMPOSE_FILE) | grep ':/var/www/runtime' | sed 's/.*- *\([^:]*\):.*/\1/') +PHP_RUNTIME_CONTAINER := /var/www/runtime + +# Nginx 配置 +NGINX_CONTAINER := $(shell sed -n '/^[[:space:]]*nginx:/,/^networks:/p' $(COMPOSE_FILE) | grep 'container_name:' | awk '{print $$2}') +NGINX_IMAGE := $(shell sed -n '/^[[:space:]]*nginx:/,/^networks:/p' $(COMPOSE_FILE) | grep 'image:' | awk '{print $$2}') +NGINX_IP := $(shell sed -n '/^[[:space:]]*nginx:/,/^networks:/p' $(COMPOSE_FILE) | grep 'ipv4_address:' | awk '{print $$2}') +NGINX_PORT_OUT := $(shell sed -n '/^[[:space:]]*nginx:/,/^networks:/p' $(COMPOSE_FILE) | grep ':80"' | sed 's/.*"\([0-9]*\):.*/\1/') +# Nginx内部端口 +NGINX_PORT_IN := $(shell sed -n '/^[[:space:]]*nginx:/,/^networks:/p' $(COMPOSE_FILE) | grep ':80"' | sed 's/.*:\([0-9]*\)".*/\1/') +# Nginx目录映射 +NGINX_VHOST_LOCAL := $(shell sed -n '/^[[:space:]]*nginx:/,/^networks:/p' $(COMPOSE_FILE) | grep '/etc/nginx/conf.d' | sed 's/.*- *\([^:]*\):.*/\1/') +NGINX_VHOST_CONTAINER := $(shell sed -n '/^[[:space:]]*nginx:/,/^networks:/p' $(COMPOSE_FILE) | grep '/etc/nginx/conf.d' | sed 's/.*:\([^ ]*\).*/\1/') +NGINX_LOG_LOCAL := $(shell sed -n '/^[[:space:]]*nginx:/,/^networks:/p' $(COMPOSE_FILE) | grep '/etc/nginx/log' | sed 's/.*- *\([^:]*\):.*/\1/') +NGINX_LOG_CONTAINER := $(shell sed -n '/^[[:space:]]*nginx:/,/^networks:/p' $(COMPOSE_FILE) | grep '/etc/nginx/log' | sed 's/.*:\([^ ]*\).*/\1/') + +# 网络配置 +NETWORK_SUBNET := $(shell grep -A 3 'ipam:' $(COMPOSE_FILE) | grep 'subnet:' | sed 's/.*subnet: *//') + +# 帮助信息 +.PHONY: help +help: + @echo "" + @echo -e "$(GREEN)CRMEB Docker 管理脚本$(NC)" + @echo "" + @echo "用法: make [目标]" + @echo "" + @echo -e "$(YELLOW)容器管理:$(NC)" + @echo " make install 安装并启动(清理数据,首次部署)" + @echo " make start 启动容器" + @echo " make restart 重启容器" + @echo " make stop 停止容器" + @echo " make delete 删除容器和数据" + @echo " make rebuild 重新构建并启动" + @echo " make pull 拉取最新镜像" + @echo "" + @echo -e "$(YELLOW)信息查看:$(NC)" + @echo " make info 查看所有容器信息总览" + @echo " make info-mysql 查看 MySQL 详细信息" + @echo " make info-redis 查看 Redis 详细信息" + @echo " make info-php 查看 PHP 详细信息" + @echo " make info-nginx 查看 Nginx 详细信息" + @echo " make info-network 查看网络信息" + @echo " make info-quick 快速参考卡片" + @echo " make ps 查看容器状态" + @echo "" + @echo -e "$(YELLOW)日志查看:$(NC)" + @echo " make logs 查看所有日志" + @echo " make logs-php 查看 PHP 日志" + @echo " make logs-mysql 查看 MySQL 日志" + @echo " make logs-redis 查看 Redis 日志" + @echo " make logs-nginx 查看 Nginx 日志" + @echo "" + @echo -e "$(YELLOW)容器进入:$(NC)" + @echo " make exec-php 进入 PHP 容器" + @echo " make exec-mysql 进入 MySQL 容器" + @echo " make exec-redis 进入 Redis 容器" + @echo "" + @echo -e "$(YELLOW)服务管理:$(NC)" + @echo " make timer 启动定时任务" + @echo " make workerman 启动长连接服务" + @echo " make queue 启动队列监听" + @echo " make services 启动所有服务" + @echo "" + @echo -e "$(YELLOW)其他:$(NC)" + @echo " make clean 清理缓存和数据" + @echo " make init 完整初始化(首次使用)" + @echo " make help 显示帮助信息" + @echo "" + @echo "环境变量:" + @echo " COMPOSE_FILE 指定 compose 文件 (默认: docker-compose.yml)" + @echo " 示例: COMPOSE_FILE=docker-compose.build.yml make install" + @echo "" + +# 检查 docker-compose 是否可用 +check-docker: + @if ! command -v docker-compose &> /dev/null; then \ + echo -e "$(RED)错误: docker-compose 未安装$(NC)"; \ + exit 1; \ + fi + @if [ ! -f "$(COMPOSE_FILE)" ]; then \ + echo -e "$(RED)错误: 配置文件 $(COMPOSE_FILE) 不存在$(NC)"; \ + exit 1; \ + fi + +# 清理 install.lock +clean-lock: + @echo -e "$(YELLOW)清理 install.lock...$(NC)" + @if [ -f "$(PHP_APP_LOCAL)/public/install.lock" ]; then \ + rm -f $(PHP_APP_LOCAL)/public/install.lock; \ + echo "已删除 install.lock"; \ + fi + +# 清理 MySQL 数据 +clean-mysql: + @echo -e "$(YELLOW)清理 MySQL 数据...$(NC)" + @if [ -d "mysql/data" ] && [ -n "$(ls -A mysql/data 2>/dev/null)" ]; then \ + rm -rf mysql/data/*; \ + echo "已清空 MySQL 数据目录"; \ + fi + +# 清理 runtime 缓存 +clean-runtime: + @echo -e "$(YELLOW)清理 runtime 缓存...$(NC)" + @if [ -d "$(PHP_RUNTIME_LOCAL)" ] && [ -n "$(ls -A $(PHP_RUNTIME_LOCAL) 2>/dev/null)" ]; then \ + rm -rf $(PHP_RUNTIME_LOCAL)/*; \ + echo "已清空 runtime 目录"; \ + fi + +# 设置目录权限 +set-permission: + @echo -e "$(YELLOW)设置目录权限...$(NC)" + @chmod -R 777 $(PHP_RUNTIME_LOCAL) 2>/dev/null || true + @chmod -R 777 $(PHP_APP_LOCAL)/public 2>/dev/null || true + @chmod 777 $(PHP_APP_LOCAL)/.env 2>/dev/null || true + @chmod 777 $(PHP_APP_LOCAL)/.version 2>/dev/null || true + @chmod 777 $(PHP_APP_LOCAL)/.constant 2>/dev/null || true + +# 清理网络 +clean-network: + @echo -e "$(YELLOW)清理可能存在的冲突网络...$(NC)" + @for net in $$(docker network ls --format "{{.Name}}" | grep -E "(app_net|docker_app_net|crmeb_app_net)"); do \ + echo "删除网络: $$net"; \ + docker network rm "$$net" 2>/dev/null || true; \ + done + @docker network prune -f 2>/dev/null || true + +# 停止旧容器 +down: + @echo -e "$(YELLOW)停止旧容器...$(NC)" + @$(COMPOSE_COMMAND) down 2>/dev/null || true + +# ==================== 目标定义 ==================== + +# 安装并启动(清理数据,首次部署) +.PHONY: install +install: check-docker down clean-lock clean-mysql clean-runtime set-permission clean-network + @echo -e "$(YELLOW)安装并启动 Docker 环境...$(NC)" + @$(COMPOSE_COMMAND) up -d + @echo "" + @echo -e "$(GREEN)=== 安装完成 ===$(NC)" + @echo "配置文件: $(COMPOSE_FILE)" + @echo "访问地址: http://localhost:$(NGINX_PORT_OUT)" + @echo "管理端地址: http://localhost:$(NGINX_PORT_OUT)/admin" + @echo "查看日志: make logs" + +# 启动容器 +.PHONY: start +start: check-docker clean-network + @echo -e "$(YELLOW)启动容器...$(NC)" + @$(COMPOSE_COMMAND) up -d + @echo "" + @echo -e "$(GREEN)=== 启动完成 ===$(NC)" + @echo "配置文件: $(COMPOSE_FILE)" + @echo "访问地址: http://localhost:$(NGINX_PORT_OUT)" + +# 重启容器 +.PHONY: restart +restart: + @echo -e "$(YELLOW)重启容器...$(NC)" + @$(COMPOSE_COMMAND) restart + @echo "" + @echo -e "$(GREEN)=== 重启完成 ===$(NC)" + +# 停止容器 +.PHONY: stop +stop: + @echo -e "$(YELLOW)停止容器...$(NC)" + @$(COMPOSE_COMMAND) down + @echo -e "$(GREEN)=== 已停止 ===$(NC)" + +# 删除容器和数据 +.PHONY: delete +delete: + @echo -e "$(YELLOW)删除容器和数据...$(NC)" + @$(COMPOSE_COMMAND) down -v + @rm -rf $(MYSQL_DATA_LOCAL)/* 2>/dev/null || true + @rm -rf $(PHP_RUNTIME_LOCAL)/* 2>/dev/null || true + @rm -f $(PHP_APP_LOCAL)/public/install.lock 2>/dev/null || true + @echo -e "$(GREEN)=== 已删除 ===$(NC)" + +# 查看日志 +.PHONY: logs +logs: + @$(COMPOSE_COMMAND) logs -f + +# 查看容器状态 +.PHONY: ps +ps: + @$(COMPOSE_COMMAND) ps + +# 清理缓存(保留容器) +.PHONY: clean +clean: clean-lock clean-mysql clean-runtime set-permission + @echo -e "$(GREEN)=== 缓存清理完成 ===$(NC)" + @echo "注意: 容器仍在运行,如需完全删除使用 make delete" + +# 重新构建并启动 +.PHONY: rebuild +rebuild: check-docker + @echo -e "$(YELLOW)重新构建镜像...$(NC)" + @$(COMPOSE_COMMAND) build --no-cache + @$(COMPOSE_COMMAND) up -d + @echo "" + @echo -e "$(GREEN)=== 重建完成 ===$(NC)" + +# 拉取最新镜像 +.PHONY: pull +pull: + @echo -e "$(YELLOW)拉取最新镜像...$(NC)" + @$(COMPOSE_COMMAND) pull + @echo -e "$(GREEN)=== 拉取完成 ===$(NC)" + +# 进入 PHP 容器 +.PHONY: exec-php +exec-php: + @docker exec -it $(PHP_CONTAINER) /bin/bash + +# 进入 MySQL 容器 +.PHONY: exec-mysql +exec-mysql: + @docker exec -it $(MYSQL_CONTAINER) mysql -uroot -p$(MYSQL_ROOT_PWD) + +# 进入 Redis 容器 +.PHONY: exec-redis +exec-redis: + @docker exec -it $(REDIS_CONTAINER) redis-cli -a $(REDIS_PWD) + +# 启动定时任务 +.PHONY: timer +timer: + @docker exec -it $(PHP_CONTAINER) cd $(PHP_APP_CONTAINER) && php think timer start --d + +# 启动 Workerman 长连接 +.PHONY: workerman +workerman: + @docker exec -it $(PHP_CONTAINER) cd $(PHP_APP_CONTAINER) && php think workerman start --d + +# 启动队列监听 +.PHONY: queue +queue: + @docker exec -it $(PHP_CONTAINER) cd $(PHP_APP_CONTAINER) && php think queue:listen --queue + +# 启动所有服务(定时任务+Workerman+队列) +.PHONY: services +services: timer workerman queue + @echo -e "$(GREEN)=== 所有服务已启动 ===$(NC)" + +# 查看 PHP 容器日志 +.PHONY: logs-php +logs-php: + @$(COMPOSE_COMMAND) logs -f $(PHP_CONTAINER) + +# 查看 MySQL 容器日志 +.PHONY: logs-mysql +logs-mysql: + @$(COMPOSE_COMMAND) logs -f $(MYSQL_CONTAINER) + +# 查看 Redis 容器日志 +.PHONY: logs-redis +logs-redis: + @$(COMPOSE_COMMAND) logs -f $(REDIS_CONTAINER) + +# 查看 Nginx 容器日志 +.PHONY: logs-nginx +logs-nginx: + @$(COMPOSE_COMMAND) logs -f $(NGINX_CONTAINER) + +# 完整初始化(首次使用) +.PHONY: init +init: install + @echo "" + @echo -e "$(GREEN)=== 初始化完成 ===$(NC)" + @echo "请访问 http://localhost:$(NGINX_PORT_OUT) 进行系统安装" + +# ==================== 信息查看命令 ==================== + +# 查看所有容器信息 +.PHONY: info +info: + @echo "" + @echo -e "$(GREEN)╔══════════════════════════════════════════════════════════════╗$(NC)" + @echo -e "$(GREEN)║ CRMEB Docker 容器信息总览 ║$(NC)" + @echo -e "$(GREEN)╚══════════════════════════════════════════════════════════════╝$(NC)" + @echo "" + @echo -e "$(CYAN)配置文件: $(COMPOSE_FILE)$(NC)" + @echo "" + @echo -e "$(YELLOW)【访问地址】$(NC)" + @echo " 前端地址: http://localhost:$(NGINX_PORT_OUT)/" + @echo " 后台管理: http://localhost:$(NGINX_PORT_OUT)/admin" + @echo " 安装向导: http://localhost:$(NGINX_PORT_OUT)/install (首次访问)" + @echo "" + @echo -e "$(YELLOW)【MySQL 数据库】$(NC)" + @echo " 容器名称: $(MYSQL_CONTAINER)" + @echo " 镜像: $(MYSQL_IMAGE)" + @echo " 内部地址: $(MYSQL_CONTAINER):$(MYSQL_PORT_IN)" + @echo " 外部地址: localhost:$(MYSQL_PORT_OUT)" + @echo " Root密码: $(MYSQL_ROOT_PWD)" + @echo " 业务用户: $(MYSQL_USER)" + @echo " 业务密码: $(MYSQL_PWD)" + @echo " 数据库名: $(MYSQL_DB)" + @echo " 内部IP: $(MYSQL_IP)" + @echo " 数据目录: $(MYSQL_DATA_LOCAL)" + @echo "" + @echo -e "$(YELLOW)【Redis 缓存】$(NC)" + @echo " 容器名称: $(REDIS_CONTAINER)" + @echo " 镜像: $(REDIS_IMAGE)" + @echo " 内部地址: $(REDIS_CONTAINER):$(REDIS_PORT_IN)" + @echo " 外部地址: localhost:$(REDIS_PORT_OUT)" + @echo " 密码: $(REDIS_PWD)" + @echo " 内部IP: $(REDIS_IP)" + @echo " 数据库: 0" + @echo "" + @echo -e "$(YELLOW)【PHP 应用】$(NC)" + @echo " 容器名称: $(PHP_CONTAINER)" + @echo " 镜像: $(PHP_IMAGE)" + @echo " 内部IP: $(PHP_IP)" + @echo " 应用目录: $(PHP_APP_CONTAINER)" + @echo " 端口映射: $(PHP_PORT_9000):$(PHP_PORT_9000_IN), $(PHP_PORT_40001):$(PHP_PORT_40001_IN), $(PHP_PORT_40002):$(PHP_PORT_40002_IN)" + @echo "" + @echo -e "$(YELLOW)【Nginx 服务】$(NC)" + @echo " 容器名称: $(NGINX_CONTAINER)" + @echo " 镜像: $(NGINX_IMAGE)" + @echo " 外部端口: $(NGINX_PORT_OUT)" + @echo " 内部端口: $(NGINX_PORT_IN)" + @echo " 内部IP: $(NGINX_IP)" + @echo " 配置文件: $(NGINX_VHOST_LOCAL)" + @echo " 日志目录: $(NGINX_LOG_LOCAL)" + @echo "" + @echo -e "$(YELLOW)【网络配置】$(NC)" + @echo " 网络名称: app_net" + @echo " 网段: $(NETWORK_SUBNET)" + @echo "" + @echo -e "$(YELLOW)【常用命令】$(NC)" + @echo " 查看容器状态: make ps" + @echo " 查看日志: make logs" + @echo " 进入PHP容器: make exec-php" + @echo " 进入MySQL: make exec-mysql" + @echo " 启动服务: make services" + @echo "" + +# 查看 MySQL 详细信息 +.PHONY: info-mysql +info-mysql: + @echo "" + @echo -e "$(GREEN)╔══════════════════════════════════════════╗$(NC)" + @echo -e "$(GREEN)║ MySQL 数据库详细信息 ║$(NC)" + @echo -e "$(GREEN)╚══════════════════════════════════════════╝$(NC)" + @echo "" + @echo -e "$(CYAN)配置文件: $(COMPOSE_FILE)$(NC)" + @echo "" + @echo -e "$(YELLOW)【连接信息】$(NC)" + @echo " 容器名称: $(MYSQL_CONTAINER)" + @echo " 镜像版本: $(MYSQL_IMAGE)" + @echo " 内部地址: $(MYSQL_CONTAINER)" + @echo " 内部端口: $(MYSQL_PORT_IN)" + @echo " 外部端口: $(MYSQL_PORT_OUT)" + @echo " 内部IP: $(MYSQL_IP)" + @echo "" + @echo -e "$(YELLOW)【账号信息】$(NC)" + @echo " Root用户: root" + @echo " Root密码: $(MYSQL_ROOT_PWD)" + @echo " 业务用户: $(MYSQL_USER)" + @echo " 业务密码: $(MYSQL_PWD)" + @echo " 数据库名: $(MYSQL_DB)" + @echo "" + @echo -e "$(YELLOW)【数据存储】$(NC)" + @echo " 本地目录: $(MYSQL_DATA_LOCAL)" + @echo " 容器目录: $(MYSQL_DATA_CONTAINER)" + @echo "" + @echo -e "$(YELLOW)【日志目录】$(NC)" + @echo " 本地目录: $(MYSQL_LOG_LOCAL)" + @echo " 容器目录: $(MYSQL_LOG_CONTAINER)" + @echo "" + @echo -e "$(YELLOW)【连接命令】$(NC)" + @echo " 本地连接: mysql -h 127.0.0.1 -P $(MYSQL_PORT_OUT) -u root -p$(MYSQL_ROOT_PWD)" + @echo " 容器内连接: docker exec -it $(MYSQL_CONTAINER) mysql -uroot -p$(MYSQL_ROOT_PWD)" + @echo " 或使用make: make exec-mysql" + @echo "" + @echo -e "$(YELLOW)【配置文件】$(NC)" + @echo " 本地配置: $(or $(MYSQL_CONF_LOCAL),未映射)" + @echo " 容器配置: $(MYSQL_CONF_CONTAINER)" + @echo "" + +# 查看 Redis 详细信息 +.PHONY: info-redis +info-redis: + @echo "" + @echo -e "$(GREEN)╔══════════════════════════════════════════╗$(NC)" + @echo -e "$(GREEN)║ Redis 缓存详细信息 ║$(NC)" + @echo -e "$(GREEN)╚══════════════════════════════════════════╝$(NC)" + @echo "" + @echo -e "$(CYAN)配置文件: $(COMPOSE_FILE)$(NC)" + @echo "" + @echo -e "$(YELLOW)【连接信息】$(NC)" + @echo " 容器名称: $(REDIS_CONTAINER)" + @echo " 镜像版本: $(REDIS_IMAGE)" + @echo " 内部地址: $(REDIS_CONTAINER)" + @echo " 内部端口: $(REDIS_PORT_IN)" + @echo " 外部端口: $(REDIS_PORT_OUT)" + @echo " 内部IP: $(REDIS_IP)" + @echo "" + @echo -e "$(YELLOW)【认证信息】$(NC)" + @echo " 密码: $(REDIS_PWD)" + @echo " 默认数据库: 0" + @echo " 最大数据库: 15" + @echo "" + @echo -e "$(YELLOW)【连接命令】$(NC)" + @echo " 本地连接: redis-cli -h 127.0.0.1 -p $(REDIS_PORT_OUT) -a $(REDIS_PWD)" + @echo " 容器内连接: docker exec -it $(REDIS_CONTAINER) redis-cli -a $(REDIS_PWD)" + @echo " 或使用make: make exec-redis" + @echo "" + @echo -e "$(YELLOW)【配置文件】$(NC)" + @echo " 本地配置: $(or $(REDIS_CONF_LOCAL),未映射)" + @echo " 容器配置: $(REDIS_CONF_CONTAINER)" + @echo "" + +# 查看 PHP 详细信息 +.PHONY: info-php +info-php: + @echo "" + @echo -e "$(GREEN)╔══════════════════════════════════════════╗$(NC)" + @echo -e "$(GREEN)║ PHP 应用详细信息 ║$(NC)" + @echo -e "$(GREEN)╚══════════════════════════════════════════╝$(NC)" + @echo "" + @echo -e "$(CYAN)配置文件: $(COMPOSE_FILE)$(NC)" + @echo "" + @echo -e "$(YELLOW)【容器信息】$(NC)" + @echo " 容器名称: $(PHP_CONTAINER)" + @echo " 镜像版本: $(PHP_IMAGE)" + @echo " 内部IP: $(PHP_IP)" + @echo "" + @echo -e "$(YELLOW)【端口映射】$(NC)" + @echo " PHP-FPM: $(PHP_PORT_9000):$(PHP_PORT_9000_IN)" + @echo " 长连接1: $(PHP_PORT_40001):$(PHP_PORT_40001_IN)" + @echo " 长连接2: $(PHP_PORT_40002):$(PHP_PORT_40002_IN)" + @echo "" + @echo -e "$(YELLOW)【目录映射】$(NC)" + @echo " 应用目录: $(PHP_APP_LOCAL) -> $(PHP_APP_CONTAINER)" + @echo " 运行时目录: $(PHP_RUNTIME_LOCAL) -> $(PHP_RUNTIME_CONTAINER)" + @echo "" + @echo -e "$(YELLOW)【常用命令】$(NC)" + @echo " 进入容器: make exec-php" + @echo " 查看日志: make logs-php" + @echo " 启动定时任务: make timer" + @echo " 启动长连接: make workerman" + @echo " 启动队列: make queue" + @echo "" + @echo -e "$(YELLOW)【ThinkPHP 命令】$(NC)" + @echo " 清除缓存: docker exec $(PHP_CONTAINER) php $(PHP_APP_CONTAINER)/think clear" + @echo " 查看路由: docker exec $(PHP_CONTAINER) php $(PHP_APP_CONTAINER)/think route:list" + @echo " 数据库迁移: docker exec $(PHP_CONTAINER) php $(PHP_APP_CONTAINER)/think migrate:run" + @echo "" + +# 查看 Nginx 详细信息 +.PHONY: info-nginx +info-nginx: + @echo "" + @echo -e "$(GREEN)╔══════════════════════════════════════════╗$(NC)" + @echo -e "$(GREEN)║ Nginx 服务详细信息 ║$(NC)" + @echo -e "$(GREEN)╚══════════════════════════════════════════╝$(NC)" + @echo "" + @echo -e "$(CYAN)配置文件: $(COMPOSE_FILE)$(NC)" + @echo "" + @echo -e "$(YELLOW)【容器信息】$(NC)" + @echo " 容器名称: $(NGINX_CONTAINER)" + @echo " 镜像版本: $(NGINX_IMAGE)" + @echo " 内部IP: $(NGINX_IP)" + @echo "" + @echo -e "$(YELLOW)【端口映射】$(NC)" + @echo " HTTP: $(NGINX_PORT_OUT):$(NGINX_PORT_IN)" + @echo "" + @echo -e "$(YELLOW)【访问地址】$(NC)" + @echo " 前端首页: http://localhost:$(NGINX_PORT_OUT)/" + @echo " 后台管理: http://localhost:$(NGINX_PORT_OUT)/admin" + @echo " API接口: http://localhost:$(NGINX_PORT_OUT)/api/" + @echo " 安装页面: http://localhost:$(NGINX_PORT_OUT)/install" + @echo "" + @echo -e "$(YELLOW)【配置文件】$(NC)" + @echo " 本地配置: $(NGINX_VHOST_LOCAL)" + @echo " 容器配置: $(NGINX_VHOST_CONTAINER)" + @echo "" + @echo -e "$(YELLOW)【日志文件】$(NC)" + @echo " 本地目录: $(NGINX_LOG_LOCAL)" + @echo " 容器目录: $(NGINX_LOG_CONTAINER)" + @echo " 访问日志: $(NGINX_LOG_LOCAL)/access.log" + @echo " 错误日志: $(NGINX_LOG_LOCAL)/error.log" + @echo "" + @echo -e "$(YELLOW)【常用命令】$(NC)" + @echo " 查看日志: make logs-nginx" + @echo " 重载配置: docker exec $(NGINX_CONTAINER) nginx -s reload" + @echo " 测试配置: docker exec $(NGINX_CONTAINER) nginx -t" + @echo "" + +# 查看网络信息 +.PHONY: info-network +info-network: + @echo "" + @echo -e "$(GREEN)╔══════════════════════════════════════════╗$(NC)" + @echo -e "$(GREEN)║ Docker 网络信息 ║$(NC)" + @echo -e "$(GREEN)╚══════════════════════════════════════════╝$(NC)" + @echo "" + @echo -e "$(CYAN)配置文件: $(COMPOSE_FILE)$(NC)" + @echo "" + @echo -e "$(YELLOW)【网络配置】$(NC)" + @echo " 网络名称: app_net" + @echo " 网段: $(NETWORK_SUBNET)" + @echo " 网关: $(shell echo $(NETWORK_SUBNET) | sed 's/0\/24/1/')" + @echo "" + @echo -e "$(YELLOW)【容器IP地址】$(NC)" + @echo " MySQL: $(MYSQL_IP)" + @echo " Redis: $(REDIS_IP)" + @echo " PHP: $(PHP_IP)" + @echo " Nginx: $(NGINX_IP)" + @echo "" + @echo -e "$(YELLOW)【容器间通信】$(NC)" + @echo " PHP -> MySQL: $(MYSQL_CONTAINER):$(MYSQL_PORT_IN)" + @echo " PHP -> Redis: $(REDIS_CONTAINER):$(REDIS_PORT_IN)" + @echo " Nginx -> PHP: $(PHP_CONTAINER):$(PHP_PORT_9000_IN)" + @echo "" + @echo -e "$(YELLOW)【常用命令】$(NC)" + @echo " 查看网络: docker network ls" + @echo " 网络详情: docker network inspect app_net" + @echo " 清理网络: make clean-network" + @echo "" + +# 查看快速参考 +.PHONY: info-quick +info-quick: + @echo "" + @echo -e "$(GREEN)╔══════════════════════════════════════════╗$(NC)" + @echo -e "$(GREEN)║ 快速参考卡片 ║$(NC)" + @echo -e "$(GREEN)╚══════════════════════════════════════════╝$(NC)" + @echo "" + @echo -e "$(CYAN)配置文件: $(COMPOSE_FILE)$(NC)" + @echo "" + @echo -e "$(YELLOW)【一键安装】$(NC)" + @echo " make install # 首次部署,自动清理数据" + @echo "" + @echo -e "$(YELLOW)【日常管理】$(NC)" + @echo " make start # 启动" + @echo " make stop # 停止" + @echo " make restart # 重启" + @echo " make logs # 查看日志" + @echo "" + @echo -e "$(YELLOW)【数据库连接】$(NC)" + @echo " Host: $(MYSQL_CONTAINER) (容器内) / localhost:$(MYSQL_PORT_OUT) (外部)" + @echo " User: root / Password: $(MYSQL_ROOT_PWD) / DB: $(MYSQL_DB)" + @echo "" + @echo -e "$(YELLOW)【Redis连接】$(NC)" + @echo " Host: $(REDIS_CONTAINER) (容器内) / localhost:$(REDIS_PORT_OUT) (外部)" + @echo " Password: $(REDIS_PWD)" + @echo "" + @echo -e "$(YELLOW)【访问地址】$(NC)" + @echo " 前端: http://localhost:$(NGINX_PORT_OUT)/" + @echo " 后台: http://localhost:$(NGINX_PORT_OUT)/admin" + @echo "" + @echo -e "$(YELLOW)【故障排查】$(NC)" + @echo " make ps # 查看容器状态" + @echo " make logs-php # PHP日志" + @echo " make logs-nginx # Nginx日志" + @echo " make info # 完整信息" + @echo "" diff --git a/help/docker/README.md b/help/docker/README.md index 11faa3f57..d3c2f9258 100644 --- a/help/docker/README.md +++ b/help/docker/README.md @@ -30,7 +30,170 @@ https://www.runoob.com/docker/docker-compose.html 建议去下载最新开源代码 https://gitee.com/ZhongBangKeJi/CRMEB 程序放到docker 同级目录下 -## 3、启动项目 +## 3、启动项目(推荐使用 run.sh 脚本) + +推荐使用项目提供的 `run.sh` 管理脚本进行启动,它提供了交互式菜单和命令行两种方式: + +### 3.1 方式一:交互式菜单(推荐) + +```bash +cd help/docker +chmod +x run.sh +./run.sh +``` + +脚本会显示交互式菜单: +``` + 1、安装并启动 + 2、启动容器 + 3、重启容器 + 4、停止容器 + 5、删除容器和数据 + 6、查看日志 + 7、查看帮助 + 8、退出 +``` + +### 3.2 方式二:命令行参数 + +```bash +# 安装并启动(清理旧数据,首次部署) +./run.sh install + +# 启动容器 +./run.sh start + +# 重启容器 +./run.sh restart + +# 停止容器 +./run.sh stop + +# 删除容器和数据 +./run.sh delete + +# 查看日志 +./run.sh logs + +# 查看帮助 +./run.sh -h +``` + +### 3.3 环境变量 + +可以通过 `COMPOSE_FILE` 环境变量指定不同的 compose 文件: + +```bash +# 使用默认配置 +./run.sh install + +# 使用其他配置文件 +COMPOSE_FILE=docker-compose.build.yml ./run.sh install +``` + +### 3.4 run.sh 脚本功能说明 + +| 功能 | 说明 | +|------|------| +| install | 停止旧容器、清理数据(MySQL、runtime)、设置权限、启动新容器 | +| start | 启动容器(保留现有数据) | +| restart | 重启容器 | +| stop | 停止容器 | +| delete | 删除容器和数据(完全清理) | +| logs | 实时查看日志 | + +> **提示**:`install` 命令会执行以下操作: +> - 删除 `install.lock` 文件(允许重新安装) +> - 清空 MySQL 数据目录 +> - 清空 runtime 缓存目录 +> - 设置正确的目录权限 + +### 3.5 方式三:使用 Makefile(推荐开发者) + +项目提供了 `Makefile` 文件,支持更丰富的管理命令: + +```bash +cd help/docker + +# 查看所有可用命令 +make help + +# 安装并启动(首次部署) +make install + +# 启动容器 +make start + +# 停止容器 +make stop + +# 重启容器 +make restart + +# 查看日志 +make logs + +# 查看容器状态 +make ps +``` + +#### Makefile 常用命令 + +| 命令 | 说明 | +|------|------| +| `make install` | 安装并启动(清理数据,首次部署) | +| `make start` | 启动容器 | +| `make stop` | 停止容器 | +| `make restart` | 重启容器 | +| `make delete` | 删除容器和数据 | +| `make logs` | 查看所有日志 | +| `make ps` | 查看容器状态 | +| `make clean` | 清理缓存(保留容器) | +| `make rebuild` | 重新构建镜像并启动 | + +#### 信息查看命令 + +| 命令 | 说明 | +|------|------| +| `make info` | 查看所有容器信息总览(地址、端口、账号等) | +| `make info-mysql` | 查看 MySQL 详细信息(连接地址、账号密码) | +| `make info-redis` | 查看 Redis 详细信息(连接地址、密码) | +| `make info-php` | 查看 PHP 详细信息(目录映射、端口) | +| `make info-nginx` | 查看 Nginx 详细信息(访问地址、配置文件) | +| `make info-network` | 查看网络信息(容器IP、通信方式) | +| `make info-quick` | 快速参考卡片(常用命令速查) | + +#### 进阶命令 + +| 命令 | 说明 | +|------|------| +| `make exec-php` | 进入 PHP 容器 | +| `make exec-mysql` | 进入 MySQL 容器 | +| `make exec-redis` | 进入 Redis 容器 | +| `make timer` | 启动定时任务 | +| `make workerman` | 启动长连接服务 | +| `make queue` | 启动队列监听 | +| `make services` | 启动所有服务(定时任务+长连接+队列) | +| `make logs-php` | 查看 PHP 日志 | +| `make logs-mysql` | 查看 MySQL 日志 | +| `make logs-redis` | 查看 Redis 日志 | +| `make logs-nginx` | 查看 Nginx 日志 | +| `make init` | 完整初始化(首次使用) | + +#### 指定配置文件 + +```bash +# 使用默认配置 +make install + +# 使用其他配置文件 +COMPOSE_FILE=docker-compose.build.yml make install +``` + +### 3.6 传统方式(直接使用 docker-compose) + +如果不使用脚本,也可以直接使用 docker-compose 命令: + ``` 进入docker-compose目录 cd /docker diff --git a/help/docker/docker-compose.yml b/help/docker/docker-compose.yml index e6caaf3c5..7c3fb18f0 100644 --- a/help/docker/docker-compose.yml +++ b/help/docker/docker-compose.yml @@ -47,11 +47,10 @@ services: REDIS_PASSWORD: 123456 APP_DEBUG: true DEFAULT_TIMEZONE: Asia/Shanghai - # ports: - # - "9000:9000" - # - "40001:40001" - # - "40002:40002" - # - "40003:40003" + ports: + - "9000:9000" + - "40001:40001" + - "40002:40002" working_dir: /var/www volumes: - ../../crmeb:/var/www diff --git a/help/docker/run.sh b/help/docker/run.sh new file mode 100644 index 000000000..4b90e2428 --- /dev/null +++ b/help/docker/run.sh @@ -0,0 +1,430 @@ +#!/bin/bash + +# CRMEB Docker 开发环境管理脚本 + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +cd "$SCRIPT_DIR" + +# 配置文件(可自定义,默认 docker-compose.yml) +COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}" + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +CYAN='\033[0;36m' +NC='\033[0m' + +# ==================== 从 docker-compose.yml 读取配置 ==================== + +# 提取服务配置的通用函数 +get_config() { + local pattern="$1" + local section_start="$2" + local section_end="$3" + sed -n "/^[[:space:]]*${section_start}:/,/^[[:space:]]*${section_end}:/p" "$COMPOSE_FILE" | grep "$pattern" | head -1 +} + +# MySQL 配置 +MYSQL_CONTAINER=$(get_config 'container_name:' 'mysql' 'redis' | awk '{print $2}') +MYSQL_PORT_OUT=$(get_config ':3306"' 'mysql' 'redis' | sed 's/.*"\([0-9]*\):.*/\1/') +MYSQL_PORT_IN=$(get_config ':3306"' 'mysql' 'redis' | sed 's/.*:\([0-9]*\)".*/\1/') +MYSQL_ROOT_PWD=$(get_config 'MYSQL_ROOT_PASSWORD:' 'mysql' 'redis' | awk '{print $2}') +MYSQL_USER=$(get_config 'MYSQL_USER:' 'mysql' 'redis' | awk '{print $2}') +MYSQL_PWD=$(get_config 'MYSQL_PASSWORD:' 'mysql' 'redis' | awk '{print $2}') +MYSQL_DB=$(get_config 'MYSQL_DATABASE:' 'mysql' 'redis' | awk '{print $2}') +MYSQL_IP=$(get_config 'ipv4_address:' 'mysql' 'redis' | awk '{print $2}') +MYSQL_DATA_LOCAL=$(get_config '/var/lib/mysql' 'mysql' 'redis' | sed 's/.*- *\([^:]*\):.*/\1/') +MYSQL_LOG_LOCAL=$(get_config '/var/log/mysql' 'mysql' 'redis' | sed 's/.*- *\([^:]*\):.*/\1/') + +# Redis 配置 +REDIS_CONTAINER=$(get_config 'container_name:' 'redis' 'phpfpm' | awk '{print $2}') +REDIS_PORT_OUT=$(get_config ':6379"' 'redis' 'phpfpm' | sed 's/.*"\([0-9]*\):.*/\1/') +REDIS_PORT_IN=$(get_config ':6379"' 'redis' 'phpfpm' | sed 's/.*:\([0-9]*\)".*/\1/') +REDIS_PWD=$(get_config 'REDIS_PASSWORD:' 'redis' 'phpfpm' | awk '{print $2}') +REDIS_IP=$(get_config 'ipv4_address:' 'redis' 'phpfpm' | awk '{print $2}') + +# PHP 配置 +PHP_CONTAINER=$(get_config 'container_name:' 'phpfpm' 'nginx' | awk '{print $2}') +PHP_IP=$(get_config 'ipv4_address:' 'phpfpm' 'nginx' | awk '{print $2}') +PHP_PORT_9000=$(get_config ':9000"' 'phpfpm' 'nginx' | sed 's/.*"\([0-9]*\):.*/\1/') +PHP_PORT_9000_IN=$(get_config ':9000"' 'phpfpm' 'nginx' | sed 's/.*:\([0-9]*\)".*/\1/') +PHP_APP_LOCAL=$(get_config ':/var/www$' 'phpfpm' 'nginx' | sed 's/.*- *\([^:]*\):.*/\1/') +PHP_RUNTIME_LOCAL=$(get_config ':/var/www/runtime' 'phpfpm' 'nginx' | sed 's/.*- *\([^:]*\):.*/\1/') + +# Nginx 配置 +NGINX_CONTAINER=$(get_config 'container_name:' 'nginx' '^networks' | awk '{print $2}') +NGINX_PORT_OUT=$(get_config ':80"' 'nginx' '^networks' | sed 's/.*"\([0-9]*\):.*/\1/') +NGINX_PORT_IN=$(get_config ':80"' 'nginx' '^networks' | sed 's/.*:\([0-9]*\)".*/\1/') +NGINX_IP=$(get_config 'ipv4_address:' 'nginx' '^networks' | awk '{print $2}') +NGINX_VHOST_LOCAL=$(get_config '/etc/nginx/conf.d' 'nginx' '^networks' | sed 's/.*- *\([^:]*\):.*/\1/') +NGINX_LOG_LOCAL=$(get_config '/etc/nginx/log' 'nginx' '^networks' | sed 's/.*- *\([^:]*\):.*/\1/') + +# 网络配置 +NETWORK_SUBNET=$(grep -A 3 'ipam:' "$COMPOSE_FILE" | grep 'subnet:' | sed 's/.*subnet: *//') + +# ==================== 帮助信息 ==================== + +show_help() { + echo -e "${GREEN}CRMEB Docker 管理脚本${NC}" + echo "" + echo "用法: $0 [选项]" + echo "" + echo -e "${YELLOW}容器管理:${NC}" + echo " install 安装并启动(清理数据,首次部署)" + echo " start 启动容器" + echo " restart 重启容器" + echo " stop 停止容器" + echo " delete 删除容器和数据" + echo " logs 查看日志" + echo "" + echo -e "${YELLOW}信息查看:${NC}" + echo " info 查看所有容器信息" + echo " info-db 查看MySQL连接信息" + echo " info-redis查看Redis连接信息" + echo " ps 查看容器状态" + echo "" + echo -e "${YELLOW}其他:${NC}" + echo " -h, --help 显示帮助" + echo "" + echo "环境变量:" + echo " COMPOSE_FILE 指定 compose 文件 (默认: docker-compose.yml)" + echo "" + echo "示例:" + echo " $0 install # 使用默认配置" + echo " COMPOSE_FILE=docker-compose.build.yml $0 install # 使用其他配置" + echo " $0 start # 启动服务" + echo " $0 info # 查看容器信息" +} + +# ==================== 检查函数 ==================== + +check_docker() { + if ! command -v docker-compose &> /dev/null; then + echo -e "${RED}错误: docker-compose 未安装${NC}" + exit 1 + fi + if [ ! -f "$COMPOSE_FILE" ]; then + echo -e "${RED}错误: 配置文件 $COMPOSE_FILE 不存在${NC}" + exit 1 + fi +} + +# ==================== 清理函数 ==================== + +# 清理数据 +cleanup() { + echo -e "${YELLOW}=== 清理旧数据 ===${NC}" + + # 删除 install.lock 文件 + if [ -n "$PHP_APP_LOCAL" ] && [ -f "$PHP_APP_LOCAL/public/install.lock" ]; then + echo "删除 install.lock..." + rm -f "$PHP_APP_LOCAL/public/install.lock" + fi + + # 删除 MySQL 数据目录内容 + if [ -n "$MYSQL_DATA_LOCAL" ] && [ -d "$MYSQL_DATA_LOCAL" ] && [ -n "$(ls -A "$MYSQL_DATA_LOCAL" 2>/dev/null)" ]; then + echo "删除 MySQL 数据..." + rm -rf "$MYSQL_DATA_LOCAL"/* + fi + + # 删除 runtime 目录内容 + if [ -n "$PHP_RUNTIME_LOCAL" ] && [ -d "$PHP_RUNTIME_LOCAL" ] && [ -n "$(ls -A "$PHP_RUNTIME_LOCAL" 2>/dev/null)" ]; then + echo "删除 runtime 缓存..." + rm -rf "$PHP_RUNTIME_LOCAL"/* + fi + + # 设置目录权限为 777 + echo "设置目录权限..." + [ -n "$PHP_RUNTIME_LOCAL" ] && chmod -R 777 "$PHP_RUNTIME_LOCAL" 2>/dev/null + [ -n "$PHP_APP_LOCAL" ] && chmod -R 777 "$PHP_APP_LOCAL/public" 2>/dev/null + [ -n "$PHP_APP_LOCAL" ] && chmod 777 "$PHP_APP_LOCAL/.env" 2>/dev/null + [ -n "$PHP_APP_LOCAL" ] && chmod 777 "$PHP_APP_LOCAL/.version" 2>/dev/null + [ -n "$PHP_APP_LOCAL" ] && chmod 777 "$PHP_APP_LOCAL/.constant" 2>/dev/null +} + +# 清理网络 +cleanup_network() { + echo "清理可能存在的冲突网络..." + + # 删除可能冲突的网络(docker-compose 默认使用目录名_app_net) + for net in $(docker network ls --format "{{.Name}}" | grep -E "(app_net|docker_app_net|crmeb_app_net)"); do + echo "删除网络: $net" + docker network rm "$net" 2>/dev/null + done + + # 清理未使用的网络 + docker network prune -f 2>/dev/null +} + +# ==================== 操作函数 ==================== + +# 安装(清理数据并启动) +do_install() { + check_docker + + echo -e "${YELLOW}=== 停止旧容器 ===${NC}" + docker-compose -f "$COMPOSE_FILE" down 2>/dev/null + + cleanup + + # 清理网络 + cleanup_network + + echo -e "${YELLOW}=== 安装并启动 Docker 环境 ===${NC}" + docker-compose -f "$COMPOSE_FILE" up -d + + echo "" + echo -e "${GREEN}=== 安装完成 ===${NC}" + echo "配置文件: $COMPOSE_FILE" + echo "访问地址: http://localhost:${NGINX_PORT_OUT}" + echo "管理端: http://localhost:${NGINX_PORT_OUT}/admin" + echo "查看日志: $0 logs" +} + +# 启动 +do_start() { + check_docker + cleanup_network + echo -e "${YELLOW}=== 启动容器 ===${NC}" + docker-compose -f "$COMPOSE_FILE" up -d + echo "" + echo -e "${GREEN}=== 启动完成 ===${NC}" + echo "配置文件: $COMPOSE_FILE" + echo "访问地址: http://localhost:${NGINX_PORT_OUT}" +} + +# 重启 +do_restart() { + check_docker + echo -e "${YELLOW}=== 重启容器 ===${NC}" + docker-compose -f "$COMPOSE_FILE" restart + echo "" + echo -e "${GREEN}=== 重启完成 ===${NC}" +} + +# 停止 +do_stop() { + check_docker + echo -e "${YELLOW}=== 停止容器 ===${NC}" + docker-compose -f "$COMPOSE_FILE" down + echo -e "${GREEN}=== 已停止 ===${NC}" +} + +# 删除 +do_delete() { + check_docker + echo -e "${YELLOW}=== 删除容器和数据 ===${NC}" + docker-compose -f "$COMPOSE_FILE" down -v + [ -n "$MYSQL_DATA_LOCAL" ] && rm -rf "$MYSQL_DATA_LOCAL"/* 2>/dev/null + [ -n "$PHP_RUNTIME_LOCAL" ] && rm -rf "$PHP_RUNTIME_LOCAL"/* 2>/dev/null + [ -n "$PHP_APP_LOCAL" ] && rm -f "$PHP_APP_LOCAL/public/install.lock" 2>/dev/null + echo -e "${GREEN}=== 已删除 ===${NC}" +} + +# 查看日志 +do_logs() { + check_docker + docker-compose -f "$COMPOSE_FILE" logs -f +} + +# 查看容器状态 +do_ps() { + check_docker + docker-compose -f "$COMPOSE_FILE" ps +} + +# ==================== 信息查看函数 ==================== + +# 查看所有容器信息 +do_info() { + check_docker + echo "" + echo -e "${GREEN}╔══════════════════════════════════════════════════════════════╗${NC}" + echo -e "${GREEN}║ CRMEB Docker 容器信息总览 ║${NC}" + echo -e "${GREEN}╚══════════════════════════════════════════════════════════════╝${NC}" + echo "" + echo -e "${CYAN}配置文件: $COMPOSE_FILE${NC}" + echo "" + echo -e "${YELLOW}【访问地址】${NC}" + echo " 前端地址: http://localhost:${NGINX_PORT_OUT}/" + echo " 后台管理: http://localhost:${NGINX_PORT_OUT}/admin" + echo " 安装向导: http://localhost:${NGINX_PORT_OUT}/install (首次访问)" + echo "" + echo -e "${YELLOW}【MySQL 数据库】${NC}" + echo " 容器名称: ${MYSQL_CONTAINER}" + echo " 内部地址: ${MYSQL_CONTAINER}:${MYSQL_PORT_IN}" + echo " 外部地址: localhost:${MYSQL_PORT_OUT}" + echo " Root密码: ${MYSQL_ROOT_PWD}" + echo " 业务用户: ${MYSQL_USER}" + echo " 业务密码: ${MYSQL_PWD}" + echo " 数据库名: ${MYSQL_DB}" + echo " 内部IP: ${MYSQL_IP}" + echo " 数据目录: ${MYSQL_DATA_LOCAL}" + echo "" + echo -e "${YELLOW}【Redis 缓存】${NC}" + echo " 容器名称: ${REDIS_CONTAINER}" + echo " 内部地址: ${REDIS_CONTAINER}:${REDIS_PORT_IN}" + echo " 外部地址: localhost:${REDIS_PORT_OUT}" + echo " 密码: ${REDIS_PWD}" + echo " 内部IP: ${REDIS_IP}" + echo "" + echo -e "${YELLOW}【PHP 应用】${NC}" + echo " 容器名称: ${PHP_CONTAINER}" + echo " 应用目录: ${PHP_APP_LOCAL}" + echo " 内部IP: ${PHP_IP}" + echo "" + echo -e "${YELLOW}【Nginx 服务】${NC}" + echo " 容器名称: ${NGINX_CONTAINER}" + echo " 外部端口: ${NGINX_PORT_OUT}" + echo " 内部IP: ${NGINX_IP}" + echo " 配置文件: ${NGINX_VHOST_LOCAL}" + echo " 日志目录: ${NGINX_LOG_LOCAL}" + echo "" + echo -e "${YELLOW}【网络配置】${NC}" + echo " 网络名称: app_net" + echo " 网段: ${NETWORK_SUBNET}" + echo "" + echo -e "${YELLOW}【常用命令】${NC}" + echo " 查看容器状态: $0 ps" + echo " 查看日志: $0 logs" + echo " 进入PHP容器: docker exec -it ${PHP_CONTAINER} /bin/bash" + echo " 进入MySQL: docker exec -it ${MYSQL_CONTAINER} mysql -uroot -p${MYSQL_ROOT_PWD}" + echo "" +} + +# 查看MySQL连接信息 +do_info_db() { + check_docker + echo "" + echo -e "${GREEN}╔══════════════════════════════════════════╗${NC}" + echo -e "${GREEN}║ MySQL 数据库详细信息 ║${NC}" + echo -e "${GREEN}╚══════════════════════════════════════════╝${NC}" + echo "" + echo -e "${CYAN}配置文件: $COMPOSE_FILE${NC}" + echo "" + echo -e "${YELLOW}【连接信息】${NC}" + echo " 容器名称: ${MYSQL_CONTAINER}" + echo " 内部端口: ${MYSQL_PORT_IN}" + echo " 外部端口: ${MYSQL_PORT_OUT}" + echo " 内部IP: ${MYSQL_IP}" + echo "" + echo -e "${YELLOW}【账号信息】${NC}" + echo " Root用户: root" + echo " Root密码: ${MYSQL_ROOT_PWD}" + echo " 业务用户: ${MYSQL_USER}" + echo " 业务密码: ${MYSQL_PWD}" + echo " 数据库名: ${MYSQL_DB}" + echo "" + echo -e "${YELLOW}【数据存储】${NC}" + echo " 本地目录: ${MYSQL_DATA_LOCAL}" + echo " 日志目录: ${MYSQL_LOG_LOCAL}" + echo "" + echo -e "${YELLOW}【连接命令】${NC}" + echo " 本地连接: mysql -h 127.0.0.1 -P ${MYSQL_PORT_OUT} -u root -p${MYSQL_ROOT_PWD}" + echo " 容器内连接: docker exec -it ${MYSQL_CONTAINER} mysql -uroot -p${MYSQL_ROOT_PWD}" + echo "" +} + +# 查看Redis连接信息 +do_info_redis() { + check_docker + echo "" + echo -e "${GREEN}╔══════════════════════════════════════════╗${NC}" + echo -e "${GREEN}║ Redis 缓存详细信息 ║${NC}" + echo -e "${GREEN}╚══════════════════════════════════════════╝${NC}" + echo "" + echo -e "${CYAN}配置文件: $COMPOSE_FILE${NC}" + echo "" + echo -e "${YELLOW}【连接信息】${NC}" + echo " 容器名称: ${REDIS_CONTAINER}" + echo " 内部端口: ${REDIS_PORT_IN}" + echo " 外部端口: ${REDIS_PORT_OUT}" + echo " 内部IP: ${REDIS_IP}" + echo "" + echo -e "${YELLOW}【认证信息】${NC}" + echo " 密码: ${REDIS_PWD}" + echo "" + echo -e "${YELLOW}【连接命令】${NC}" + echo " 本地连接: redis-cli -h 127.0.0.1 -p ${REDIS_PORT_OUT} -a ${REDIS_PWD}" + echo " 容器内连接: docker exec -it ${REDIS_CONTAINER} redis-cli -a ${REDIS_PWD}" + echo "" +} + +# ==================== 交互式菜单 ==================== + +show_menu() { + echo "" + echo " 1、安装并启动" + echo " 2、启动容器" + echo " 3、重启容器" + echo " 4、停止容器" + echo " 5、删除容器和数据" + echo " 6、查看日志" + echo " 7、查看容器信息" + echo " 8、查看帮助" + echo " 9、退出" + echo "" + read -p "请选择操作 (1-9): " choice + echo "" + + case $choice in + 1) do_install ;; + 2) do_start ;; + 3) do_restart ;; + 4) do_stop ;; + 5) do_delete ;; + 6) do_logs ;; + 7) do_info ;; + 8) show_help; show_menu ;; + 9) echo "已退出"; exit 0 ;; + *) echo "无效选择,请重试"; show_menu ;; + esac +} + +# ==================== 主逻辑 ==================== + +if [ $# -eq 0 ]; then + # 无参数时显示交互式菜单 + show_menu +else + case "$1" in + install) + do_install + ;; + start) + do_start + ;; + restart) + do_restart + ;; + stop) + do_stop + ;; + delete) + do_delete + ;; + logs) + do_logs + ;; + ps) + do_ps + ;; + info) + do_info + ;; + info-db) + do_info_db + ;; + info-redis) + do_info_redis + ;; + -h|--help) + show_help + ;; + *) + show_help + exit 1 + ;; + esac +fi