From c896194aebe42d90d1564589f6eaca497b3d2267 Mon Sep 17 00:00:00 2001 From: Arunavo Ray Date: Wed, 21 May 2025 22:19:43 +0530 Subject: [PATCH 01/10] Fix Bun permissions issue in LXC container installer --- scripts/gitea-mirror-lxc-installer.sh | 48 ++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/scripts/gitea-mirror-lxc-installer.sh b/scripts/gitea-mirror-lxc-installer.sh index 4a97e44..9cd9872 100755 --- a/scripts/gitea-mirror-lxc-installer.sh +++ b/scripts/gitea-mirror-lxc-installer.sh @@ -71,9 +71,15 @@ if command -v bun >/dev/null 2>&1; then 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 -e "${GREEN}Making Bun accessible to all users...${NC}" + ln -sf "$BUN_INSTALL/bin/bun" /usr/local/bin/bun + echo -e "${GREEN}Bun installed successfully${NC}" bun --version fi @@ -105,6 +111,11 @@ cd "$INSTALL_DIR" 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 @@ -124,9 +135,19 @@ JWT_SECRET=${JWT_SECRET:-$(openssl rand -hex 32)} echo -e "${BLUE}Step 6/7: Creating systemd service...${NC}" # Store Bun path in a variable for better maintainability -BUN_PATH=$(command -v bun) +# 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}" + ln -sf "$(command -v bun)" "$BUN_PATH" +fi + +# Make sure the Bun executable has the right permissions +chmod 755 "$BUN_PATH" + cat >/etc/systemd/system/gitea-mirror.service </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 + chmod -R 755 "$(dirname "$BUN_PATH")" + chmod 755 "$BUN_PATH" + + # 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 @@ -185,4 +224,11 @@ 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}" From 0cf95b2a0ef7d4f76ffa951114889edc600f5e6b Mon Sep 17 00:00:00 2001 From: Arunavo Ray Date: Wed, 21 May 2025 22:26:50 +0530 Subject: [PATCH 02/10] Improve error handling and permission checks in LXC installer --- scripts/gitea-mirror-lxc-installer.sh | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/scripts/gitea-mirror-lxc-installer.sh b/scripts/gitea-mirror-lxc-installer.sh index 9cd9872..3cc65ac 100755 --- a/scripts/gitea-mirror-lxc-installer.sh +++ b/scripts/gitea-mirror-lxc-installer.sh @@ -78,8 +78,20 @@ else # Make Bun accessible to all users by creating a symlink in /usr/local/bin echo -e "${GREEN}Making Bun accessible to all users...${NC}" + + # Check if /usr/local/bin is writable + if [ ! -w /usr/local/bin ]; then + echo -e "${RED}Error: /usr/local/bin is not writable. Please run the script as root or with sufficient permissions.${NC}" + 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 @@ -146,7 +158,9 @@ if [ ! -f "$BUN_PATH" ]; then fi # Make sure the Bun executable has the right permissions -chmod 755 "$BUN_PATH" +if [ -f "$BUN_PATH" ]; then + chmod 755 "$BUN_PATH" +fi cat >/etc/systemd/system/gitea-mirror.service </dev/null; then else echo -e "${YELLOW}Warning: $SERVICE_USER cannot access Bun. Fixing permissions...${NC}" # Make sure the Bun binary and its directory are accessible - chmod -R 755 "$(dirname "$BUN_PATH")" - chmod 755 "$BUN_PATH" + 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 From 161685b966a50d735448694f30aa25baa4598bbe Mon Sep 17 00:00:00 2001 From: Arunavo Ray Date: Wed, 21 May 2025 22:30:15 +0530 Subject: [PATCH 03/10] Add directory permission check before creating symlink in systemd service setup --- scripts/gitea-mirror-lxc-installer.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/scripts/gitea-mirror-lxc-installer.sh b/scripts/gitea-mirror-lxc-installer.sh index 3cc65ac..4cf2d23 100755 --- a/scripts/gitea-mirror-lxc-installer.sh +++ b/scripts/gitea-mirror-lxc-installer.sh @@ -154,7 +154,19 @@ 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 From 32ef9124a7936ef02d063fc087607205a6b45f7b Mon Sep 17 00:00:00 2001 From: Arunavo Ray Date: Thu, 22 May 2025 08:12:26 +0530 Subject: [PATCH 04/10] Remove sqlite3 dependency from package.json --- bun.lock | 97 ++++++++++++++++++++++++++++++++++++++++------------ package.json | 1 - 2 files changed, 75 insertions(+), 23 deletions(-) diff --git a/bun.lock b/bun.lock index f2641f9..d165a9f 100644 --- a/bun.lock +++ b/bun.lock @@ -40,7 +40,6 @@ "react-dom": "^19.1.0", "react-icons": "^5.5.0", "sonner": "^2.0.3", - "sqlite3": "^5.1.7", "superagent": "^10.2.1", "tailwind-merge": "^3.3.0", "tailwindcss": "^4.1.7", @@ -637,7 +636,7 @@ "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], - "chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="], + "chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], "ci-info": ["ci-info@4.2.0", "", {}, "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg=="], @@ -1187,7 +1186,7 @@ "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], - "minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="], + "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], "minipass-collect": ["minipass-collect@1.0.2", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA=="], @@ -1199,9 +1198,9 @@ "minipass-sized": ["minipass-sized@1.0.3", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g=="], - "minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="], + "minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="], - "mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], + "mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="], "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="], @@ -1491,7 +1490,7 @@ "tapable": ["tapable@2.2.2", "", {}, "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg=="], - "tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="], + "tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="], "tar-fs": ["tar-fs@2.1.2", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA=="], @@ -1643,7 +1642,7 @@ "xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="], - "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + "yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], @@ -1667,7 +1666,7 @@ "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@isaacs/fs-minipass/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], + "@npmcli/move-file/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], "@octokit/plugin-paginate-rest/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="], @@ -1675,8 +1674,6 @@ "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], - "@tailwindcss/oxide/tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.4.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.4.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ=="], @@ -1701,10 +1698,16 @@ "boxen/chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="], + "cacache/chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="], + "cacache/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], "cacache/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "cacache/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], + + "cacache/tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="], + "fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], "gauge/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], @@ -1725,16 +1728,18 @@ "minipass-fetch/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "minipass-fetch/minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="], + "minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], "minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], "minipass-sized/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - "minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - "node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], + "node-gyp/tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="], + "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], @@ -1745,6 +1750,8 @@ "socks-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], + "sqlite3/tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="], + "ssri/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], "strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], @@ -1761,34 +1768,80 @@ "@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], - "@tailwindcss/oxide/tar/chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], - - "@tailwindcss/oxide/tar/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], - - "@tailwindcss/oxide/tar/minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="], - - "@tailwindcss/oxide/tar/mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="], - - "@tailwindcss/oxide/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], - "ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "cacache/lru-cache/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "cacache/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "cacache/tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="], + + "cacache/tar/minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="], + + "cacache/tar/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "fs-minipass/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + "gauge/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "make-fetch-happen/http-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], "make-fetch-happen/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], + "make-fetch-happen/lru-cache/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "make-fetch-happen/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "minipass-collect/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "minipass-fetch/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "minipass-fetch/minizlib/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "minipass-flush/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "minipass-pipeline/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "minipass-sized/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + "node-fetch/whatwg-url/tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], "node-fetch/whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], + "node-gyp/tar/chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="], + + "node-gyp/tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="], + + "node-gyp/tar/minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="], + + "node-gyp/tar/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], + + "node-gyp/tar/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + "send/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + "sqlite3/tar/chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="], + + "sqlite3/tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="], + + "sqlite3/tar/minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="], + + "sqlite3/tar/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], + + "sqlite3/tar/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "ssri/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + "wide-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "wide-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "cacache/tar/minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "node-gyp/tar/minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "sqlite3/tar/minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], } } diff --git a/package.json b/package.json index 6836601..7a3e7f5 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,6 @@ "react-dom": "^19.1.0", "react-icons": "^5.5.0", "sonner": "^2.0.3", - "sqlite3": "^5.1.7", "superagent": "^10.2.1", "tailwind-merge": "^3.3.0", "tailwindcss": "^4.1.7", From a15178d2cd28a1116a2651846badfa154973c426 Mon Sep 17 00:00:00 2001 From: Arunavo Ray Date: Thu, 22 May 2025 08:39:07 +0530 Subject: [PATCH 05/10] Implement health check API and update health check commands in Docker and Docker Compose --- Dockerfile | 2 +- docker-compose.homelab.yml | 2 +- src/lib/api.ts | 77 +++++++++++++++++++++++ src/pages/api/health.ts | 126 +++++++++++++++++++++++++++++++++++++ 4 files changed, 205 insertions(+), 2 deletions(-) create mode 100644 src/pages/api/health.ts diff --git a/Dockerfile b/Dockerfile index e34e061..797a45e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -49,6 +49,6 @@ VOLUME /app/data EXPOSE 4321 HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ - CMD wget --no-verbose --tries=1 --spider http://localhost:4321/ || exit 1 + CMD wget --no-verbose --tries=1 --spider http://localhost:4321/api/health || exit 1 ENTRYPOINT ["./docker-entrypoint.sh"] diff --git a/docker-compose.homelab.yml b/docker-compose.homelab.yml index dcef182..cb3fd8d 100644 --- a/docker-compose.homelab.yml +++ b/docker-compose.homelab.yml @@ -18,7 +18,7 @@ services: - DATABASE_URL=sqlite://data/gitea-mirror.db - DELAY=${DELAY:-3600} healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:4321/health"] + test: ["CMD", "curl", "-f", "http://localhost:4321/api/health"] interval: 1m timeout: 10s retries: 3 diff --git a/src/lib/api.ts b/src/lib/api.ts index eb27948..9526095 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -88,3 +88,80 @@ export const giteaApi = { body: JSON.stringify({ url, token }), }), }; + +// Health API +export interface HealthResponse { + status: "ok" | "error"; + timestamp: string; + version: string; + database: { + connected: boolean; + message: string; + }; + system: { + uptime: { + startTime: string; + uptimeMs: number; + formatted: string; + }; + memory: { + rss: string; + heapTotal: string; + heapUsed: string; + external: string; + systemTotal: string; + systemFree: string; + }; + os: { + platform: string; + version: string; + arch: string; + }; + env: string; + }; + error?: string; +} + +export const healthApi = { + check: async (): Promise => { + try { + const response = await fetch(`${API_BASE}/health`); + + if (!response.ok) { + const errorData = await response.json().catch(() => ({ + status: "error", + error: "Failed to parse error response", + })); + + return { + ...errorData, + status: "error", + timestamp: new Date().toISOString(), + } as HealthResponse; + } + + return await response.json(); + } catch (error) { + return { + status: "error", + timestamp: new Date().toISOString(), + error: error instanceof Error ? error.message : "Unknown error checking health", + version: "unknown", + database: { connected: false, message: "Failed to connect to API" }, + system: { + uptime: { startTime: "", uptimeMs: 0, formatted: "N/A" }, + memory: { + rss: "N/A", + heapTotal: "N/A", + heapUsed: "N/A", + external: "N/A", + systemTotal: "N/A", + systemFree: "N/A", + }, + os: { platform: "", version: "", arch: "" }, + env: "", + }, + }; + } + }, +}; diff --git a/src/pages/api/health.ts b/src/pages/api/health.ts new file mode 100644 index 0000000..9695293 --- /dev/null +++ b/src/pages/api/health.ts @@ -0,0 +1,126 @@ +import type { APIRoute } from "astro"; +import { jsonResponse } from "@/lib/utils"; +import { db } from "@/lib/db"; +import { ENV } from "@/lib/config"; +import os from "os"; + +// Track when the server started +const serverStartTime = new Date(); + +export const GET: APIRoute = async () => { + try { + // Check database connection by running a simple query + const dbStatus = await checkDatabaseConnection(); + + // Get system information + const systemInfo = { + uptime: getUptime(), + memory: getMemoryUsage(), + os: { + platform: os.platform(), + version: os.version(), + arch: os.arch(), + }, + env: ENV.NODE_ENV, + }; + + // Build response + const healthData = { + status: "ok", + timestamp: new Date().toISOString(), + version: process.env.npm_package_version || "unknown", + database: dbStatus, + system: systemInfo, + }; + + return jsonResponse({ + data: healthData, + status: 200, + }); + } catch (error) { + console.error("Health check failed:", error); + + return jsonResponse({ + data: { + status: "error", + timestamp: new Date().toISOString(), + error: error instanceof Error ? error.message : "Unknown error", + }, + status: 503, // Service Unavailable + }); + } +}; + +/** + * Check database connection by running a simple query + */ +async function checkDatabaseConnection() { + try { + // Run a simple query to check if the database is accessible + const result = await db.select({ test: sql`1` }).from(sql`sqlite_master`).limit(1); + + return { + connected: true, + message: "Database connection successful", + }; + } catch (error) { + console.error("Database connection check failed:", error); + + return { + connected: false, + message: error instanceof Error ? error.message : "Database connection failed", + }; + } +} + +/** + * Get server uptime information + */ +function getUptime() { + const now = new Date(); + const uptimeMs = now.getTime() - serverStartTime.getTime(); + + // Convert to human-readable format + const seconds = Math.floor(uptimeMs / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + + return { + startTime: serverStartTime.toISOString(), + uptimeMs, + formatted: `${days}d ${hours % 24}h ${minutes % 60}m ${seconds % 60}s`, + }; +} + +/** + * Get memory usage information + */ +function getMemoryUsage() { + const memoryUsage = process.memoryUsage(); + + return { + rss: formatBytes(memoryUsage.rss), + heapTotal: formatBytes(memoryUsage.heapTotal), + heapUsed: formatBytes(memoryUsage.heapUsed), + external: formatBytes(memoryUsage.external), + systemTotal: formatBytes(os.totalmem()), + systemFree: formatBytes(os.freemem()), + }; +} + +/** + * Format bytes to human-readable format + */ +function formatBytes(bytes: number): string { + if (bytes === 0) return '0 Bytes'; + + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; +} + +// Import sql tag for raw SQL queries +import { sql } from "drizzle-orm"; From 5bf52c806ff82255a0664f8c8e2a2ae8c6603113 Mon Sep 17 00:00:00 2001 From: Arunavo Ray Date: Thu, 22 May 2025 08:53:19 +0530 Subject: [PATCH 06/10] Update README and add LXC deployment guide; enhance LXC installer scripts --- README.md | 46 ++-- docs/LXC.md | 131 ++++++++++++ scripts/gitea-mirror-lxc-installer.sh | 295 ++++++-------------------- scripts/gitea-mirror-lxc-local.sh | 86 ++++++++ 4 files changed, 313 insertions(+), 245 deletions(-) create mode 100644 docs/LXC.md create mode 100755 scripts/gitea-mirror-lxc-local.sh diff --git a/README.md b/README.md index 739c252..7513c78 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,15 @@ docker compose --profile production up -d # Using Bun 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 + +# 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).

Dashboard @@ -163,23 +167,39 @@ docker compose --profile production up -d 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 -# 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 ``` -The installer script: -- Downloads the Gitea Mirror repository -- Installs all dependencies including Bun -- Builds the application -- Sets up a systemd service -- Starts the application +**2. Local testing (offline-friendly, works on developer laptops)** -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 @@ -379,7 +399,7 @@ docker compose -f docker-compose.dev.yml up -d - **Backend**: Bun - **Database**: SQLite (handles both data storage and event notifications) - **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 diff --git a/docs/LXC.md b/docs/LXC.md new file mode 100644 index 0000000..482d89b --- /dev/null +++ b/docs/LXC.md @@ -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://: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://:4321/api/health + +# Detailed health information (JSON) +curl http://: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. diff --git a/scripts/gitea-mirror-lxc-installer.sh b/scripts/gitea-mirror-lxc-installer.sh index 4cf2d23..44568fa 100755 --- a/scripts/gitea-mirror-lxc-installer.sh +++ b/scripts/gitea-mirror-lxc-installer.sh @@ -1,266 +1,97 @@ -#!/bin/bash -# Gitea Mirror LXC Container Installer -# This is a self-contained script to install Gitea Mirror in an LXC container -# Usage: curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-installer.sh | bash +#!/usr/bin/env bash +# gitea-mirror-proxmox.sh +# Fully online installer for a Proxmox LXC guest running Gitea Mirror + Bun. -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 +JWT_SECRET=$(openssl rand -hex 32) -# Color codes for better readability -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color +REPO="https://github.com/arunavo4/gitea-mirror.git" +# ───────────────────────────────────────────────────────────────────────── -# Print banner -echo -e "${BLUE}" -echo "╔════════════════════════════════════════════════════════════╗" -echo "║ ║" -echo "║ Gitea Mirror LXC Container Installer ║" -echo "║ ║" -echo "╚════════════════════════════════════════════════════════════╝" -echo -e "${NC}" +TEMPLATE='ubuntu-22.04-standard_22.04-1_amd64.tar.zst' +TEMPLATE_PATH="/var/lib/vz/template/cache/${TEMPLATE}" -# Ensure script is run as root -if [ "$(id -u)" -ne 0 ]; then - echo -e "${RED}This script must be run as root${NC}" >&2 - exit 1 +echo "▶️ Ensuring template exists…" +if [[ ! -f $TEMPLATE_PATH ]]; then + pveam update >/dev/null + pveam download "$STORAGE" "$TEMPLATE" fi -echo -e "${GREEN}Starting Gitea Mirror installation...${NC}" - -# Check if we're in an LXC container -if [ -d /proc/vz ] && [ ! -d /proc/bc ]; then - echo -e "${YELLOW}Running in an OpenVZ container. Some features may not work.${NC}" -elif [ -f /proc/1/environ ] && grep -q container=lxc /proc/1/environ; then - echo -e "${GREEN}Running in an LXC container. Good!${NC}" -else - echo -e "${YELLOW}Not running in a container. This script is designed for LXC containers.${NC}" - read -p "Continue anyway? (y/n) " -n 1 -r - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - echo -e "${RED}Installation aborted.${NC}" - exit 1 - fi +echo "▶️ Creating container $CTID (if missing)…" +if ! pct status "$CTID" &>/dev/null; then + pct create "$CTID" "$TEMPLATE_PATH" \ + --rootfs "$STORAGE:$DISK_SIZE" \ + --hostname "$HOSTNAME" \ + --cores "$CORES" --memory "$MEMORY" \ + --net0 "name=eth0,bridge=$BRIDGE,ip=$IP_CONF" \ + --features nesting=1 \ + --unprivileged 0 fi -# Install dependencies -echo -e "${BLUE}Step 1/7: Installing dependencies...${NC}" -apt update -apt install -y curl git sqlite3 build-essential openssl +pct start "$CTID" -# Create service user -echo -e "${BLUE}Step 2/7: Creating service user...${NC}" -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 +echo "▶️ Installing base packages inside CT $CTID…" +pct exec "$CTID" -- bash -c 'apt update && apt install -y curl git build-essential openssl sqlite3 unzip' -# Install Bun -echo -e "${BLUE}Step 3/7: Installing Bun runtime...${NC}" -if command -v bun >/dev/null 2>&1; then - echo -e "${YELLOW}Bun is already installed${NC}" +echo "▶️ Installing Bun runtime…" +pct exec "$CTID" -- bash -c ' + export BUN_INSTALL=/opt/bun + 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 -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 -e "${GREEN}Making Bun accessible to all users...${NC}" - - # Check if /usr/local/bin is writable - if [ ! -w /usr/local/bin ]; then - echo -e "${RED}Error: /usr/local/bin is not writable. Please run the script as root or with sufficient permissions.${NC}" - 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 +echo "▶️ Cloning & building Gitea Mirror…" +pct exec "$CTID" -- bash -c " + git clone --depth=1 '$REPO' /opt/gitea-mirror || (cd /opt/gitea-mirror && git pull) + cd /opt/gitea-mirror + bun install + bun run build 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 </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 enable gitea-mirror.service -systemctl start gitea-mirror.service +systemctl enable gitea-mirror +systemctl restart gitea-mirror +" -# Check if service started successfully -if systemctl is-active --quiet gitea-mirror.service; then - 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 +echo -e "\n🔍 Service status:" +pct exec "$CTID" -- systemctl status gitea-mirror --no-pager | head -n15 -# Get IP address -IP_ADDRESS=$(hostname -I | awk '{print $1}') - -# Print success message -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}" +GUEST_IP=$(pct exec "$CTID" -- hostname -I | awk '{print $1}') +echo -e "\n🌐 Browse to: http://$GUEST_IP:$PORT\n" +echo "🗝️ JWT_SECRET = $JWT_SECRET" +echo -e "\n✅ Done – Gitea Mirror is running in CT $CTID." diff --git a/scripts/gitea-mirror-lxc-local.sh b/scripts/gitea-mirror-lxc-local.sh new file mode 100755 index 0000000..339b62a --- /dev/null +++ b/scripts/gitea-mirror-lxc-local.sh @@ -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 </etc/systemd/system/gitea-mirror.service < Date: Thu, 22 May 2025 08:56:53 +0530 Subject: [PATCH 07/10] Update LXC deployment guide references and remove outdated documentation --- README.md | 4 +- docs/LXC.md | 131 --------------------------- scripts/README-lxc.md | 201 +++++++++++++++++++----------------------- 3 files changed, 92 insertions(+), 244 deletions(-) delete mode 100644 docs/LXC.md diff --git a/README.md b/README.md index 7513c78..401bf03 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/ sudo LOCAL_REPO_DIR=~/Development/gitea-mirror ./scripts/gitea-mirror-lxc-local.sh ```` -See the [LXC Container Deployment Guide](docs/LXC.md). +See the [LXC Container Deployment Guide](scripts/README-lxc.md).

Dashboard @@ -199,7 +199,7 @@ Both scripts: The application includes a health check endpoint at `/api/health` for monitoring. -See the [LXC Container Deployment Guide](docs/LXC.md) for detailed instructions. +See the [LXC Container Deployment Guide](scripts/README-lxc.md) for detailed instructions. ##### Building Your Own Image diff --git a/docs/LXC.md b/docs/LXC.md deleted file mode 100644 index 482d89b..0000000 --- a/docs/LXC.md +++ /dev/null @@ -1,131 +0,0 @@ -# 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://: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://:4321/api/health - -# Detailed health information (JSON) -curl http://: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. diff --git a/scripts/README-lxc.md b/scripts/README-lxc.md index 6a44936..482d89b 100644 --- a/scripts/README-lxc.md +++ b/scripts/README-lxc.md @@ -1,109 +1,117 @@ # LXC Container Deployment Guide -This guide explains how to deploy the Gitea Mirror application on Proxmox LXC containers while keeping your existing Docker containers. +## Overview +Run **Gitea Mirror** in an isolated LXC container, either: -## Prerequisites +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 -- Proxmox VE installed and configured -- Basic knowledge of LXC containers and Proxmox -- Access to Proxmox web interface or CLI +--- -## Creating an LXC Container +## 1. Proxmox VE (online, recommended for prod) -1. In Proxmox web interface, create a new LXC container: - - Choose Ubuntu 22.04 as the template - - Allocate appropriate resources (2GB RAM, 2 CPU cores recommended) - - At least 10GB of disk space - - Configure networking as needed +### Prerequisites +* Proxmox VE node with the default `vmbr0` bridge +* Root shell on the node +* Ubuntu 22.04 LXC template present (`pveam update && pveam download ...`) -2. Start the container and get a shell (either via Proxmox web console or SSH) +### One-command install -## Deploying Gitea Mirror +```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)" +``` -### Option 1: One-Command Installation (Recommended) +What it does: -This method allows you to install Gitea Mirror with a single command, without having to copy files manually: +* 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` -1. SSH into your LXC container: - ```bash - ssh root@lxc-container-ip - ``` +Browse to: -2. Run the installer script directly: - ```bash - curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-installer.sh | bash - ``` +``` +http://:4321 +``` -3. The installer will: - - Download the Gitea Mirror repository - - Install all dependencies including Bun - - Build the application - - Set up a systemd service - - Start the application - - Display access information +--- -### Option 2: Manual Setup +## 2. Local testing (LXD on a workstation, works offline) -If you prefer to set up manually or the automatic script doesn't work for your environment: +### Prerequisites -1. Install dependencies: - ```bash - apt update - apt install -y curl git sqlite3 build-essential - ``` +* `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` -2. Install Bun: - ```bash - curl -fsSL https://bun.sh/install | bash - export BUN_INSTALL="/root/.bun" - export PATH="$BUN_INSTALL/bin:$PATH" - ``` +### Offline installer script -3. Clone or copy your project: - ```bash - git clone https://github.com/yourusername/gitea-mirror.git /opt/gitea-mirror - cd /opt/gitea-mirror - ``` +```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 -4. Build and initialize: - ```bash - bun install - bun run build - bun run manage-db init - ``` +sudo LOCAL_REPO_DIR=~/Development/gitea-mirror \ + ./gitea-mirror-lxc-local.sh +``` -5. Create a systemd service manually: - ```bash - nano /etc/systemd/system/gitea-mirror.service - # Add the service configuration as shown below: +What it does: - [Unit] - Description=Gitea Mirror - After=network.target +* 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 - [Service] - Type=simple - WorkingDirectory=/opt/gitea-mirror - ExecStart=/root/.bun/bin/bun dist/server/entry.mjs - Restart=on-failure - RestartSec=10 - User=gitea-mirror - Group=gitea-mirror - Environment=NODE_ENV=production - Environment=HOST=0.0.0.0 - Environment=PORT=4321 - Environment=DATABASE_URL=file:data/gitea-mirror.db - Environment=JWT_SECRET=your-secure-secret-key +Access from host: - [Install] - WantedBy=multi-user.target - ``` +``` +http://$(lxc exec gitea-test -- hostname -I | awk '{print $1}'):4321 +``` - 6. Enable and start the service: - ```bash - systemctl enable gitea-mirror.service - systemctl start gitea-mirror.service - ``` +(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://:4321/api/health + +# Detailed health information (JSON) +curl http://: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 @@ -121,32 +129,3 @@ If you need your LXC container to communicate with Docker containers: ``` 3. In Proxmox, edit the LXC container's network configuration to use this bridge. - -## Accessing the Application - -Once deployed, you can access the Gitea Mirror application at: -``` -http://lxc-container-ip:4321 -``` - -## Troubleshooting - -- Check service status: - ```bash - systemctl status gitea-mirror - ``` - -- View logs: - ```bash - journalctl -u gitea-mirror -f - ``` - -- If the service fails to start, check permissions on the data directory: - ```bash - chown -R gitea-mirror:gitea-mirror /opt/gitea-mirror/data - ``` - -- Verify Bun is installed correctly: - ```bash - bun --version - ``` From 1ab642c9e70fc72770c1d0379eeed73ca57e4edd Mon Sep 17 00:00:00 2001 From: Arunavo Ray Date: Thu, 22 May 2025 09:04:05 +0530 Subject: [PATCH 08/10] Update LXC deployment scripts: replace installer script with Proxmox-specific script and update README references --- README.md | 4 ++-- scripts/README-lxc.md | 2 +- ...ea-mirror-lxc-installer.sh => gitea-mirror-lxc-proxmox.sh} | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename scripts/{gitea-mirror-lxc-installer.sh => gitea-mirror-lxc-proxmox.sh} (99%) diff --git a/README.md b/README.md index 401bf03..0cecf96 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ bun run setup && bun run dev # 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-proxmox.sh | bash # For local testing (offline-friendly) sudo LOCAL_REPO_DIR=~/Development/gitea-mirror ./scripts/gitea-mirror-lxc-local.sh @@ -176,7 +176,7 @@ Gitea Mirror offers two deployment options for LXC containers: ```bash # 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-proxmox.sh | bash ``` **2. Local testing (offline-friendly, works on developer laptops)** diff --git a/scripts/README-lxc.md b/scripts/README-lxc.md index 482d89b..4ba71df 100644 --- a/scripts/README-lxc.md +++ b/scripts/README-lxc.md @@ -19,7 +19,7 @@ Run **Gitea Mirror** in an isolated LXC container, either: ```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)" +sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-proxmox.sh)" ``` What it does: diff --git a/scripts/gitea-mirror-lxc-installer.sh b/scripts/gitea-mirror-lxc-proxmox.sh similarity index 99% rename from scripts/gitea-mirror-lxc-installer.sh rename to scripts/gitea-mirror-lxc-proxmox.sh index 44568fa..d242a2e 100755 --- a/scripts/gitea-mirror-lxc-installer.sh +++ b/scripts/gitea-mirror-lxc-proxmox.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# gitea-mirror-proxmox.sh +# gitea-mirror-lxc-proxmox.sh # Fully online installer for a Proxmox LXC guest running Gitea Mirror + Bun. set -euo pipefail From 8b5c5d8ed25f6d9b51b51f68109ad029019d8085 Mon Sep 17 00:00:00 2001 From: Arunavo Ray Date: Thu, 22 May 2025 09:06:47 +0530 Subject: [PATCH 09/10] Update README to include event management scripts and LXC deployment details --- scripts/README.md | 81 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/scripts/README.md b/scripts/README.md index 3dcae9e..e0d0fef 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -1,12 +1,14 @@ # Scripts Directory -This folder contains utility scripts for database management. +This folder contains utility scripts for database management, event management, Docker builds, and LXC container deployment. -## Database Management Tool (manage-db.ts) +## Database Management + +### Database Management Tool (manage-db.ts) This is a consolidated database management tool that handles all database-related operations. It combines the functionality of the previous separate scripts into a single, more intelligent script that can check, fix, and initialize the database as needed. -### Features +#### Features - **Check Mode**: Validates the existence and integrity of the database - **Init Mode**: Creates the database only if it doesn't already exist @@ -14,12 +16,12 @@ This is a consolidated database management tool that handles all database-relate - **Reset Users Mode**: Removes all users and their data - **Auto Mode**: Automatically checks, fixes, and initializes the database if needed -## Running the Database Management Tool +#### Running the Database Management Tool You can execute the database management tool using your package manager with various commands: ```bash -# Checks database status (default action if no command is specified, equivalent to 'bun run check-db') +# Checks database status (default action if no command is specified) bun run manage-db # Check database status @@ -37,9 +39,6 @@ bun run db-auto # Reset all users (for testing signup flow) bun run reset-users -# Update the database schema to the latest version -bun run update-schema - # Remove database files completely bun run cleanup-db @@ -53,6 +52,70 @@ bun run dev:clean bun run start:fresh ``` -## Database File Location +#### Database File Location The database file should be located in the `./data/gitea-mirror.db` directory. If the file is found in the root directory, the fix mode will move it to the correct location. + +## Event Management + +The following scripts help manage events in the SQLite database: + +### Event Inspection (check-events.ts) + +Displays all events currently stored in the database. + +```bash +bun scripts/check-events.ts +``` + +### Event Cleanup (cleanup-events.ts) + +Removes old events from the database to prevent it from growing too large. + +```bash +# Remove events older than 7 days (default) +bun scripts/cleanup-events.ts + +# Remove events older than X days +bun scripts/cleanup-events.ts 14 +``` + +This script can be scheduled to run periodically (e.g., daily) using cron or another scheduler. + +### Mark Events as Read (mark-events-read.ts) + +Marks all unread events as read. + +```bash +bun scripts/mark-events-read.ts +``` + +### Make Events Appear Older (make-events-old.ts) + +For testing purposes, this script modifies event timestamps to make them appear older. + +```bash +bun scripts/make-events-old.ts +``` + +## Deployment Scripts + +### Docker Deployment + +- **build-docker.sh**: Builds the Docker image for the application +- **docker-diagnostics.sh**: Provides diagnostic information for Docker deployments + +### LXC Container Deployment + +Two scripts are provided for deploying Gitea Mirror in LXC containers: + +1. **gitea-mirror-lxc-proxmox.sh**: For online deployment on a Proxmox VE host + - Pulls everything from GitHub + - Creates a privileged container with the application + - Sets up systemd service + +2. **gitea-mirror-lxc-local.sh**: For offline/LAN-only deployment on a developer laptop + - Pushes your local checkout + Bun ZIP to the container + - Useful for testing without internet access + +For detailed instructions on LXC deployment, see [README-lxc.md](./README-lxc.md). From 9ccd656734b9a605021e12bd6c0bf60128fb9c48 Mon Sep 17 00:00:00 2001 From: Arunavo Ray Date: Thu, 22 May 2025 09:12:32 +0530 Subject: [PATCH 10/10] Update documentation: revise architecture, configuration, and quick start guides to reflect new features and deployment options --- src/content/docs/architecture.md | 35 +++++++++++++---- src/content/docs/configuration.md | 61 +++++++++++++++++++++++++++-- src/content/docs/quickstart.md | 65 ++++++++++++++++++++++++++++--- 3 files changed, 146 insertions(+), 15 deletions(-) diff --git a/src/content/docs/architecture.md b/src/content/docs/architecture.md index 4045f4b..20f5072 100644 --- a/src/content/docs/architecture.md +++ b/src/content/docs/architecture.md @@ -2,7 +2,7 @@ title: "Architecture" description: "Comprehensive overview of the Gitea Mirror application architecture." order: 1 -updatedDate: 2023-10-15 +updatedDate: 2025-05-22 ---

@@ -21,17 +21,18 @@ The application is built using: - Astro: Web framework for the frontend - React: Component library for interactive UI elements - Shadcn UI: UI component library built on Tailwind CSS -- SQLite: Database for storing configuration and state +- SQLite: Database for storing configuration, state, and events - Bun: Runtime environment for the backend +- Drizzle ORM: Type-safe ORM for database interactions ## Architecture Diagram ```mermaid graph TD subgraph "Gitea Mirror" - Frontend["Frontend
(Astro)"] + Frontend["Frontend
(Astro + React)"] Backend["Backend
(Bun)"] - Database["Database
(SQLite)"] + Database["Database
(SQLite + Drizzle)"] Frontend <--> Backend Backend <--> Database @@ -70,14 +71,15 @@ The backend is built with Bun and provides API endpoints for the frontend to int - Mirroring operations - Database interactions -### Database (SQLite) +### Database (SQLite + Drizzle ORM) -SQLite is used for data persistence, storing: +SQLite with Bun's native SQLite driver is used for data persistence, with Drizzle ORM providing type-safe database interactions. The database stores: - User accounts and authentication data - GitHub and Gitea configuration - Repository and organization information - Mirroring job history and status +- Event notifications and their read status ## Data Flow @@ -93,11 +95,30 @@ SQLite is used for data persistence, storing: gitea-mirror/ ├── src/ # Source code │ ├── components/ # React components +│ ├── content/ # Documentation and content │ ├── layouts/ # Astro layout components │ ├── lib/ # Utility functions and database │ ├── pages/ # Astro pages and API routes │ └── styles/ # CSS and Tailwind styles ├── public/ # Static assets ├── data/ # Database and persistent data -└── docker/ # Docker configuration +├── docker/ # Docker configuration +└── scripts/ # Utility scripts for deployment and maintenance + ├── gitea-mirror-lxc-proxmox.sh # Proxmox LXC deployment script + ├── gitea-mirror-lxc-local.sh # Local LXC deployment script + └── manage-db.ts # Database management tool ``` + +## Deployment Options + +Gitea Mirror supports multiple deployment options: + +1. **Docker**: Run as a containerized application using Docker and docker-compose +2. **LXC Containers**: Deploy in Linux Containers (LXC) on Proxmox VE or local workstations +3. **Native**: Run directly on the host system using Bun runtime + +Each deployment method has its own advantages: + +- **Docker**: Isolation, easy updates, consistent environment +- **LXC**: Lightweight virtualization, better performance than Docker, system-level isolation +- **Native**: Best performance, direct access to system resources diff --git a/src/content/docs/configuration.md b/src/content/docs/configuration.md index ce4c713..459754e 100644 --- a/src/content/docs/configuration.md +++ b/src/content/docs/configuration.md @@ -2,7 +2,7 @@ title: "Configuration" description: "Guide to configuring Gitea Mirror for your environment." order: 2 -updatedDate: 2023-10-15 +updatedDate: 2025-05-22 ---
@@ -24,10 +24,10 @@ The following environment variables can be used to configure Gitea Mirror: | Variable | Description | Default Value | Example | |----------|-------------|---------------|---------| | `NODE_ENV` | Runtime environment (development, production, test) | `development` | `production` | -| `DATABASE_URL` | SQLite database URL | `sqlite://data/gitea-mirror.db` | `sqlite://path/to/your/database.db` | +| `DATABASE_URL` | SQLite database URL | `file:data/gitea-mirror.db` | `file:path/to/your/database.db` | | `JWT_SECRET` | Secret key for JWT authentication | `your-secret-key-change-this-in-production` | `your-secure-random-string` | | `HOST` | Server host | `localhost` | `0.0.0.0` | -| `PORT` | Server port | `3000` | `8080` | +| `PORT` | Server port | `4321` | `8080` | ### Important Security Note @@ -118,3 +118,58 @@ Example patterns: - `*` - All repositories - `org-name/*` - All repositories in a specific organization - `username/repo-name` - A specific repository + +### Database Management + +Gitea Mirror includes several database management tools that can be run from the command line: + +```bash +# Initialize the database (only if it doesn't exist) +bun run init-db + +# Check database status +bun run check-db + +# Fix database location issues +bun run fix-db + +# Reset all users (for testing signup flow) +bun run reset-users + +# Remove database files completely +bun run cleanup-db +``` + +### Event Management + +Events in Gitea Mirror (such as repository mirroring operations) are stored in the SQLite database. You can manage these events using the following scripts: + +```bash +# View all events in the database +bun scripts/check-events.ts + +# Clean up old events (default: older than 7 days) +bun scripts/cleanup-events.ts + +# Mark all events as read +bun scripts/mark-events-read.ts +``` + +### 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://your-server:port/api/health + +# Detailed health information (JSON) +curl http://your-server:port/api/health +``` diff --git a/src/content/docs/quickstart.md b/src/content/docs/quickstart.md index 2e75493..ddc01ad 100644 --- a/src/content/docs/quickstart.md +++ b/src/content/docs/quickstart.md @@ -2,7 +2,7 @@ title: "Quick Start Guide" description: "Get started with Gitea Mirror quickly." order: 3 -updatedDate: 2023-10-15 +updatedDate: 2025-05-22 ---
@@ -16,13 +16,16 @@ Before you begin, make sure you have: 1. A GitHub account with a personal access token 2. A Gitea instance with an access token -3. Docker and docker-compose (recommended) or Bun 1.2.9+ installed +3. One of the following: + - Docker and docker-compose (for Docker deployment) + - Bun 1.2.9+ (for native deployment) + - Proxmox VE or LXD (for LXC container deployment) ## Installation Options Choose the installation method that works best for your environment. -### Using Docker (Recommended) +### Using Docker (Recommended for most users) Docker provides the easiest way to get started with minimal configuration. @@ -39,7 +42,7 @@ Docker provides the easiest way to get started with minimal configuration. 3. Access the application at [http://localhost:4321](http://localhost:4321) -### Manual Installation +### Using Bun (Native Installation) If you prefer to run the application directly on your system: @@ -62,6 +65,11 @@ If you prefer to run the application directly on your system: bun run dev ``` + Note: For Bun-specific features, use: + ```bash + bunx --bun astro dev + ``` + **Production Mode:** ```bash bun run build @@ -70,6 +78,44 @@ If you prefer to run the application directly on your system: 4. Access the application at [http://localhost:4321](http://localhost:4321) +### Using LXC Containers (Recommended for server deployments) + +#### Proxmox VE (Online Installation) + +For deploying on a Proxmox VE host with internet access: + +```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-proxmox.sh)" +``` + +This script: +- Creates a privileged LXC container +- Installs Bun and dependencies +- Clones and builds the application +- Sets up a systemd service + +#### Local LXD (Offline-friendly Installation) + +For testing on a local workstation or in environments without internet access: + +1. Clone the repository locally: + ```bash + git clone https://github.com/arunavo4/gitea-mirror.git + ``` + +2. Download the Bun installer once: + ```bash + curl -L -o /tmp/bun-linux-x64.zip https://github.com/oven-sh/bun/releases/latest/download/bun-linux-x64.zip + ``` + +3. Run the local LXC installer: + ```bash + sudo LOCAL_REPO_DIR=~/path/to/gitea-mirror ./gitea-mirror/scripts/gitea-mirror-lxc-local.sh + ``` + +For more details on LXC deployment, see the [LXC Container Deployment Guide](https://github.com/arunavo4/gitea-mirror/blob/main/scripts/README-lxc.md). + ## Initial Configuration Follow these steps to configure Gitea Mirror for first use: @@ -116,7 +162,12 @@ If you encounter any issues: - Check the Activity Log for detailed error messages - Verify your GitHub and Gitea tokens have the correct permissions - Ensure your Gitea instance is accessible from the machine running Gitea Mirror -- For Docker installations, check container logs with `docker logs gitea-mirror` +- Check logs based on your deployment method: + - Docker: `docker logs gitea-mirror` + - Native: Check the terminal output or system logs + - LXC: `systemctl status gitea-mirror` or `journalctl -u gitea-mirror -f` +- Use the health check endpoint to verify system status: `curl http://your-server:4321/api/health` +- For database issues, try the database management tools: `bun run check-db` or `bun run fix-db` ## Next Steps @@ -125,3 +176,7 @@ After your initial setup: - Explore the dashboard for an overview of your mirroring status - Set up automatic mirroring schedules for hands-off operation - Configure organization mirroring for team repositories +- Check out the [Configuration Guide](/configuration) for advanced settings +- Review the [Architecture Documentation](/architecture) to understand the system +- For server deployments, set up monitoring using the health check endpoint +- Consider setting up a cron job to clean up old events: `bun scripts/cleanup-events.ts`