GiteaDocker/install.sh

461 lines
13 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 <<EOF
version: '3'
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=mysql
- GITEA__database__HOST=$MYSQL_CONTAINER_NAME:3306
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=$GITEA_DB_PASSWORD
- GITEA__server__DOMAIN=$DOMAIN
- GITEA__server__ROOT_URL=https://$DOMAIN/
restart: always
volumes:
- ./data/gitea:/data
- ./conf/gitea/app.ini:/data/gitea/conf/app.ini:ro
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
networks:
- $DOCKER_NETWORK
networks:
$DOCKER_NETWORK:
external: true
EOF
# 创建Nginx配置
echo "创建Nginx配置..."
cat > conf/nginx/conf.d/$DOMAIN.conf <<EOF
server {
listen 80;
server_name $DOMAIN;
# 将HTTP请求重定向到HTTPS
location / {
return 301 https://\$host\$request_uri;
}
# Let's Encrypt验证路径
location /.well-known/acme-challenge/ {
root /www;
}
}
server {
listen 443 ssl;
http2 on;
server_name $DOMAIN;
# SSL证书配置
ssl_certificate /ssl/$DOMAIN/$DOMAIN.pem;
ssl_certificate_key /ssl/$DOMAIN/$DOMAIN.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# 反向代理到Gitea服务
location / {
# 使用容器IP而不是主机名避免DNS解析问题
resolver 127.0.0.11 valid=30s;
set \$upstream gitea;
proxy_pass http://\$upstream:3000;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
# WebSocket支持
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
# 超时设置
proxy_read_timeout 600s;
proxy_connect_timeout 600s;
proxy_send_timeout 600s;
# 缓冲设置
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
# 大文件上传设置
client_max_body_size 512M;
# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
EOF
# 创建Gitea配置
echo "创建Gitea配置..."
# 生成随机密钥
SECRET_KEY=$(openssl rand -hex 16)
INTERNAL_TOKEN=$(openssl rand -hex 16)
LFS_JWT_SECRET=$(openssl rand -hex 16)
cat > conf/gitea/app.ini <<EOF
APP_NAME = Gitea: Git with a cup of tea
RUN_USER = git
RUN_MODE = prod
[repository]
ROOT = /data/git/repositories
[repository.local]
LOCAL_COPY_PATH = /data/gitea/tmp/local-repo
[repository.upload]
TEMP_PATH = /data/gitea/uploads
[server]
APP_DATA_PATH = /data/gitea
DOMAIN = $DOMAIN
SSH_DOMAIN = $DOMAIN
HTTP_PORT = 3000
ROOT_URL = https://$DOMAIN/
DISABLE_SSH = false
SSH_PORT = 22
SSH_LISTEN_PORT = 22
LFS_START_SERVER = true
LFS_CONTENT_PATH = /data/git/lfs
LFS_JWT_SECRET = $LFS_JWT_SECRET
OFFLINE_MODE = false
[database]
PATH = /data/gitea/gitea.db
DB_TYPE = mysql
HOST = $MYSQL_CONTAINER_NAME:3306
NAME = gitea
USER = gitea
PASSWD = $GITEA_DB_PASSWORD
SSL_MODE = disable
CHARSET = utf8mb4
[indexer]
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve
[session]
PROVIDER_CONFIG = /data/gitea/sessions
PROVIDER = file
[picture]
AVATAR_UPLOAD_PATH = /data/gitea/avatars
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
[attachment]
PATH = /data/gitea/attachments
[log]
MODE = console
LEVEL = info
ROOT_PATH = /data/gitea/log
[security]
INSTALL_LOCK = false
SECRET_KEY = $SECRET_KEY
INTERNAL_TOKEN = $INTERNAL_TOKEN
[service]
DISABLE_REGISTRATION = false
REQUIRE_SIGNIN_VIEW = false
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
ENABLE_CAPTCHA = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
DEFAULT_ENABLE_TIMETRACKING = true
NO_REPLY_ADDRESS = noreply.$DOMAIN
[mailer]
ENABLED = false
[openid]
ENABLE_OPENID_SIGNIN = true
ENABLE_OPENID_SIGNUP = true
[ui]
DEFAULT_THEME = auto
THEMES = auto,gitea,arc-green
EOF
# 创建数据库
echo "创建Gitea数据库..."
cat > create_db.sql <<EOF
CREATE DATABASE IF NOT EXISTS gitea CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'gitea'@'%' IDENTIFIED BY '$GITEA_DB_PASSWORD';
GRANT ALL PRIVILEGES ON gitea.* TO 'gitea'@'%';
FLUSH PRIVILEGES;
EOF
docker exec -i $MYSQL_CONTAINER mysql -uroot -p$MYSQL_ROOT_PASSWORD < create_db.sql
if [ $? -ne 0 ]; then
echo "错误: 创建数据库失败请检查MySQL root密码是否正确" 1>&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的初始化设置包括创建管理员账户"