Incus-Gitea/gitea
2025-03-18 20:12:55 -04:00

315 lines
9.1 KiB
Bash
Executable File

#!/bin/bash
set -e
CONTAINER_NAME="gitea"
HTTP_PORT="80"
HTTPS_PORT="443"
SSH_PORT="2222"
PROFILE_NAME="gitea-profile"
ROOT_DISK_SIZE="20GB"
NETWORK_NAME="incusbr0"
DB_USER="gitea"
DB_PASS="gitea_password" # Default password, can be overridden with -p option
# Add this near the top of your script
handle_error() {
echo "ERROR: $1" >&2
exit 1
}
# Near the top of your script after setting default variables
if [ -f .env ]; then
echo "Loading configuration from .env file..."
source .env
fi
# Function to create the Incus profile
create_profile() {
local cpu=$1
local ram=$2
echo "Creating Incus profile with root disk size of $ROOT_DISK_SIZE..."
incus profile create $PROFILE_NAME || true
echo "Recommended RAM allocation for Gitea: at least 2GB"
echo "Recommended CPU allocation: at least 2 cores"
# Then set reasonable defaults if not specified
if [ -z "$ram" ]; then
ram=2
echo "Setting default RAM to ${ram}GB"
fi
if [ -z "$cpu" ]; then
cpu=2
echo "Setting default CPU to $cpu cores"
fi
incus profile set $PROFILE_NAME limits.memory=${ram}GB
incus profile set $PROFILE_NAME limits.cpu=$cpu
incus profile device add $PROFILE_NAME root disk path=/ pool=default size=$ROOT_DISK_SIZE
echo "Ensuring network exists..."
if ! incus network list | grep -q $NETWORK_NAME; then
echo "Creating network $NETWORK_NAME..."
incus network create $NETWORK_NAME
fi
}
# Function to check if profile exists
profile_exists() {
incus profile list | grep -q $PROFILE_NAME
}
# Function to install Gitea and PostgreSQL using Docker Compose
install_gitea() {
if ! profile_exists; then
echo "Error: Profile does not exist. Please create a profile first using '$0 profile'."
exit 1
fi
# Ask for the domain name
read -p "Enter your domain name (e.g., gitea.example.com): " DOMAIN_NAME
echo "Creating Incus container..."
incus launch images:ubuntu/22.04 $CONTAINER_NAME -p $PROFILE_NAME
echo "Attaching network to container..."
incus network attach $NETWORK_NAME $CONTAINER_NAME
echo "Configuring container..."
incus config set $CONTAINER_NAME security.nesting=true
incus config set $CONTAINER_NAME linux.kernel_modules=overlay,nf_nat
incus config device add $CONTAINER_NAME gitea-ssh proxy listen=tcp:0.0.0.0:$SSH_PORT connect=tcp:127.0.0.1:22
incus config device add $CONTAINER_NAME gitea-http proxy listen=tcp:0.0.0.0:$HTTP_PORT connect=tcp:127.0.0.1:80
incus config device add $CONTAINER_NAME gitea-https proxy listen=tcp:0.0.0.0:$HTTPS_PORT connect=tcp:127.0.0.1:443
incus config device add $CONTAINER_NAME gitea-data disk source=/path/to/host/storage path=/var/lib/gitea
incus config device add $CONTAINER_NAME postgres-data disk source=/path/to/host/postgres path=/var/lib/postgresql/data
echo "Waiting for network to be ready..."
sleep 10
echo "Installing Docker and Docker Compose..."
incus exec $CONTAINER_NAME -- bash -c "
apt update
apt install -y docker.io docker-compose nginx certbot python3-certbot-nginx
"
echo "Creating Docker Compose file..."
incus exec $CONTAINER_NAME -- bash -c "cat > /root/docker-compose.yml << EOL
version: '3'
networks:
gitea:
external: false
services:
server:
image: gitea/gitea:latest
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- DB_TYPE=postgres
- DB_HOST=db:5432
- DB_NAME=gitea
- DB_USER=$DB_USER
- DB_PASSWD=$DB_PASS
restart: always
networks:
- gitea
volumes:
- /var/lib/gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- '3000:3000'
- '22:22'
depends_on:
- db
db:
image: postgres:latest
restart: always
environment:
- POSTGRES_USER=$DB_USER
- POSTGRES_PASSWORD=$DB_PASS
- POSTGRES_DB=gitea
networks:
- gitea
volumes:
- /var/lib/postgresql/data:/var/lib/postgresql/data
EOL"
echo "Creating Nginx configuration..."
incus exec $CONTAINER_NAME -- bash -c "cat > /etc/nginx/sites-available/gitea << EOL
server {
listen 80;
server_name $DOMAIN_NAME;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host \\\$host;
proxy_set_header X-Real-IP \\\$remote_addr;
}
}
EOL"
echo "Enabling Nginx configuration..."
incus exec $CONTAINER_NAME -- bash -c "
ln -s /etc/nginx/sites-available/gitea /etc/nginx/sites-enabled/
rm /etc/nginx/sites-enabled/default
nginx -t && systemctl reload nginx
"
echo "Starting Gitea and PostgreSQL with Docker Compose..."
incus exec $CONTAINER_NAME -- bash -c "
cd /root
docker-compose up -d
"
echo "Waiting for Gitea to start..."
for i in {1..30}; do
if incus exec $CONTAINER_NAME -- curl -s http://localhost:3000 > /dev/null; then
echo "Gitea is running!"
break
fi
echo -n "."
sleep 2
if [ $i -eq 30 ]; then
echo "Gitea didn't start properly. Check logs with: incus exec $CONTAINER_NAME -- docker-compose logs"
fi
done
echo "Configuring SSL with Certbot..."
incus exec $CONTAINER_NAME -- certbot --nginx -d $DOMAIN_NAME --non-interactive --agree-tos --email admin@$DOMAIN_NAME
echo "Copying custom files to Gitea data directory..."
incus exec $CONTAINER_NAME -- bash -c "
mkdir -p /var/lib/gitea/templates
mkdir -p /var/lib/gitea/public/assets/img
"
incus file push custom/templates/* ${CONTAINER_NAME}/var/lib/gitea/templates/
incus file push custom/public/assets/img/* ${CONTAINER_NAME}/var/lib/gitea/public/assets/img/
echo "Setting correct permissions for custom files..."
incus exec $CONTAINER_NAME -- bash -c "
chown -R 1000:1000 /var/lib/gitea/templates
chown -R 1000:1000 /var/lib/gitea/public
chmod -R 755 /var/lib/gitea/templates
chmod -R 755 /var/lib/gitea/public
"
echo "Restarting Gitea to apply custom files..."
incus exec $CONTAINER_NAME -- docker-compose -f /root/docker-compose.yml restart server
CONTAINER_IP=$(incus exec $CONTAINER_NAME -- ip addr show eth0 | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)
echo "Gitea setup complete!"
echo "Access Gitea at https://$DOMAIN_NAME"
echo "SSH access available on port $SSH_PORT"
echo ""
echo "Important: Make sure your domain ($DOMAIN_NAME) is pointed to this server's IP address: $CONTAINER_IP"
}
# Add a backup function
backup_gitea() {
echo "Creating backup of Gitea data..."
BACKUP_DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="./backups/$BACKUP_DATE"
mkdir -p $BACKUP_DIR
# Export container data
incus exec $CONTAINER_NAME -- bash -c "cd /root && docker-compose stop"
incus file pull $CONTAINER_NAME/var/lib/gitea $BACKUP_DIR/gitea-data
incus file pull $CONTAINER_NAME/var/lib/postgresql/data $BACKUP_DIR/postgres-data
incus exec $CONTAINER_NAME -- bash -c "cd /root && docker-compose start"
echo "Backup completed: $BACKUP_DIR"
}
# Add an update function
update_gitea() {
echo "Updating Gitea..."
incus exec $CONTAINER_NAME -- bash -c "cd /root && docker-compose pull && docker-compose up -d"
echo "Gitea has been updated to the latest version."
}
# Function to display usage
usage() {
echo "Usage"
echo "Create profile:"
echo "$0 profile [-c cpu] [-r ram]"
echo ""
echo "Install Gitea and PostgreSQL:"
echo "$0 install [-p dbpassword]"
}
# Main script logic
case "$1" in
profile)
shift
cpu=""
ram=""
while getopts ":c:r:" opt; do
case ${opt} in
c )
cpu=$OPTARG
;;
r )
ram=$OPTARG
;;
\? )
echo "Invalid option: $OPTARG" 1>&2
usage
exit 1
;;
: )
echo "Invalid option: $OPTARG requires an argument" 1>&2
usage
exit 1
;;
esac
done
create_profile $cpu $ram
;;
install)
shift
while getopts ":p:" opt; do
case ${opt} in
p )
DB_PASS=$OPTARG
;;
\? )
echo "Invalid option: $OPTARG" 1>&2
usage
exit 1
;;
: )
echo "Invalid option: $OPTARG requires an argument" 1>&2
usage
exit 1
;;
esac
done
if [ -z "$DB_PASS" ]; then
DB_PASS=$(openssl rand -base64 16)
echo "Generated random database password: $DB_PASS"
echo "Please save this password in a secure location."
fi
install_gitea
;;
backup)
backup_gitea
;;
update)
update_gitea
;;
*)
usage
exit 1
;;
esac
exit 0