2026-02-10
Tech
00

目录

run-compose.sh脚本
compose示例
使用脚本

为了方便使用Docker compose进行批发性的部署,下面提供了一个通用的使用DockerCompose的Docker项目部署脚本

其中

  • PROJECT NAME 为项目显示名称
  • COMPOSE_URL 为存放Docker compose文件的URL
  • PLACEHOLDER_PORT 为占位符,不需要修改
  • DEFAULT_PORT 为默认的对外端口

run-compose.sh脚本

bash
#!/bin/sh # ================= PROFILE ================= PROJECT_NAME="PROJECT NAME" COMPOSE_URL="https://.../.../*.yaml" PLACEHOLDER_PORT="PORT" DEFAULT_PORT="6688" COMPOSE_TEMPLATE="docker-compose-${PROJECT_NAME}.yaml" COMPOSE_FILE="docker-compose.yaml" # =========================================== RED='\033[31m' GREEN='\033[32m' YELLOW='\033[33m' BLUE='\033[34m' CYAN='\033[36m' WHITE='\033[37m' BOLD='\033[1m' PLAIN='\033[0m' log_info() { printf "${CYAN}│ [INFO] ${PLAIN} %s\n" "$1"; } log_success() { printf "${GREEN}│ [OK] ${PLAIN} %s\n" "$1"; } log_warn() { printf "${YELLOW}│ [WARN] ${PLAIN} %s\n" "$1"; } log_err() { printf "${RED}│ [ERR] ${PLAIN} %s\n" "$1"; } check_env() { if ! command -v docker > /dev/null 2>&1; then printf "\n" log_err "未检测到 Docker,请先安装。" exit 1 fi } download_compose_file() { if [ -f "$COMPOSE_TEMPLATE" ]; then return; fi log_info "正在下载配置模板..." if command -v curl >/dev/null 2>&1; then curl -fsSL "$COMPOSE_URL" -o "$COMPOSE_TEMPLATE" elif command -v wget >/dev/null 2>&1; then wget -qO "$COMPOSE_TEMPLATE" "$COMPOSE_URL" else log_err "缺少 curl 或 wget,无法下载。" return 1 fi [ -f "$COMPOSE_TEMPLATE" ] || { log_err "下载失败。"; return 1; } log_success "模板下载完成。" } do_up() { check_env download_compose_file || return printf "\n" printf "${BLUE}╭── ${BOLD}⚙️ 配置向导${PLAIN}${BLUE}───────────────────────────${PLAIN}\n" printf "${BLUE}${PLAIN}\n" printf "${BLUE}${PLAIN} 请输入宿主机对外端口 (默认: ${CYAN}%s${PLAIN}): " "$DEFAULT_PORT" read INPUT_PORT < /dev/tty PORT="${INPUT_PORT:-$DEFAULT_PORT}" case "$PORT" in ''|*[!0-9]*) log_err "端口必须是数字。"; return ;; esac if grep -q "$PLACEHOLDER_PORT" "$COMPOSE_TEMPLATE"; then sed "s/$PLACEHOLDER_PORT/$PORT/g" "$COMPOSE_TEMPLATE" > "$COMPOSE_FILE" else cp "$COMPOSE_TEMPLATE" "$COMPOSE_FILE" fi log_info "正在启动容器..." docker compose up -d if [ $? -eq 0 ]; then printf "${BLUE}${PLAIN}\n" log_success "服务部署成功!" printf "${BLUE}${PLAIN} 🔗 访问地址: http://localhost:${BOLD}%s${PLAIN}\n" "$PORT" printf "${BLUE}╰─────────────────────────────────────────${PLAIN}\n" printf "\n" else log_err "启动失败,请检查报错。" fi } do_down() { if [ ! -f "$COMPOSE_FILE" ]; then log_warn "未发现配置文件。" return fi printf "${BLUE}${PLAIN}\n" printf "${BLUE}${PLAIN} ${YELLOW}请选择清理级别:${PLAIN}\n" printf "${BLUE}${PLAIN} ${GREEN}1.${PLAIN}仅停止并删除容器和网络\n" printf "${BLUE}${PLAIN} ${GREEN}2.${PLAIN} 同时删除挂载卷(数据会丢失!)\n" printf "${BLUE}${PLAIN} ${GREEN}3.${PLAIN} 同时删除本地构建的镜像(不影响公共镜像)\n" printf "${BLUE}${PLAIN} ${GREEN}4.${PLAIN} 删除一切(含公共镜像如redis/mysql)\n" printf "${BLUE}${PLAIN}\n" printf "👉 请选择 [1-4](默认 1): " read level < /dev/tty level="${level:-1}" case "$level" in 1) docker compose down ;; 2) docker compose down -v ;; 3) docker compose down -v --rmi local ;; 4) docker compose down -v --rmi all ;;*) log_err "无效选择"; return ;; esac rm -f "$COMPOSE_FILE" "$COMPOSE_TEMPLATE" log_success "清理完成。" } do_start() { [ -f "$COMPOSE_FILE" ] || { log_err "请先执行 [1] 部署"; return; } docker compose start && log_success "服务已启动" } do_stop() { [ -f "$COMPOSE_FILE" ] || { log_err "请先执行 [1] 部署"; return; } docker compose stop && log_success "服务已暂停" } do_restart() { [ -f "$COMPOSE_FILE" ] || { log_err "请先执行 [1] 部署"; return; } docker compose restart && log_success "服务已重启" } do_update() { [ -f "$COMPOSE_FILE" ] || { log_err "请先执行 [1] 部署"; return; } log_info "拉取镜像..." && docker compose pull log_info "重建容器..." && docker compose up -d log_success "更新完成" } do_status() { [ -f "$COMPOSE_FILE" ] || { log_err "未配置服务"; return; } printf "\n" docker compose ps printf "\n" } show_menu() { printf "${BLUE}╭─────────────────────────────────────────${PLAIN}\n" printf "${BLUE}${PLAIN} ${BOLD}🐳 Docker ${PLAIN} ${CYAN}%s${PLAIN}\n" "$PROJECT_NAME" printf "${BLUE}├─────────────────────────────────────────${PLAIN}\n" printf "${BLUE}${PLAIN}\n" printf "${BLUE}${PLAIN} ${GREEN}1.${PLAIN} 🚀 %-30s\n" "一键部署 (Up)" printf "${BLUE}${PLAIN} ${GREEN}2.${PLAIN} 🗑️ %-30s\n" "彻底删除 (Down)" printf "${BLUE}${PLAIN}\n" printf "${BLUE}${PLAIN} ${GREEN}3.${PLAIN} ▶️ %-30s\n" "启动服务 (Start)" printf "${BLUE}${PLAIN} ${GREEN}4.${PLAIN} ⏹️ %-30s\n" "停止服务 (Stop)" printf "${BLUE}${PLAIN} ${GREEN}5.${PLAIN} 🔄 %-30s\n" "重启服务 (Restart)" printf "${BLUE}${PLAIN} ${GREEN}6.${PLAIN} 🆙 %-30s\n" "更新镜像 (Update)" printf "${BLUE}${PLAIN} ${GREEN}7.${PLAIN} 📊 %-30s\n" "查看状态 (Status)" printf "${BLUE}${PLAIN}\n" printf "${BLUE}${PLAIN} ${GREEN}0.${PLAIN} 🚪 %-30s\n" "退出脚本 (Exit)" printf "${BLUE}${PLAIN}\n" printf "${BLUE}╰─────────────────────────────────────────${PLAIN}\n" } while :; do show_menu printf " 👉 请输入指令 [0-7]: " read choice < /dev/tty case "$choice" in 1) do_up ;; 2) do_down ;; 3) do_start ;; 4) do_stop ;; 5) do_restart ;; 6) do_update ;; 7) do_status ;; 0) printf "\n👋 Bye!\n\n"; exit 0 ;; *) printf "\n${RED}❌ 无效指令${PLAIN}\n"; sleep 1 ;; esac printf "\n 按 Enter 继续..." read _ < /dev/tty done

compose示例

bash
services: redis: image: redis:7 container_name: redis-db volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 fastapi: image: xly23333/fastapi-redis container_name: fastapi-app ports: - "PORT:6001" environment: REDIS_HOST: redis REDIS_PORT: 6379 depends_on: redis: condition: service_healthy volumes: redis_data:

这里的核心是:对外port的位置一定要书写为"PORT:容器内端口",这样脚本就可以自动替换默认/用户输入的脚本

使用脚本

将脚本和compose全部放置在服务器上,开启一个web服务器,随后再任意设备上运行下面的命令来使用

bash
wget -N https://<URL>/<shellName>.sh && sudo sh ./<shellName>.sh

其中<URL><shellName>请根据自己的需要进行修改

本文作者:XLY23333

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!