Update README and add LXC deployment guide; enhance LXC installer scripts

This commit is contained in:
Arunavo Ray
2025-05-22 08:53:19 +05:30
parent a15178d2cd
commit 5bf52c806f
4 changed files with 313 additions and 245 deletions

View File

@@ -19,11 +19,15 @@ docker compose --profile production up -d
# Using Bun # Using Bun
bun run setup && bun run dev bun run setup && bun run dev
# Using LXC on Proxmox # Using LXC Containers
# For Proxmox VE (online)
curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-installer.sh | bash curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-installer.sh | bash
# For local testing (offline-friendly)
sudo LOCAL_REPO_DIR=~/Development/gitea-mirror ./scripts/gitea-mirror-lxc-local.sh
```` ````
See the [LXC Container Deployment Guide](scripts/README-lxc.md). See the [LXC Container Deployment Guide](docs/LXC.md).
<p align="center"> <p align="center">
<img src=".github/assets/dashboard.png" alt="Dashboard" width="80%"/> <img src=".github/assets/dashboard.png" alt="Dashboard" width="80%"/>
@@ -163,23 +167,39 @@ docker compose --profile production up -d
See [Docker build documentation](./scripts/README-docker.md) for more details. See [Docker build documentation](./scripts/README-docker.md) for more details.
##### Using LXC Containers (for Proxmox Homelab Setups) ##### Using LXC Containers
Gitea Mirror can be deployed on Proxmox LXC containers, which is ideal for homelab setups: Gitea Mirror offers two deployment options for LXC containers:
**1. Proxmox VE (online, recommended for production)**
```bash ```bash
# One-command installation on an Ubuntu 22.04 LXC container # One-command installation on Proxmox VE
# Optional env overrides: CTID HOSTNAME STORAGE DISK_SIZE CORES MEMORY BRIDGE IP_CONF
curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-installer.sh | bash curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-installer.sh | bash
``` ```
The installer script: **2. Local testing (offline-friendly, works on developer laptops)**
- Downloads the Gitea Mirror repository
- Installs all dependencies including Bun
- Builds the application
- Sets up a systemd service
- Starts the application
See the [LXC Container Deployment Guide](scripts/README-lxc.md) for detailed instructions. ```bash
# Download the script
curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-local.sh -o gitea-mirror-lxc-local.sh
chmod +x gitea-mirror-lxc-local.sh
# Run with your local repo directory
sudo LOCAL_REPO_DIR=~/Development/gitea-mirror ./gitea-mirror-lxc-local.sh
```
Both scripts:
- Set up a privileged Ubuntu 22.04 LXC container
- Install Bun runtime environment
- Build the application
- Configure a systemd service
- Start the service automatically
The application includes a health check endpoint at `/api/health` for monitoring.
See the [LXC Container Deployment Guide](docs/LXC.md) for detailed instructions.
##### Building Your Own Image ##### Building Your Own Image
@@ -379,7 +399,7 @@ docker compose -f docker-compose.dev.yml up -d
- **Backend**: Bun - **Backend**: Bun
- **Database**: SQLite (handles both data storage and event notifications) - **Database**: SQLite (handles both data storage and event notifications)
- **API Integration**: GitHub API (Octokit), Gitea API - **API Integration**: GitHub API (Octokit), Gitea API
- **Deployment Options**: Docker containers, Proxmox LXC containers - **Deployment Options**: Docker containers, LXC containers (Proxmox VE and local testing)
## Contributing ## Contributing

131
docs/LXC.md Normal file
View File

@@ -0,0 +1,131 @@
# LXC Container Deployment Guide
## Overview
Run **Gitea Mirror** in an isolated LXC container, either:
1. **Online, on a Proxmox VE host** script pulls everything from GitHub
2. **Offline / LAN-only, on a developer laptop** script pushes your local checkout + Bun ZIP
---
## 1. Proxmox VE (online, recommended for prod)
### Prerequisites
* Proxmox VE node with the default `vmbr0` bridge
* Root shell on the node
* Ubuntu 22.04 LXC template present (`pveam update && pveam download ...`)
### One-command install
```bash
# optional env overrides: CTID HOSTNAME STORAGE DISK_SIZE CORES MEMORY BRIDGE IP_CONF
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-installer.sh)"
```
What it does:
* Creates **privileged** CT `$CTID` with nesting enabled
* Installs curl / git / Bun (official installer)
* Clones & builds `arunavo4/gitea-mirror`
* Writes a root-run systemd service and starts it
* Prints the container IP + random `JWT_SECRET`
Browse to:
```
http://<container-ip>:4321
```
---
## 2. Local testing (LXD on a workstation, works offline)
### Prerequisites
* `lxd` installed (`sudo apt install lxd`; `lxd init --auto`)
* Your repo cloned locally e.g. `~/Development/gitea-mirror`
* Bun ZIP downloaded once:
`https://github.com/oven-sh/bun/releases/latest/download/bun-linux-x64.zip`
### Offline installer script
```bash
git clone https://github.com/arunavo4/gitea-mirror.git # if not already
curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-local.sh -o gitea-mirror-lxc-local.sh
chmod +x gitea-mirror-lxc-local.sh
sudo LOCAL_REPO_DIR=~/Development/gitea-mirror \
./gitea-mirror-lxc-local.sh
```
What it does:
* Launches privileged LXC `gitea-test` (`lxc launch ubuntu:22.04 ...`)
* Pushes **Bun ZIP** + tarred **local repo** into `/opt`
* Unpacks, builds, initializes DB
* Symlinks both `bun` and `bunx``/usr/local/bin`
* Creates a root systemd unit and starts it
Access from host:
```
http://$(lxc exec gitea-test -- hostname -I | awk '{print $1}'):4321
```
(Optional) forward to host localhost:
```bash
sudo lxc config device add gitea-test mirror proxy \
listen=tcp:0.0.0.0:4321 connect=tcp:127.0.0.1:4321
```
---
## Health-check endpoint
Gitea Mirror includes a built-in health check endpoint at `/api/health` that provides:
- System status and uptime
- Database connectivity check
- Memory usage statistics
- Environment information
You can use this endpoint for monitoring your deployment:
```bash
# Basic check (returns 200 OK if healthy)
curl -I http://<container-ip>:4321/api/health
# Detailed health information (JSON)
curl http://<container-ip>:4321/api/health
```
---
## Troubleshooting
| Check | Command |
| -------------- | ----------------------------------------------------- |
| Service status | `systemctl status gitea-mirror` |
| Live logs | `journalctl -u gitea-mirror -f` |
| Verify Bun | `bun --version && bunx --version` |
| DB perms | `chown -R root:root /opt/gitea-mirror/data` (Proxmox) |
---
## Connecting LXC and Docker Containers
If you need your LXC container to communicate with Docker containers:
1. On your host machine, create a bridge network:
```bash
docker network create gitea-network
```
2. Find the bridge interface created by Docker:
```bash
ip a | grep docker
# Look for something like docker0 or br-xxxxxxxx
```
3. In Proxmox, edit the LXC container's network configuration to use this bridge.

View File

@@ -1,266 +1,97 @@
#!/bin/bash #!/usr/bin/env bash
# Gitea Mirror LXC Container Installer # gitea-mirror-proxmox.sh
# This is a self-contained script to install Gitea Mirror in an LXC container # Fully online installer for a Proxmox LXC guest running Gitea Mirror + Bun.
# Usage: curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-installer.sh | bash
set -e set -euo pipefail
# ────── adjustable defaults ──────────────────────────────────────────────
CTID=${CTID:-106} # container ID
HOSTNAME=${HOSTNAME:-gitea-mirror}
STORAGE=${STORAGE:-local-lvm} # where rootfs lives
DISK_SIZE=${DISK_SIZE:-8G}
CORES=${CORES:-2}
MEMORY=${MEMORY:-2048} # MiB
BRIDGE=${BRIDGE:-vmbr0}
IP_CONF=${IP_CONF:-dhcp} # or "192.168.1.240/24,gw=192.168.1.1"
# Configuration variables - change these as needed
INSTALL_DIR="/opt/gitea-mirror"
REPO_URL="https://github.com/arunavo4/gitea-mirror.git"
SERVICE_USER="gitea-mirror"
PORT=4321 PORT=4321
JWT_SECRET=$(openssl rand -hex 32)
# Color codes for better readability REPO="https://github.com/arunavo4/gitea-mirror.git"
RED='\033[0;31m' # ─────────────────────────────────────────────────────────────────────────
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Print banner TEMPLATE='ubuntu-22.04-standard_22.04-1_amd64.tar.zst'
echo -e "${BLUE}" TEMPLATE_PATH="/var/lib/vz/template/cache/${TEMPLATE}"
echo "╔════════════════════════════════════════════════════════════╗"
echo "║ ║"
echo "║ Gitea Mirror LXC Container Installer ║"
echo "║ ║"
echo "╚════════════════════════════════════════════════════════════╝"
echo -e "${NC}"
# Ensure script is run as root echo "▶️ Ensuring template exists…"
if [ "$(id -u)" -ne 0 ]; then if [[ ! -f $TEMPLATE_PATH ]]; then
echo -e "${RED}This script must be run as root${NC}" >&2 pveam update >/dev/null
exit 1 pveam download "$STORAGE" "$TEMPLATE"
fi fi
echo -e "${GREEN}Starting Gitea Mirror installation...${NC}" echo "▶️ Creating container $CTID (if missing)…"
if ! pct status "$CTID" &>/dev/null; then
# Check if we're in an LXC container pct create "$CTID" "$TEMPLATE_PATH" \
if [ -d /proc/vz ] && [ ! -d /proc/bc ]; then --rootfs "$STORAGE:$DISK_SIZE" \
echo -e "${YELLOW}Running in an OpenVZ container. Some features may not work.${NC}" --hostname "$HOSTNAME" \
elif [ -f /proc/1/environ ] && grep -q container=lxc /proc/1/environ; then --cores "$CORES" --memory "$MEMORY" \
echo -e "${GREEN}Running in an LXC container. Good!${NC}" --net0 "name=eth0,bridge=$BRIDGE,ip=$IP_CONF" \
else --features nesting=1 \
echo -e "${YELLOW}Not running in a container. This script is designed for LXC containers.${NC}" --unprivileged 0
read -p "Continue anyway? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${RED}Installation aborted.${NC}"
exit 1
fi
fi fi
# Install dependencies pct start "$CTID"
echo -e "${BLUE}Step 1/7: Installing dependencies...${NC}"
apt update
apt install -y curl git sqlite3 build-essential openssl
# Create service user echo "▶️ Installing base packages inside CT $CTID"
echo -e "${BLUE}Step 2/7: Creating service user...${NC}" pct exec "$CTID" -- bash -c 'apt update && apt install -y curl git build-essential openssl sqlite3 unzip'
if id "$SERVICE_USER" &>/dev/null; then
echo -e "${YELLOW}User $SERVICE_USER already exists${NC}"
else
useradd -m -s /bin/bash "$SERVICE_USER"
echo -e "${GREEN}Created user $SERVICE_USER${NC}"
fi
# Install Bun echo "▶️ Installing Bun runtime…"
echo -e "${BLUE}Step 3/7: Installing Bun runtime...${NC}" pct exec "$CTID" -- bash -c '
if command -v bun >/dev/null 2>&1; then export BUN_INSTALL=/opt/bun
echo -e "${YELLOW}Bun is already installed${NC}" curl -fsSL https://bun.sh/install | bash -s -- --yes
ln -sf /opt/bun/bin/bun /usr/local/bin/bun
ln -sf /opt/bun/bin/bun /usr/local/bin/bunx
bun --version bun --version
else '
echo -e "${GREEN}Installing Bun...${NC}"
# Install Bun globally to make it accessible to all users
curl -fsSL https://bun.sh/install | bash
export BUN_INSTALL=${BUN_INSTALL:-"/root/.bun"}
export PATH="$BUN_INSTALL/bin:$PATH"
# Make Bun accessible to all users by creating a symlink in /usr/local/bin echo "▶️ Cloning & building Gitea Mirror…"
echo -e "${GREEN}Making Bun accessible to all users...${NC}" pct exec "$CTID" -- bash -c "
git clone --depth=1 '$REPO' /opt/gitea-mirror || (cd /opt/gitea-mirror && git pull)
# Check if /usr/local/bin is writable cd /opt/gitea-mirror
if [ ! -w /usr/local/bin ]; then bun install
echo -e "${RED}Error: /usr/local/bin is not writable. Please run the script as root or with sufficient permissions.${NC}" bun run build
exit 1
fi
ln -sf "$BUN_INSTALL/bin/bun" /usr/local/bin/bun
if [ $? -ne 0 ]; then
echo -e "${RED}Error: Failed to create symlink for Bun in /usr/local/bin.${NC}"
exit 1
fi
echo -e "${GREEN}Bun installed successfully${NC}"
bun --version
fi
# Clone repository
echo -e "${BLUE}Step 4/7: Downloading Gitea Mirror...${NC}"
if [ -d "$INSTALL_DIR" ]; then
echo -e "${YELLOW}Directory $INSTALL_DIR already exists${NC}"
read -p "Update existing installation? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
cd "$INSTALL_DIR"
git pull
echo -e "${GREEN}Repository updated${NC}"
else
echo -e "${YELLOW}Using existing installation${NC}"
fi
else
echo -e "${GREEN}Cloning repository...${NC}"
git clone "$REPO_URL" "$INSTALL_DIR"
echo -e "${GREEN}Repository cloned to $INSTALL_DIR${NC}"
fi
# Set up application
echo -e "${BLUE}Step 5/7: Setting up application...${NC}"
cd "$INSTALL_DIR"
# Create data directory with proper permissions
mkdir -p data
chown -R "$SERVICE_USER:$SERVICE_USER" data
# Ensure the application directory has the right permissions
echo -e "${GREEN}Setting correct permissions for application directory...${NC}"
chown -R "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR"
chmod -R 755 "$INSTALL_DIR"
# Install dependencies and build
echo -e "${GREEN}Installing dependencies and building application...${NC}"
bun install
bun run build
# Initialize database if it doesn't exist
echo -e "${GREEN}Initializing database...${NC}"
if [ ! -f "data/gitea-mirror.db" ]; then
bun run manage-db init bun run manage-db init
chown "$SERVICE_USER:$SERVICE_USER" data/gitea-mirror.db "
fi
# Generate a random JWT secret if not provided
JWT_SECRET=${JWT_SECRET:-$(openssl rand -hex 32)}
# Create systemd service
echo -e "${BLUE}Step 6/7: Creating systemd service...${NC}"
# Store Bun path in a variable for better maintainability
# Use the global Bun path to ensure it's accessible to the service user
BUN_PATH="/usr/local/bin/bun"
echo -e "${GREEN}Using Bun from: $BUN_PATH${NC}"
# Ensure the Bun executable is accessible to the service user
if [ ! -f "$BUN_PATH" ]; then
echo -e "${YELLOW}Bun not found at $BUN_PATH, creating symlink...${NC}"
# Check if /usr/local/bin is writable
if [ ! -w "$(dirname "$BUN_PATH")" ]; then
echo -e "${RED}Error: $(dirname "$BUN_PATH") is not writable. Please run the script as root or with sufficient permissions.${NC}"
exit 1
fi
ln -sf "$(command -v bun)" "$BUN_PATH"
if [ $? -ne 0 ]; then
echo -e "${RED}Error: Failed to create symlink for Bun in $(dirname "$BUN_PATH").${NC}"
exit 1
fi
fi
# Make sure the Bun executable has the right permissions
if [ -f "$BUN_PATH" ]; then
chmod 755 "$BUN_PATH"
fi
echo "▶️ Creating systemd service…"
pct exec "$CTID" -- bash -c "
cat >/etc/systemd/system/gitea-mirror.service <<SERVICE cat >/etc/systemd/system/gitea-mirror.service <<SERVICE
[Unit] [Unit]
Description=Gitea Mirror Description=Gitea Mirror
After=network.target After=network.target
[Service] [Service]
Type=simple Type=simple
WorkingDirectory=$INSTALL_DIR WorkingDirectory=/opt/gitea-mirror
ExecStart=$BUN_PATH dist/server/entry.mjs ExecStart=/usr/local/bin/bun dist/server/entry.mjs
Restart=on-failure Restart=on-failure
RestartSec=10 RestartSec=10
User=$SERVICE_USER
Group=$SERVICE_USER
Environment=NODE_ENV=production Environment=NODE_ENV=production
Environment=HOST=0.0.0.0 Environment=HOST=0.0.0.0
Environment=PORT=$PORT Environment=PORT=$PORT
Environment=DATABASE_URL=file:data/gitea-mirror.db Environment=DATABASE_URL=file:data/gitea-mirror.db
Environment=JWT_SECRET=${JWT_SECRET} Environment=JWT_SECRET=$JWT_SECRET
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
SERVICE SERVICE
# Verify that the service user can access Bun
echo -e "${BLUE}Verifying Bun permissions...${NC}"
if su - "$SERVICE_USER" -c "$BUN_PATH --version" &>/dev/null; then
echo -e "${GREEN}Bun is accessible to $SERVICE_USER user${NC}"
else
echo -e "${YELLOW}Warning: $SERVICE_USER cannot access Bun. Fixing permissions...${NC}"
# Make sure the Bun binary and its directory are accessible
BUN_DIR="$(dirname "$BUN_PATH")"
if [ -d "$BUN_DIR" ]; then
chmod 755 "$BUN_DIR"
fi
if [ -f "$BUN_PATH" ]; then
chmod 755 "$BUN_PATH"
fi
# Check again
if su - "$SERVICE_USER" -c "$BUN_PATH --version" &>/dev/null; then
echo -e "${GREEN}Fixed: Bun is now accessible to $SERVICE_USER user${NC}"
else
echo -e "${RED}Warning: $SERVICE_USER still cannot access Bun. Service may fail to start.${NC}"
fi
fi
# Start service
echo -e "${BLUE}Step 7/7: Starting service...${NC}"
systemctl daemon-reload systemctl daemon-reload
systemctl enable gitea-mirror.service systemctl enable gitea-mirror
systemctl start gitea-mirror.service systemctl restart gitea-mirror
"
# Check if service started successfully echo -e "\n🔍 Service status:"
if systemctl is-active --quiet gitea-mirror.service; then pct exec "$CTID" -- systemctl status gitea-mirror --no-pager | head -n15
echo -e "${GREEN}Gitea Mirror service started successfully!${NC}"
else
echo -e "${RED}Failed to start Gitea Mirror service. Check logs with: journalctl -u gitea-mirror${NC}"
exit 1
fi
# Get IP address GUEST_IP=$(pct exec "$CTID" -- hostname -I | awk '{print $1}')
IP_ADDRESS=$(hostname -I | awk '{print $1}') echo -e "\n🌐 Browse to: http://$GUEST_IP:$PORT\n"
echo "🗝️ JWT_SECRET = $JWT_SECRET"
# Print success message echo -e "\n✅ Done Gitea Mirror is running in CT $CTID."
echo -e "${GREEN}"
echo "╔════════════════════════════════════════════════════════════╗"
echo "║ ║"
echo "║ Gitea Mirror Installation Complete ║"
echo "║ ║"
echo "╚════════════════════════════════════════════════════════════╝"
echo -e "${NC}"
echo -e "${GREEN}Gitea Mirror is now running at: http://$IP_ADDRESS:$PORT${NC}"
echo
echo -e "${YELLOW}Important security information:${NC}"
echo -e "JWT_SECRET: ${JWT_SECRET}"
echo -e "${YELLOW}Please save this JWT_SECRET in a secure location.${NC}"
echo
echo -e "${BLUE}To check service status:${NC} systemctl status gitea-mirror"
echo -e "${BLUE}To view logs:${NC} journalctl -u gitea-mirror -f"
echo -e "${BLUE}Data directory:${NC} $INSTALL_DIR/data"
echo
echo -e "${YELLOW}Troubleshooting:${NC}"
echo -e "If you encounter permission issues with Bun, try the following:"
echo -e "1. Check if Bun is accessible: ${BLUE}su - $SERVICE_USER -c \"$BUN_PATH --version\"${NC}"
echo -e "2. Fix permissions: ${BLUE}chmod 755 $BUN_PATH${NC}"
echo -e "3. Create a symlink: ${BLUE}ln -sf \$(command -v bun) /usr/local/bin/bun${NC}"
echo -e "4. Restart the service: ${BLUE}systemctl restart gitea-mirror${NC}"
echo
echo -e "${GREEN}Thank you for installing Gitea Mirror!${NC}"

View File

@@ -0,0 +1,86 @@
#!/usr/bin/env bash
# gitea-mirror-lxc-local.sh (offline, local repo, verbose)
set -euo pipefail
CONTAINER="gitea-test"
IMAGE="ubuntu:22.04"
INSTALL_DIR="/opt/gitea-mirror"
PORT=4321
JWT_SECRET="$(openssl rand -hex 32)"
BUN_ZIP="/tmp/bun-linux-x64.zip"
BUN_URL="https://github.com/oven-sh/bun/releases/latest/download/bun-linux-x64.zip"
LOCAL_REPO_DIR="${LOCAL_REPO_DIR:-./gitea-mirror}"
REPO_TAR="/tmp/gitea-mirror-local.tar.gz"
need() { command -v "$1" >/dev/null || { echo "Missing $1"; exit 1; }; }
need curl; need lxc; need tar; need unzip
# ── build host artefacts ────────────────────────────────────────────────
[[ -d $LOCAL_REPO_DIR ]] || { echo "❌ LOCAL_REPO_DIR not found"; exit 1; }
[[ -f $LOCAL_REPO_DIR/package.json ]] || { echo "❌ package.json missing"; exit 1; }
[[ -f $BUN_ZIP ]] || curl -L --retry 5 --retry-delay 5 -o "$BUN_ZIP" "$BUN_URL"
tar -czf "$REPO_TAR" -C "$(dirname "$LOCAL_REPO_DIR")" "$(basename "$LOCAL_REPO_DIR")"
# ── ensure container exists ─────────────────────────────────────────────
lxd init --auto >/dev/null 2>&1 || true
lxc info "$CONTAINER" >/dev/null 2>&1 || lxc launch "$IMAGE" "$CONTAINER"
echo "🔧 installing base packages…"
sudo lxc exec "$CONTAINER" -- bash -c 'set -ex; apt update; apt install -y unzip tar openssl sqlite3'
echo "⬆️ pushing artefacts…"
sudo lxc file push "$BUN_ZIP" "$CONTAINER/opt/"
sudo lxc file push "$REPO_TAR" "$CONTAINER/opt/"
echo "📦 unpacking Bun + repo…"
sudo lxc exec "$CONTAINER" -- bash -ex <<'IN'
cd /opt
# Bun
unzip -oq bun-linux-x64.zip -d bun
BIN=$(find /opt/bun -type f -name bun -perm -111 | head -n1)
ln -sf "$BIN" /usr/local/bin/bun # bun
ln -sf "$BIN" /usr/local/bin/bunx # bunx shim
# Repo
rm -rf /opt/gitea-mirror
mkdir -p /opt/gitea-mirror
tar -xzf gitea-mirror-local.tar.gz --strip-components=1 -C /opt/gitea-mirror
IN
echo "🏗️ bun install / build…"
sudo lxc exec "$CONTAINER" -- bash -ex <<'IN'
cd /opt/gitea-mirror
bun install
bun run build
bun run manage-db init
IN
echo "📝 systemd unit…"
sudo lxc exec "$CONTAINER" -- bash -ex <<IN
cat >/etc/systemd/system/gitea-mirror.service <<SERVICE
[Unit]
Description=Gitea Mirror
After=network.target
[Service]
Type=simple
WorkingDirectory=$INSTALL_DIR
ExecStart=/usr/local/bin/bun dist/server/entry.mjs
Restart=on-failure
RestartSec=10
Environment=NODE_ENV=production
Environment=HOST=0.0.0.0
Environment=PORT=$PORT
Environment=DATABASE_URL=file:data/gitea-mirror.db
Environment=JWT_SECRET=$JWT_SECRET
[Install]
WantedBy=multi-user.target
SERVICE
systemctl daemon-reload
systemctl enable gitea-mirror
systemctl restart gitea-mirror
IN
echo -e "\n✅ finished; service status:"
sudo lxc exec "$CONTAINER" -- systemctl status gitea-mirror --no-pager