From 9f993b7793fb06a0bc31fb10a3db1d81da1dc457 Mon Sep 17 00:00:00 2001 From: Dcr Date: Tue, 22 Jul 2025 17:58:34 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A6=96=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 29 ++++ .env | 7 + DockerFile/Dockerfile | 41 ++++++ DockerFile/install_dayz.sh | 37 +++++ DockerFile/start.sh | 132 +++++++++++++++++ README.md | 287 +++++++++++++++++++++++++++++++++++++ docker-compose.yml | 24 ++++ install.sh | 276 +++++++++++++++++++++++++++++++++++ 8 files changed, 833 insertions(+) create mode 100644 .dockerignore create mode 100644 .env create mode 100644 DockerFile/Dockerfile create mode 100644 DockerFile/install_dayz.sh create mode 100644 DockerFile/start.sh create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 install.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3742bb4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,29 @@ +# Git相关 +.git +.gitignore + +# Docker相关 +Dockerfile +docker-compose.yml +.dockerignore +# 保留启动脚本 +!start.sh + +# 文档 +README.md +*.md + +# 日志文件 +*.log + +# 临时文件 +*.tmp +*.temp + +# 游戏数据目录(避免复制到镜像中) +games/ +steamcmd_data/ + +# 系统文件 +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/.env b/.env new file mode 100644 index 0000000..fe910eb --- /dev/null +++ b/.env @@ -0,0 +1,7 @@ +# Steam账户信息 +# 请将以下值替换为您的实际Steam用户名和密码 +STEAM_USERNAME=your_steam_username +STEAM_PASSWORD=your_steam_password + +# 注意:为了安全起见,建议使用Steam Guard令牌而不是账户密码 +# 如果启用了Steam Guard,密码应该是您的Steam Guard令牌 \ No newline at end of file diff --git a/DockerFile/Dockerfile b/DockerFile/Dockerfile new file mode 100644 index 0000000..06c6d3d --- /dev/null +++ b/DockerFile/Dockerfile @@ -0,0 +1,41 @@ +# 使用Ubuntu 22.04作为基础镜像 +FROM ubuntu:22.04 + +ENV STEAMCMD_DIR=/opt/steamcmd +ENV STEAMCMD_URL=https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y \ + wget \ + ca-certificates \ + lib32gcc-s1 \ + lib32stdc++6 \ + libc6-i386 \ + libcurl4 \ + libncurses5 \ + libsdl2-2.0-0 \ + libtinfo5 \ + libvorbisfile3 \ + lib32z1 \ + && rm -rf /var/lib/apt/lists/* + +RUN mkdir -p ${STEAMCMD_DIR} + +COPY install_dayz.sh /opt/install_dayz.sh +COPY start.sh /opt/start.sh +RUN chmod +x /opt/install_dayz.sh /opt/start.sh + +RUN useradd -m -d /home/steam steam + +RUN mkdir -p /opt/games + +RUN chown -R steam:steam ${STEAMCMD_DIR} && \ + chown -R steam:steam /home/steam && \ + chown steam:steam /opt/install_dayz.sh && \ + chown steam:steam /opt/start.sh && \ + chown -R steam:steam /opt/games + +WORKDIR ${STEAMCMD_DIR} + +CMD ["/opt/start.sh"] \ No newline at end of file diff --git a/DockerFile/install_dayz.sh b/DockerFile/install_dayz.sh new file mode 100644 index 0000000..4c7f2c3 --- /dev/null +++ b/DockerFile/install_dayz.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# DayZ服务器安装脚本 +# 使用环境变量中的Steam用户名和密码 + +# 检查环境变量 +if [ -z "$STEAM_USERNAME" ] || [ -z "$STEAM_PASSWORD" ]; then + echo "错误: 请设置 STEAM_USERNAME 和 STEAM_PASSWORD 环境变量" + echo "在本目录下执行 vi .env 设置环境变量" + echo "示例:" + echo "export STEAM_USERNAME=your_username" + echo "export STEAM_PASSWORD=your_password" + exit 1 +fi + +# 切换到SteamCMD目录 +cd /opt/steamcmd + +# 运行SteamCMD安装DayZ服务器 +echo "开始安装DayZ服务器..." +./steamcmd.sh +login $STEAM_USERNAME $STEAM_PASSWORD +app_update 223350 validate +quit + +# 检查安装结果 +if [ $? -eq 0 ]; then + echo "DayZ服务器安装完成!" +else + echo "安装失败,请检查用户名和密码是否正确" + exit 1 +fi + +# 初始化BERcon配置 +password=$(tr -dc 'A-Za-z0-9!@%^_=+?' < /dev/urandom | head -c 12) +cat > /root/Steam/steamapps/common/DayZServer/battleye/beserver_x64.cfg << EOF +RConPort 2314 +RConPassword $password +RestrictRCon 0 +EOF \ No newline at end of file diff --git a/DockerFile/start.sh b/DockerFile/start.sh new file mode 100644 index 0000000..44b6df8 --- /dev/null +++ b/DockerFile/start.sh @@ -0,0 +1,132 @@ +#!/bin/bash + +set -e # 遇到错误时退出 + +echo "==========================================" +echo "SteamCMD容器启动中..." +echo "时间: $(date)" +echo "==========================================" + +copy_files() { + local mod_path=$1 + local parent_path=$2 + local lower_addons_path="${mod_path}/addons" + local upper_addons_path="${mod_path}/Addons" + local lower_keys_path="${mod_path}/keys" + local upper_keys_path="${mod_path}/Keys" + + # 处理addons目录 + if [ -d "$lower_addons_path" ]; then + find "$lower_addons_path" -type f -name '*.bisign' -exec cp -dpf {} "$parent_path/addons/" \; + elif [ -d "$upper_addons_path" ]; then + find "$upper_addons_path" -type f -name '*.bisign' -exec cp -dpf {} "$parent_path/addons/" \; + fi + + # 处理keys目录 + if [ -d "$lower_keys_path" ]; then + find "$lower_keys_path" -type f -name '*.bikey' -exec cp -dpf {} "$parent_path/keys/" \; + elif [ -d "$upper_keys_path" ]; then + find "$upper_keys_path" -type f -name '*.bikey' -exec cp -dpf {} "$parent_path/keys/" \; + fi +} + +start_dayzserver() { + cd /root/Steam/steamapps/common/DayZServer + + # 初始化mod变量 + client_mods="" + server_mods="" + + while IFS= read -r -d $'\0' folder; do + echo "处理客户端mod: $folder" + copy_files "$folder" "." + if [ -n "$client_mods" ]; then + client_mods="${client_mods};" + fi + client_mods="${client_mods}${folder}" + done < <(find "./client_mod" -type d -name '@*' -print0) + + while IFS= read -r -d $'\0' folder; do + echo "处理服务端mod: $folder" + copy_files "$folder" "." + if [ -n "$server_mods" ]; then + server_mods="${server_mods};" + fi + server_mods="${server_mods}${folder}" + done < <(find "./server_mod" -type d -name '@*' -print0) + + # 崩溃检测和自动重启循环 + while true; do + echo "==========================================" + echo "启动DayZServer..." + echo "时间: $(date)" + echo "端口: ${DAYZ_SERVER_PORT}" + echo "CPU核心数: ${DAYZ_CPU_COUNT}" + echo "客户端mod: ${client_mods}" + echo "服务端mod: ${server_mods}" + echo "==========================================" + + echo "执行命令: ./DayZServer -port=${DAYZ_SERVER_PORT} -cpuCount=${DAYZ_CPU_COUNT} -config=serverDZ.cfg -profiles=profiles -mission=./mpmissions/${DAYZ_MISSIONS} -mod=${client_mods} -servermod=${server_mods}" + + # 启动DayZServer并捕获退出状态 + ./DayZServer -port=${DAYZ_SERVER_PORT} -cpuCount=${DAYZ_CPU_COUNT} \ + "-config=serverDZ.cfg" "-profiles=profiles" \ + "-mission=./mpmissions/${DAYZ_MISSIONS}" \ + "-mod=${client_mods}" "-servermod=${server_mods}" & + + # 保存进程ID + DAYZ_PID=$! + echo "DayZServer进程ID: $DAYZ_PID" + + # 等待进程结束 + wait $DAYZ_PID + EXIT_CODE=$? + + echo "==========================================" + echo "DayZServer已退出" + echo "退出代码: $EXIT_CODE" + echo "时间: $(date)" + echo "==========================================" + + # 检查是否正常退出(退出代码0通常表示正常退出) + if [ $EXIT_CODE -eq 0 ]; then + echo "DayZServer正常退出,将在5秒后重启..." + sleep 5 + echo "重新启动DayZServer..." + else + echo "DayZServer异常退出,将在5秒后重启..." + sleep 5 + echo "重新启动DayZServer..." + fi + done +} + + +# 检查并安装SteamCMD +if [ ! -f "/opt/steamcmd/steamcmd.sh" ]; then + echo "SteamCMD未安装,开始下载和安装..." + echo "下载SteamCMD..." + wget -O /opt/steamcmd/steamcmd_linux.tar.gz ${STEAMCMD_URL} + echo "解压SteamCMD..." + tar xvzf /opt/steamcmd/steamcmd_linux.tar.gz -C /opt/steamcmd + echo "清理临时文件..." + rm /opt/steamcmd/steamcmd_linux.tar.gz + echo "设置执行权限..." + chmod +x /opt/steamcmd/steamcmd.sh + echo "SteamCMD安装完成!" +else + echo "SteamCMD已存在,跳过安装" +fi + +if [ ! -f "/root/Steam/steamapps/common/DayZServer/DayZServer" ]; then + echo "DayZServer未安装,开始安装..." + bash /opt/install_dayz.sh +else + echo "DayZServer已安装,检查更新" + # 切换到SteamCMD目录 + cd /opt/steamcmd + ./steamcmd.sh +login $STEAM_USERNAME $STEAM_PASSWORD +app_update 223350 validate +quit + echo "启动DayZServer..." + cd /root/Steam/steamapps/common/DayZServer + start_dayzserver +fi \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..a7e4920 --- /dev/null +++ b/README.md @@ -0,0 +1,287 @@ +# DayZ服务器 Docker 部署项目 + +这是一个用于快速部署DayZ服务器的Docker化解决方案。通过Docker容器化技术,您可以轻松地在任何支持Docker的系统上运行DayZ服务器,无需复杂的本地环境配置。 + +## 🎯 项目特性 + +- **一键部署**: 使用Docker Compose实现一键部署DayZ服务器 +- **自动安装**: 自动下载并安装SteamCMD和DayZ服务器 +- **Mod支持**: 支持客户端和服务端Mod的自动加载 +- **崩溃恢复**: 内置崩溃检测和自动重启机制 +- **跨平台**: 支持Linux、Windows、macOS等操作系统 +- **环境隔离**: 使用Docker容器确保环境隔离和一致性 +- **配置灵活**: 支持通过环境变量自定义服务器配置 + +## 📋 系统要求 + +- Docker 20.10+ +- Docker Compose 2.0+ +- 至少4GB可用内存 +- 至少10GB可用磁盘空间 +- 稳定的网络连接(用于下载SteamCMD和DayZ服务器) + +## 🚀 快速开始 + +### 1. 克隆项目 + +```bash +git clone ./Docker_DayzServer +cd Docker_DayzServer +``` + +### 2. 设置环境变量 + +创建 `.env` 文件并配置您的Steam账户信息: + +```bash +# 创建环境变量文件 +cat > .env << EOF +STEAM_USERNAME=your_steam_username +STEAM_PASSWORD=your_steam_password +DAYZ_MISSIONS=dayzOffline.chernarusplus +DAYZ_SERVER_PORT=2302 +DAYZ_CPU_COUNT=4 +EOF +``` + +**重要**: 请确保使用有效的Steam账户,该账户 不需要 拥有DayZ游戏。 + +### 3. 运行安装脚本 + +```bash +# 给安装脚本执行权限 +chmod +x install.sh + +# 运行安装脚本(需要root权限) +sudo ./install.sh +``` + +安装脚本将自动: +- 检测您的操作系统 +- 安装Docker和Docker Compose +- 构建Docker镜像 +- 启动DayZ服务器 + +### 4. 手动部署(可选) + +如果您想手动部署,可以按以下步骤操作: + +```bash +# 构建Docker镜像, 如果仓库有更新, 都需要重新 build 一次, 更新不需要 --no-cache +docker-compose build --no-cache + +# 运行steamcmd容器进行初始安装 +docker-compose run --rm steamcmd + +# 启动所有服务 +docker-compose up -d +``` + +## ⚙️ 配置说明 + +### 环境变量 + +| 变量名 | 默认值 | 说明 | +|--------|--------|------| +| `STEAM_USERNAME` | - | Steam用户名(必需) | +| `STEAM_PASSWORD` | - | Steam密码(必需) | +| `DAYZ_MISSIONS` | `dayzOffline.chernarusplus` | 服务器地图 | +| `DAYZ_SERVER_PORT` | `2302` | 服务器端口 | +| `DAYZ_CPU_COUNT` | `4` | 使用的CPU核心数 | + +### 端口映射 + +| 容器端口 | 主机端口 | 说明 | +|----------|----------|------| +| 2302/udp | 2302/udp | DayZ游戏端口 | +| 2305/udp | 2305/udp | DayZ查询端口 | +| 2314/udp | 2314/udp | BattlEye RCon端口 | + +### 目录结构 + +``` +Docker_DayzServer/ +├── docker-compose.yml # Docker Compose配置文件 +├── DockerFile/ # Docker构建文件 +│ ├── Dockerfile # Docker镜像定义 +│ ├── install_dayz.sh # DayZ安装脚本 +│ └── start.sh # 启动脚本 +├── install.sh # 一键安装脚本 +└── dayz/ # 数据目录(自动创建) + ├── .steamcmd/ # SteamCMD数据 + ├── .dayz_server/ # DayZ服务器文件 + ├── client_mod/ # 客户端Mod + ├── server_mod/ # 服务端Mod + ├── battleye/ # BattlEye配置 + ├── profiles/ # 服务器配置文件 + └── mpmissions/ # 地图文件 +``` + +## 🎮 使用说明 + +### 启动服务器 + +```bash +# 启动所有服务 +docker-compose up -d + +# 查看运行状态 +docker-compose ps + +# 查看日志 +docker-compose logs -f steamcmd +``` + +### 停止服务器 + +```bash +# 停止所有服务 +docker-compose down + +# 停止并删除数据卷(谨慎使用) +docker-compose down -v +``` + +### 重启服务器 + +```bash +# 重启服务 +docker-compose restart steamcmd +``` + +### 更新服务器 + +```bash +# 重新构建镜像并启动 +docker-compose build --no-cache +docker-compose up -d +``` + +## 🔧 Mod管理 + +### 添加客户端Mod + +1. 将Mod文件放入 `dayz/client_mod/` 目录 +2. Mod文件夹应以 `@` 开头 +3. 重启服务器以加载新Mod + +### 添加服务端Mod + +1. 将Mod文件放入 `dayz/server_mod/` 目录 +2. Mod文件夹应以 `@` 开头 +3. 重启服务器以加载新Mod + +### Mod配置示例 + +``` +dayz/ +├── client_mod/ +│ ├── @CF +│ └── @DayZExpansion +└── server_mod/ + └── @DayZExpansionServer +``` + +## 📊 监控和日志 + +### 查看实时日志 + +```bash +# 查看容器日志 +docker-compose logs -f steamcmd + +# 查看特定时间段的日志 +docker-compose logs --since="2024-01-01T00:00:00" steamcmd +``` + +### 服务器状态检查 + +```bash +# 检查容器状态 +docker-compose ps + +# 检查资源使用情况 +docker stats steamcmd +``` + +## 🔒 安全配置 + +### BattlEye配置 + +BattlEye配置文件位于 `dayz/battleye/beserver_x64.cfg`,包含: +- RCon端口:2314 +- 自动生成的RCon密码 +- 远程管理设置 + +### 防火墙配置 + +确保以下端口在防火墙中开放: +- UDP 2302 (游戏端口) +- UDP 2305 (查询端口) +- UDP 2314 (RCon端口) + +## 🛠️ 故障排除 + +### 常见问题 + +1. **Steam登录失败** + - 检查Steam用户名和密码是否正确 + - 检查网络连接 + +2. **服务器无法启动** + - 检查端口是否被占用 + - 查看容器日志:`docker-compose logs steamcmd` + - 确保有足够的磁盘空间 + +3. **Mod加载失败** + - 检查Mod文件夹名称是否正确(以@开头) + - 确保Mod文件完整 + - 查看启动日志中的Mod加载信息 + +### 调试命令 + +```bash +# 进入容器进行调试 +docker-compose exec steamcmd bash + +# 查看容器资源使用情况 +docker stats steamcmd + +# 检查网络连接 +docker-compose exec steamcmd netstat -tulpn +``` + +## 📝 更新日志 + +### v1.0.0 +- 初始版本发布 +- 支持基本的DayZ服务器部署 +- 集成SteamCMD自动安装 +- 支持Mod加载 +- 内置崩溃恢复机制 + +## 🤝 贡献 + +欢迎提交Issue和Pull Request来改进这个项目! + +## 📄 许可证 + +本项目采用MIT许可证。详见LICENSE文件。 + +## ⚠️ 免责声明 + +- 本项目仅供学习和研究使用 +- 请确保遵守DayZ和Steam的服务条款 +- 使用本项目的风险由用户自行承担 +- 建议在测试环境中先进行验证 + +## 📞 支持 + +如果您在使用过程中遇到问题,请: +1. 查看本文档的故障排除部分 +2. 检查项目的Issue页面 +3. 提交新的Issue并提供详细的错误信息 + +--- + +**祝您游戏愉快!** 🎮 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c4a67c3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,24 @@ +services: + steamcmd: + build: ./DockerFile/ + container_name: steamcmd + volumes: + - ./dayz/.steamcmd:/root/Steam + - ./dayz/.dayz_server:/root/Steam/steamapps/common/DayZServer + - ./dayz/.steamcmd_data:/opt/steamcmd + - ./dayz/client_mod:/root/Steam/steamapps/common/DayZServer/client_mod + - ./dayz/server_mod:/root/Steam/steamapps/common/DayZServer/server_mod + - ./dayz/battleye:/root/Steam/steamapps/common/DayZServer/battleye + - ./dayz/profiles:/root/Steam/steamapps/common/DayZServer/profiles + - ./dayz/mpmissions:/root/Steam/steamapps/common/DayZServer/mpmissions + environment: + - STEAM_USERNAME=${STEAM_USERNAME:-} + - STEAM_PASSWORD=${STEAM_PASSWORD:-} + - DAYZ_MISSIONS=dayzOffline.chernarusplus + - DAYZ_SERVER_PORT=2302 + - DAYZ_CPU_COUNT=4 + ports: + - "2302:2302/udp" + - "2305:2305/udp" + - "2314:2314/udp" + restart: unless-stopped \ No newline at end of file diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..9060fb6 --- /dev/null +++ b/install.sh @@ -0,0 +1,276 @@ +#!/bin/bash + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# 打印带颜色的消息 +print_message() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# 检测操作系统类型 +detect_os() { + if [ -f /etc/os-release ]; then + . /etc/os-release + OS=$NAME + VER=$VERSION_ID + elif type lsb_release >/dev/null 2>&1; then + OS=$(lsb_release -si) + VER=$(lsb_release -sr) + elif [ -f /etc/lsb-release ]; then + . /etc/lsb-release + OS=$DISTRIB_ID + VER=$DISTRIB_RELEASE + elif [ -f /etc/debian_version ]; then + OS=Debian + VER=$(cat /etc/debian_version) + elif [ -f /etc/SuSe-release ]; then + OS=SuSE + elif [ -f /etc/redhat-release ]; then + OS=RedHat + VER=$(cat /etc/redhat-release | sed 's/.*release \([0-9.]*\).*/\1/') + else + OS=$(uname -s) + VER=$(uname -r) + fi + + echo "检测到操作系统: $OS $VER" +} + +# 更新包管理器 +update_package_manager() { + print_message "更新包管理器..." + + if [[ "$OS" == *"Ubuntu"* ]] || [[ "$OS" == *"Debian"* ]]; then + apt update && apt upgrade -y + apt install -y curl wget + elif [[ "$OS" == *"CentOS"* ]] || [[ "$OS" == *"Red Hat"* ]] || [[ "$OS" == *"Rocky"* ]] || [[ "$OS" == *"AlmaLinux"* ]]; then + if command -v dnf &> /dev/null; then + dnf update -y + dnf install -y curl wget + else + yum update -y + yum install -y curl wget + fi + else + print_message "使用通用方式安装curl和wget..." + # 尝试通用方式安装 + if command -v apt &> /dev/null; then + apt update && apt install -y curl wget + elif command -v dnf &> /dev/null; then + dnf install -y curl wget + elif command -v yum &> /dev/null; then + yum install -y curl wget + elif command -v zypper &> /dev/null; then + zypper install -y curl wget + else + print_warning "无法自动安装curl和wget,请手动安装" + fi + fi +} + +# 卸载旧版本Docker +remove_old_docker() { + print_message "检查并卸载旧版本Docker..." + + if [[ "$OS" == *"Ubuntu"* ]] || [[ "$OS" == *"Debian"* ]]; then + apt-get remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true + elif [[ "$OS" == *"CentOS"* ]] || [[ "$OS" == *"Red Hat"* ]] || [[ "$OS" == *"Rocky"* ]] || [[ "$OS" == *"AlmaLinux"* ]]; then + if command -v dnf &> /dev/null; then + dnf remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 2>/dev/null || true + else + yum remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 2>/dev/null || true + fi + else + print_message "使用通用方式卸载旧版本Docker..." + # 通用卸载方式 + if command -v apt &> /dev/null; then + apt-get remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true + elif command -v dnf &> /dev/null; then + dnf remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 2>/dev/null || true + elif command -v yum &> /dev/null; then + yum remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 2>/dev/null || true + fi + fi +} + +# 安装Docker +install_docker() { + print_message "安装Docker..." + + # 使用官方的get-docker.sh脚本,它已经做了跨平台兼容 + curl -fsSL https://get.docker.com -o get-docker.sh + sh get-docker.sh + rm -f get-docker.sh + + # 启动并启用Docker服务 + systemctl start docker + systemctl enable docker +} + +# 安装Docker Compose +install_docker_compose() { + print_message "安装Docker Compose..." + + # 检查是否已经安装了docker-compose-plugin + if docker compose version &> /dev/null; then + print_message "Docker Compose 插件已安装" + return + fi + + # 下载并安装独立版本的Docker Compose + COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d\" -f4) + + # 下载适合当前系统的Docker Compose二进制文件 + curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + + chmod +x /usr/local/bin/docker-compose + + # 创建软链接 + ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose +} + +# 验证安装 +verify_installation() { + print_message "验证安装..." + + if command -v docker &> /dev/null; then + print_message "Docker 安装成功" + docker --version + else + print_error "Docker 安装失败" + exit 1 + fi + + if command -v docker-compose &> /dev/null || docker compose version &> /dev/null; then + print_message "Docker Compose 安装成功" + if command -v docker-compose &> /dev/null; then + docker-compose --version + else + docker compose version + fi + else + print_error "Docker Compose 安装失败" + exit 1 + fi + + # 测试Docker服务 + if systemctl is-active --quiet docker; then + print_message "Docker 服务运行正常" + else + print_error "Docker 服务未运行" + exit 1 + fi +} + +# 构建和启动Docker容器 +build_and_start_containers() { + print_message "开始构建和启动Docker容器..." + + # 检查是否存在docker-compose.yml文件 + if [ ! -f "docker-compose.yml" ]; then + print_error "未找到docker-compose.yml文件,请确保在正确的目录中运行此脚本" + exit 1 + fi + + # 构建Docker镜像(不使用缓存) + print_message "构建Docker镜像(不使用缓存)..." + if command -v docker-compose &> /dev/null; then + docker-compose build --no-cache + else + docker compose build --no-cache + fi + + if [ $? -ne 0 ]; then + print_error "Docker镜像构建失败" + exit 1 + fi + + print_message "Docker镜像构建成功" + + # 运行steamcmd容器 + print_message "运行steamcmd容器..." + if command -v docker-compose &> /dev/null; then + docker-compose run --rm steamcmd + else + docker compose run --rm steamcmd + fi + + if [ $? -ne 0 ]; then + print_warning "steamcmd容器运行失败,但继续启动其他服务" + else + print_message "steamcmd容器运行完成" + fi + + # 启动所有容器 + print_message "启动所有Docker容器..." + if command -v docker-compose &> /dev/null; then + docker-compose up -d + else + docker compose up -d + fi + + if [ $? -eq 0 ]; then + print_message "所有Docker容器启动成功" + + # 显示容器状态 + print_message "容器状态:" + if command -v docker-compose &> /dev/null; then + docker-compose ps + else + docker compose ps + fi + else + print_error "Docker容器启动失败" + exit 1 + fi +} + +# 主函数 +main() { + print_message "开始安装 Docker 和 Docker Compose..." + + # 检查是否为root用户 + if [[ $EUID -ne 0 ]]; then + print_error "此脚本需要root权限运行" + exit 1 + fi + + detect_os + update_package_manager + remove_old_docker + install_docker + install_docker_compose + verify_installation + + print_message "Docker 和 Docker Compose 安装完成!" + + # 询问是否继续构建和启动容器 + echo + read -p "是否现在构建和启动Docker容器?(y/n): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + build_and_start_containers + print_message "所有操作完成!" + else + print_message "安装完成!您可以稍后手动运行以下命令:" + print_message "1. docker-compose build --no-cache" + print_message "2. docker-compose run --rm steamcmd" + print_message "3. docker-compose up -d" + print_message "运行第二步时,第一次运行会等待steam验证码,需要手动输入" + fi +} + +# 执行主函数 +main "$@" \ No newline at end of file