Compare commits

...

4 Commits

Author SHA1 Message Date
8045ec38df v1.13.0
Some checks failed
CI / Build Test (Current Platform) (push) Failing after 1m0s
CI / Type Check & Lint (push) Failing after 1m10s
Release / build-and-release (push) Failing after 4m38s
Publish to npm / npm-publish (push) Failing after 5m34s
CI / Build All Platforms (push) Successful in 10m5s
2026-03-15 12:24:48 +00:00
793fb18b43 feat(install): improve installer with version selection, service restart handling, and upgrade documentation 2026-03-15 12:24:48 +00:00
09534fd899 v1.12.1
Some checks failed
CI / Type Check & Lint (push) Failing after 45s
CI / Build Test (Current Platform) (push) Failing after 1m24s
CI / Build All Platforms (push) Failing after 3m27s
Publish to npm / npm-publish (push) Failing after 3m21s
Release / build-and-release (push) Failing after 4m45s
2026-03-15 12:07:15 +00:00
5f3783a5e9 fix(package.json): update package metadata 2026-03-15 12:07:15 +00:00
8 changed files with 311 additions and 174 deletions

View File

@@ -1,5 +1,18 @@
# Changelog # Changelog
## 2026-03-15 - 1.13.0 - feat(install)
improve installer with version selection, service restart handling, and upgrade documentation
- Adds installer command-line options for help, specific version selection, and custom install directory.
- Fetches the latest release from the Gitea API when no version is provided and installs the matching platform binary.
- Preserves Onebox data directories, stops and restarts the systemd service during updates, and refreshes installation instructions in the README including upgrade usage.
## 2026-03-15 - 1.12.1 - fix(package.json)
update package metadata
- Single metadata-only file changed (+1, -1)
- No source code or runtime behavior modified; safe patch release
## 2026-03-15 - 1.12.0 - feat(cli,release) ## 2026-03-15 - 1.12.0 - feat(cli,release)
add self-upgrade command and automate CI, release, and npm publishing workflows add self-upgrade command and automate CI, release, and npm publishing workflows

View File

@@ -1,6 +1,6 @@
{ {
"name": "@serve.zone/onebox", "name": "@serve.zone/onebox",
"version": "1.12.0", "version": "1.13.0",
"exports": "./mod.ts", "exports": "./mod.ts",
"nodeModulesDir": "auto", "nodeModulesDir": "auto",
"tasks": { "tasks": {

View File

@@ -1,192 +1,308 @@
#!/bin/bash #!/bin/bash
# Onebox Installer Script
# Downloads and installs pre-compiled Onebox binary from Gitea releases
# #
# Onebox installer script # Usage:
# Direct piped installation (recommended):
# curl -sSL https://code.foss.global/serve.zone/onebox/raw/branch/main/install.sh | sudo bash
# #
# With version specification:
# curl -sSL https://code.foss.global/serve.zone/onebox/raw/branch/main/install.sh | sudo bash -s -- --version v1.11.0
#
# Options:
# -h, --help Show this help message
# --version VERSION Install specific version (e.g., v1.11.0)
# --install-dir DIR Installation directory (default: /opt/onebox)
set -e set -e
# Configuration # Default values
REPO_URL="https://code.foss.global/serve.zone/onebox" SHOW_HELP=0
SPECIFIED_VERSION=""
INSTALL_DIR="/opt/onebox" INSTALL_DIR="/opt/onebox"
BIN_LINK="/usr/local/bin/onebox" GITEA_BASE_URL="https://code.foss.global"
GITEA_REPO="serve.zone/onebox"
SERVICE_NAME="smartdaemon_onebox"
# Colors # Parse command line arguments
RED='\033[0;31m' while [[ $# -gt 0 ]]; do
GREEN='\033[0;32m' case $1 in
YELLOW='\033[1;33m' -h|--help)
NC='\033[0m' # No Color SHOW_HELP=1
shift
;;
--version)
SPECIFIED_VERSION="$2"
shift 2
;;
--install-dir)
INSTALL_DIR="$2"
shift 2
;;
*)
echo "Unknown option: $1"
echo "Use -h or --help for usage information"
exit 1
;;
esac
done
# Functions if [ $SHOW_HELP -eq 1 ]; then
error() { echo "Onebox Installer Script"
echo -e "${RED}Error: $1${NC}" >&2 echo "Downloads and installs pre-compiled Onebox binary"
exit 1 echo ""
} echo "Usage: $0 [options]"
echo ""
info() { echo "Options:"
echo -e "${GREEN}$1${NC}" echo " -h, --help Show this help message"
} echo " --version VERSION Install specific version (e.g., v1.11.0)"
echo " --install-dir DIR Installation directory (default: /opt/onebox)"
warn() { echo ""
echo -e "${YELLOW}$1${NC}" echo "Examples:"
} echo " # Install latest version"
echo " curl -sSL https://code.foss.global/serve.zone/onebox/raw/branch/main/install.sh | sudo bash"
# Detect platform and architecture echo ""
detect_platform() { echo " # Install specific version"
OS=$(uname -s | tr '[:upper:]' '[:lower:]') echo " curl -sSL https://code.foss.global/serve.zone/onebox/raw/branch/main/install.sh | sudo bash -s -- --version v1.11.0"
ARCH=$(uname -m) exit 0
fi
case "$OS" in
linux)
PLATFORM="linux"
;;
darwin)
PLATFORM="macos"
;;
*)
error "Unsupported operating system: $OS"
;;
esac
case "$ARCH" in
x86_64|amd64)
ARCH="x64"
;;
aarch64|arm64)
ARCH="arm64"
;;
*)
error "Unsupported architecture: $ARCH"
;;
esac
BINARY_NAME="onebox-${PLATFORM}-${ARCH}"
}
# Get latest version from Gitea API
get_latest_version() {
info "Fetching latest version..."
VERSION=$(curl -s "${REPO_URL}/releases" | grep -o '"tag_name":"v[^"]*' | head -1 | cut -d'"' -f4 | cut -c2-)
if [ -z "$VERSION" ]; then
warn "Could not fetch latest version, using 'main' branch"
VERSION="main"
else
info "Latest version: v${VERSION}"
fi
}
# Check if running as root # Check if running as root
check_root() { if [ "$EUID" -ne 0 ]; then
if [ "$EUID" -ne 0 ]; then echo "Please run as root (sudo bash install.sh or pipe to sudo bash)"
error "This script must be run as root (use sudo)" exit 1
fi fi
# Helper function to detect OS and architecture
detect_platform() {
local os=$(uname -s)
local arch=$(uname -m)
# Map OS
case "$os" in
Linux)
os_name="linux"
;;
Darwin)
os_name="macos"
;;
MINGW*|MSYS*|CYGWIN*)
os_name="windows"
;;
*)
echo "Error: Unsupported operating system: $os"
echo "Supported: Linux, macOS, Windows"
exit 1
;;
esac
# Map architecture
case "$arch" in
x86_64|amd64)
arch_name="x64"
;;
aarch64|arm64)
arch_name="arm64"
;;
*)
echo "Error: Unsupported architecture: $arch"
echo "Supported: x86_64/amd64 (x64), aarch64/arm64 (arm64)"
exit 1
;;
esac
# Construct binary name
if [ "$os_name" = "windows" ]; then
echo "onebox-${os_name}-${arch_name}.exe"
else
echo "onebox-${os_name}-${arch_name}"
fi
} }
# Get latest release version from Gitea API
get_latest_version() {
echo "Fetching latest release version from Gitea..." >&2
local api_url="${GITEA_BASE_URL}/api/v1/repos/${GITEA_REPO}/releases/latest"
local response=$(curl -sSL "$api_url" 2>/dev/null)
if [ $? -ne 0 ] || [ -z "$response" ]; then
echo "Error: Failed to fetch latest release information from Gitea API" >&2
echo "URL: $api_url" >&2
exit 1
fi
# Extract tag_name from JSON response
local version=$(echo "$response" | grep -o '"tag_name":"[^"]*"' | cut -d'"' -f4)
if [ -z "$version" ]; then
echo "Error: Could not determine latest version from API response" >&2
exit 1
fi
echo "$version"
}
# Main installation process
echo "================================================"
echo " Onebox Installation Script"
echo "================================================"
echo ""
# Detect platform
BINARY_NAME=$(detect_platform)
echo "Detected platform: $BINARY_NAME"
echo ""
# Determine version to install
if [ -n "$SPECIFIED_VERSION" ]; then
VERSION="$SPECIFIED_VERSION"
echo "Installing specified version: $VERSION"
else
VERSION=$(get_latest_version)
echo "Installing latest version: $VERSION"
fi
echo ""
# Construct download URL
DOWNLOAD_URL="${GITEA_BASE_URL}/${GITEA_REPO}/releases/download/${VERSION}/${BINARY_NAME}"
echo "Download URL: $DOWNLOAD_URL"
echo ""
# Check if service is running and stop it
SERVICE_WAS_RUNNING=0
if systemctl is-enabled --quiet "$SERVICE_NAME" 2>/dev/null || systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then
SERVICE_WAS_RUNNING=1
if systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then
echo "Stopping Onebox service..."
systemctl stop "$SERVICE_NAME"
fi
fi
# Clean installation directory - ensure only binary exists
if [ -d "$INSTALL_DIR" ]; then
echo "Cleaning installation directory: $INSTALL_DIR"
rm -rf "$INSTALL_DIR"
fi
# Create fresh installation directory
echo "Creating installation directory: $INSTALL_DIR"
mkdir -p "$INSTALL_DIR"
# Download binary # Download binary
download_binary() { echo "Downloading Onebox binary..."
info "Downloading Onebox ${VERSION} for ${PLATFORM}-${ARCH}..." TEMP_FILE="$INSTALL_DIR/onebox.download"
curl -sSL "$DOWNLOAD_URL" -o "$TEMP_FILE"
# Create temp directory if [ $? -ne 0 ]; then
TMP_DIR=$(mktemp -d) echo "Error: Failed to download binary from $DOWNLOAD_URL"
TMP_FILE="${TMP_DIR}/${BINARY_NAME}" echo ""
echo "Please check:"
echo " 1. Your internet connection"
echo " 2. The specified version exists: ${GITEA_BASE_URL}/${GITEA_REPO}/releases"
echo " 3. The platform binary is available for this release"
rm -f "$TEMP_FILE"
exit 1
fi
# Try release download first # Check if download was successful (file exists and not empty)
if [ "$VERSION" != "main" ]; then if [ ! -s "$TEMP_FILE" ]; then
DOWNLOAD_URL="${REPO_URL}/releases/download/v${VERSION}/${BINARY_NAME}" echo "Error: Downloaded file is empty or does not exist"
else rm -f "$TEMP_FILE"
DOWNLOAD_URL="${REPO_URL}/raw/branch/main/dist/binaries/${BINARY_NAME}" exit 1
fi fi
if ! curl -L -f -o "$TMP_FILE" "$DOWNLOAD_URL"; then # Move to final location
error "Failed to download binary from $DOWNLOAD_URL" BINARY_PATH="$INSTALL_DIR/onebox"
fi mv "$TEMP_FILE" "$BINARY_PATH"
# Verify download if [ $? -ne 0 ] || [ ! -f "$BINARY_PATH" ]; then
if [ ! -f "$TMP_FILE" ] || [ ! -s "$TMP_FILE" ]; then echo "Error: Failed to move binary to $BINARY_PATH"
error "Downloaded file is empty or missing" rm -f "$TEMP_FILE" 2>/dev/null
fi exit 1
fi
info "✓ Download complete" # Make executable
} chmod +x "$BINARY_PATH"
# Install binary if [ $? -ne 0 ]; then
install_binary() { echo "Error: Failed to make binary executable"
info "Installing Onebox to ${INSTALL_DIR}..." exit 1
fi
# Create install directory echo "Binary installed successfully to: $BINARY_PATH"
mkdir -p "$INSTALL_DIR" echo ""
# Copy binary # Check if /usr/local/bin is in PATH
cp "$TMP_FILE" "${INSTALL_DIR}/onebox" if [[ ":$PATH:" == *":/usr/local/bin:"* ]]; then
chmod +x "${INSTALL_DIR}/onebox" BIN_DIR="/usr/local/bin"
else
BIN_DIR="/usr/bin"
fi
# Create symlink # Create symlink for global access
ln -sf "${INSTALL_DIR}/onebox" "$BIN_LINK" ln -sf "$BINARY_PATH" "$BIN_DIR/onebox"
echo "Symlink created: $BIN_DIR/onebox -> $BINARY_PATH"
echo ""
# Cleanup temp files # Create data directories
rm -rf "$TMP_DIR" mkdir -p /var/lib/onebox
mkdir -p /var/www/certbot
info "✓ Installation complete" # Restart service if it was running before update
} if [ $SERVICE_WAS_RUNNING -eq 1 ]; then
echo "Restarting Onebox service..."
systemctl restart "$SERVICE_NAME"
echo "Service restarted successfully."
echo ""
fi
# Initialize database and config echo "================================================"
initialize() { echo " Onebox Installation Complete!"
info "Initializing Onebox..." echo "================================================"
echo ""
echo "Installation details:"
echo " Binary location: $BINARY_PATH"
echo " Symlink location: $BIN_DIR/onebox"
echo " Version: $VERSION"
echo ""
# Create data directory # Check if database exists (indicates existing installation)
mkdir -p /var/lib/onebox if [ -f "/var/lib/onebox/onebox.db" ]; then
echo "Data directory: /var/lib/onebox (preserved)"
# Create certbot directory for ACME challenges echo ""
mkdir -p /var/www/certbot echo "Your existing data has been preserved."
if [ $SERVICE_WAS_RUNNING -eq 1 ]; then
info "✓ Initialization complete" echo "The service has been restarted with your current settings."
} else
echo "Start the service with: onebox daemon start"
# Print success message fi
print_success() { else
echo "" echo "Get started:"
info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo ""
info " Onebox installed successfully!" echo " onebox --version"
info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo " onebox --help"
echo "" echo ""
echo "Next steps:" echo " 1. Configure Cloudflare (optional):"
echo "" echo " onebox config set cloudflareAPIKey <key>"
echo "1. Configure Cloudflare (optional):" echo " onebox config set cloudflareEmail <email>"
echo " onebox config set cloudflareAPIKey <key>" echo " onebox config set cloudflareZoneID <zone-id>"
echo " onebox config set cloudflareEmail <email>" echo " onebox config set serverIP <your-server-ip>"
echo " onebox config set cloudflareZoneID <zone-id>" echo ""
echo " onebox config set serverIP <your-server-ip>" echo " 2. Configure ACME email:"
echo "" echo " onebox config set acmeEmail <your@email.com>"
echo "2. Configure ACME email:" echo ""
echo " onebox config set acmeEmail <your@email.com>" echo " 3. Install daemon:"
echo "" echo " onebox daemon install"
echo "3. Install daemon:" echo ""
echo " onebox daemon install" echo " 4. Start daemon:"
echo "" echo " onebox daemon start"
echo "4. Start daemon:" echo ""
echo " onebox daemon start" echo " 5. Deploy your first service:"
echo "" echo " onebox service add myapp --image nginx:latest --domain app.example.com"
echo "5. Deploy your first service:" echo ""
echo " onebox service add myapp --image nginx:latest --domain app.example.com" echo " Web UI: http://localhost:3000"
echo "" echo " Default credentials: admin / admin"
echo "Web UI: http://localhost:3000" fi
echo "Default credentials: admin / admin" echo ""
echo ""
}
# Main installation flow
main() {
info "Onebox Installer"
echo ""
check_root
detect_platform
get_latest_version
download_binary
install_binary
initialize
print_success
}
# Run main function
main

View File

@@ -1,6 +1,6 @@
{ {
"name": "@serve.zone/onebox", "name": "@serve.zone/onebox",
"version": "1.12.0", "version": "1.13.0",
"description": "Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers", "description": "Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers",
"main": "mod.ts", "main": "mod.ts",
"type": "module", "type": "module",

View File

@@ -47,10 +47,11 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
### Installation ### Installation
```bash ```bash
# Download the latest release for your platform # One-line install (recommended)
curl -sSL https://code.foss.global/serve.zone/onebox/releases/latest/download/onebox-linux-x64 -o onebox curl -sSL https://code.foss.global/serve.zone/onebox/raw/branch/main/install.sh | sudo bash
chmod +x onebox
sudo mv onebox /usr/local/bin/ # Install a specific version
curl -sSL https://code.foss.global/serve.zone/onebox/raw/branch/main/install.sh | sudo bash -s -- --version v1.11.0
# Or install from npm # Or install from npm
pnpm install -g @serve.zone/onebox pnpm install -g @serve.zone/onebox
@@ -242,6 +243,13 @@ onebox config set cloudflareZoneID your-zone-id
onebox status onebox status
``` ```
### Upgrade
```bash
# Upgrade to the latest version (requires root)
sudo onebox upgrade
```
## Configuration 🔧 ## Configuration 🔧
### System Requirements ### System Requirements

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@serve.zone/onebox', name: '@serve.zone/onebox',
version: '1.12.0', version: '1.13.0',
description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers' description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers'
} }

File diff suppressed because one or more lines are too long

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@serve.zone/onebox', name: '@serve.zone/onebox',
version: '1.12.0', version: '1.13.0',
description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers' description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers'
} }