#!/bin/bash # Gitea一键安装脚本 # 作者:AI助手 # 日期:2025-03-13 set -e echo "===== Gitea一键安装脚本 =====" echo "此脚本将在已有DNMP环境中部署Gitea服务" # 检查是否有root权限 if [ "$(id -u)" != "0" ]; then echo "此脚本需要root权限运行" 1>&2 exit 1 fi # 检查必要的命令 for cmd in docker docker-compose certbot; do if ! command -v $cmd &> /dev/null; then echo "错误: $cmd 未安装" 1>&2 exit 1 fi done # 检查DNMP环境 DOCKER_NETWORK="dnmp_default" if ! docker network ls | grep -q dnmp_default; then # 如果没有找到dnmp_default网络,检查是否有其他Docker网络 if [ $(docker network ls | wc -l) -le 2 ]; then echo "错误: 未找到可用的Docker网络,请确保Docker环境已正常运行" 1>&2 exit 1 else echo "警告: 未找到dnmp_default网络,将使用默认的bridge网络" DOCKER_NETWORK="bridge" fi else echo "找到Docker网络: $DOCKER_NETWORK" fi # 检查MySQL容器 MYSQL_CONTAINER=$(docker ps | grep -E 'mysql|mariadb' | head -1 | awk '{print $1}') if [ -z "$MYSQL_CONTAINER" ]; then echo "错误: MySQL容器未找到,请确保MySQL服务已正常运行" 1>&2 exit 1 else MYSQL_CONTAINER_NAME=$(docker inspect --format='{{.Name}}' $MYSQL_CONTAINER | sed 's/\///') echo "找到MySQL容器: $MYSQL_CONTAINER_NAME" fi # 检查Nginx容器 NGINX_CONTAINER=$(docker ps | grep nginx | head -1 | awk '{print $1}') if [ -z "$NGINX_CONTAINER" ]; then echo "错误: Nginx容器未找到,请确保Nginx服务已正常运行" 1>&2 exit 1 else NGINX_CONTAINER_NAME=$(docker inspect --format='{{.Name}}' $NGINX_CONTAINER | sed 's/\///') echo "找到Nginx容器: $NGINX_CONTAINER_NAME" # 检查Nginx容器的挂载点 echo "检查Nginx容器的挂载点..." SSL_MOUNT=$(docker inspect -f '{{range .Mounts}}{{if eq .Destination "/ssl"}}{{.Source}}{{end}}{{end}}' $NGINX_CONTAINER) WWW_MOUNT=$(docker inspect -f '{{range .Mounts}}{{if eq .Destination "/www"}}{{.Source}}{{end}}{{end}}' $NGINX_CONTAINER) CONF_MOUNT=$(docker inspect -f '{{range .Mounts}}{{if eq .Destination "/etc/nginx/conf.d"}}{{.Source}}{{end}}{{end}}' $NGINX_CONTAINER) if [ -z "$SSL_MOUNT" ]; then echo "警告: 未找到Nginx容器的SSL挂载点,将使用默认路径" SSL_MOUNT="/opt/dnmp/services/nginx/ssl" else echo "找到Nginx SSL挂载点: $SSL_MOUNT" fi if [ -z "$WWW_MOUNT" ]; then echo "警告: 未找到Nginx容器的WWW挂载点,将使用默认路径" WWW_MOUNT="/opt/dnmp/www" else echo "找到Nginx WWW挂载点: $WWW_MOUNT" fi if [ -z "$CONF_MOUNT" ]; then echo "警告: 未找到Nginx容器的配置挂载点,将使用默认路径" CONF_MOUNT="/opt/dnmp/services/nginx/conf.d" else echo "找到Nginx配置挂载点: $CONF_MOUNT" fi # 检查Nginx容器的网络 NGINX_NETWORK=$(docker inspect -f '{{range $key, $value := .NetworkSettings.Networks}}{{$key}}{{end}}' $NGINX_CONTAINER) if [ ! -z "$NGINX_NETWORK" ]; then echo "找到Nginx容器的网络: $NGINX_NETWORK" DOCKER_NETWORK=$NGINX_NETWORK fi fi # 设置变量 DOMAIN="gitea.mzh.one" MYSQL_ROOT_PASSWORD="" GITEA_DB_PASSWORD="gitea_password" INSTALL_DIR="/opt/gitea" NGINX_CONF_DIR="$CONF_MOUNT" SSL_DIR="$SSL_MOUNT/$DOMAIN" WWW_DIR="$WWW_MOUNT" # 询问MySQL root密码 read -sp "请输入MySQL root密码: " MYSQL_ROOT_PASSWORD echo "" # 询问Gitea数据库密码 read -sp "请输入Gitea数据库密码 [默认: gitea_password]: " INPUT_GITEA_DB_PASSWORD echo "" if [ ! -z "$INPUT_GITEA_DB_PASSWORD" ]; then GITEA_DB_PASSWORD=$INPUT_GITEA_DB_PASSWORD fi # 询问安装目录 read -p "请输入安装目录 [默认: $INSTALL_DIR]: " INPUT_INSTALL_DIR if [ ! -z "$INPUT_INSTALL_DIR" ]; then INSTALL_DIR=$INPUT_INSTALL_DIR fi # 创建安装目录 echo "创建安装目录: $INSTALL_DIR" mkdir -p $INSTALL_DIR cd $INSTALL_DIR # 创建项目结构 echo "创建项目结构..." mkdir -p conf/nginx/conf.d conf/gitea data/gitea data/mysql # 创建docker-compose.yml echo "创建docker-compose.yml..." cat > docker-compose.yml < conf/nginx/conf.d/$DOMAIN.conf < conf/gitea/app.ini < create_db.sql <&2 exit 1 fi # 检查是否存在冲突的配置文件 echo "检查是否存在冲突的配置文件..." CONFLICT_FILES=$(grep -l "server_name $DOMAIN" $NGINX_CONF_DIR/*.conf 2>/dev/null || true) if [ ! -z "$CONFLICT_FILES" ]; then echo "警告: 发现可能与 $DOMAIN 冲突的配置文件:" echo "$CONFLICT_FILES" read -p "是否删除这些文件?[y/N]: " DELETE_CONFLICT if [ "$DELETE_CONFLICT" == "y" ] || [ "$DELETE_CONFLICT" == "Y" ]; then for file in $CONFLICT_FILES; do if [ "$file" != "$NGINX_CONF_DIR/$DOMAIN.conf" ]; then echo "删除冲突文件: $file" rm -f "$file" fi done else echo "请手动解决配置文件冲突,否则可能导致Nginx配置错误" fi fi # 申请SSL证书 echo "申请SSL证书..." mkdir -p $WWW_DIR/.well-known/acme-challenge chmod -R 755 $WWW_DIR # 创建一个测试文件,确保路径配置正确 echo "test" > $WWW_DIR/.well-known/acme-challenge/test echo "请访问 http://$DOMAIN/.well-known/acme-challenge/test 确认是否返回 'test'" echo "如果无法访问,请检查Nginx配置和域名解析" read -p "按回车键继续..." CONTINUE # 申请证书 certbot certonly --webroot -w $WWW_DIR -d $DOMAIN CERT_STATUS=$? # 创建SSL证书目录 echo "创建SSL证书目录..." mkdir -p $SSL_DIR if [ $CERT_STATUS -ne 0 ]; then echo "警告: 申请SSL证书失败,将使用自签名证书" # 生成自签名证书 echo "生成自签名证书..." openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout $SSL_DIR/$DOMAIN.key \ -out $SSL_DIR/$DOMAIN.pem \ -subj "/CN=$DOMAIN" else # 复制SSL证书 echo "复制SSL证书..." cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem $SSL_DIR/$DOMAIN.pem cp /etc/letsencrypt/live/$DOMAIN/privkey.pem $SSL_DIR/$DOMAIN.key fi # 设置证书权限 chmod 644 $SSL_DIR/$DOMAIN.pem chmod 600 $SSL_DIR/$DOMAIN.key # 复制Nginx配置到DNMP echo "复制Nginx配置到DNMP..." mkdir -p $NGINX_CONF_DIR cp conf/nginx/conf.d/$DOMAIN.conf $NGINX_CONF_DIR/ # 启动Gitea服务 echo "启动Gitea服务..." docker-compose up -d # 等待Gitea容器启动 echo "等待Gitea容器启动..." sleep 5 # 获取Gitea容器IP地址 GITEA_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' gitea) if [ ! -z "$GITEA_IP" ]; then echo "Gitea容器IP地址: $GITEA_IP" # 更新Nginx配置,使用IP地址而不是主机名 sed -i "s/proxy_pass http:\/\/\\\$upstream:3000;/proxy_pass http:\/\/$GITEA_IP:3000;/" $NGINX_CONF_DIR/$DOMAIN.conf sed -i "/resolver 127.0.0.11/d" $NGINX_CONF_DIR/$DOMAIN.conf sed -i "/set \\\$upstream gitea;/d" $NGINX_CONF_DIR/$DOMAIN.conf fi # 重新加载Nginx配置 echo "重新加载Nginx配置..." docker exec -it $NGINX_CONTAINER nginx -t && docker exec -it $NGINX_CONTAINER nginx -s reload if [ $? -ne 0 ]; then echo "警告: Nginx配置测试失败,请检查配置文件" docker exec -it $NGINX_CONTAINER cat /var/log/nginx/error.log | tail -n 20 # 如果使用IP地址仍然失败,尝试添加hosts映射 echo "尝试添加hosts映射..." docker exec -it $NGINX_CONTAINER bash -c "echo '$GITEA_IP gitea' >> /etc/hosts" # 恢复使用主机名的配置 sed -i "s/proxy_pass http:\/\/$GITEA_IP:3000;/proxy_pass http:\/\/gitea:3000;/" $NGINX_CONF_DIR/$DOMAIN.conf # 再次重新加载Nginx配置 docker exec -it $NGINX_CONTAINER nginx -s reload if [ $? -ne 0 ]; then echo "警告: Nginx配置仍然失败,请手动检查配置" read -p "是否继续?[y/N]: " CONTINUE_NGINX if [ "$CONTINUE_NGINX" != "y" ] && [ "$CONTINUE_NGINX" != "Y" ]; then echo "安装已中断" exit 1 fi fi fi echo "===== Gitea安装完成 =====" echo "请访问 https://$DOMAIN 完成初始化设置" echo "初始化时,请使用以下数据库设置:" echo "数据库类型:MySQL" echo "主机:$MYSQL_CONTAINER_NAME:3306" echo "用户名:gitea" echo "密码:$GITEA_DB_PASSWORD" echo "数据库名:gitea" echo "注意:首次访问时,您将被引导完成Gitea的初始化设置,包括创建管理员账户"