Add installer, CI, ARM build and test updates
Introduce a one‑line Docker installer and environment examples, add CI and docker validation workflows, and update docs and tests. Key changes: - Add docker/install.sh installer that bootstraps /opt/synapsis, downloads compose files, optionally installs Docker, and generates secrets. - Add top-level .env.example and docker/.env.example entries for shared storage and local development. - Add GitHub Actions CI (ci.yml) with type checks, targeted vitest runs, build and docker-compose validation. - Update existing docker workflow to set up QEMU and build multi‑arch images (amd64, arm64). - Update README and docker/README to use the installer, point to the new repo, adjust local setup instructions, and note shared S3 env vars. - Update docker-compose comments and include shared S3 env variables and defaults. - Update .gitignore to ignore site-work mirrors. - Tests: expand supported bot source types (add brave_news, youtube), increase POST_MAX_LENGTH from 400 to 600, add minimal user handle in mention handler tests, and add mocks & test adjustments in scheduler tests to keep them unit-scoped. These changes simplify installation, add CI coverage (including Docker config validation), enable multi‑arch builds, and align tests with expanded bot source/validation behavior.
This commit is contained in:
@@ -43,3 +43,16 @@ PORT=auto
|
||||
|
||||
# Maximum AI bots per user (default: 5)
|
||||
# BOT_MAX_PER_USER=5
|
||||
|
||||
# ===========================================
|
||||
# OPTIONAL: Shared S3 Storage
|
||||
# ===========================================
|
||||
# These are only needed if you want app-level shared storage defaults.
|
||||
# Most media storage is configured per user inside the app.
|
||||
|
||||
# STORAGE_ENDPOINT=
|
||||
# STORAGE_REGION=us-east-1
|
||||
# STORAGE_BUCKET=
|
||||
# STORAGE_ACCESS_KEY=
|
||||
# STORAGE_SECRET_KEY=
|
||||
# STORAGE_PUBLIC_BASE_URL=
|
||||
|
||||
+16
-19
@@ -7,13 +7,9 @@ Production Docker deployment using pre-built images from GitHub Container Regist
|
||||
## 🚀 Quick Start
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/synapsis && cd /opt/synapsis
|
||||
curl -O https://raw.githubusercontent.com/cyph3rasi/synapsis/main/docker-compose.yml
|
||||
curl -O https://raw.githubusercontent.com/cyph3rasi/synapsis/main/docker/Caddyfile
|
||||
curl -O https://raw.githubusercontent.com/cyph3rasi/synapsis/main/docker/caddy-entrypoint.sh
|
||||
curl -O https://raw.githubusercontent.com/cyph3rasi/synapsis/main/docker/.env.example
|
||||
cp .env.example .env
|
||||
nano .env # Add your domain and secrets
|
||||
curl -fsSL https://synapsis.social/install.sh | bash
|
||||
nano /opt/synapsis/.env # Add your domain and admin email
|
||||
cd /opt/synapsis
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
@@ -27,14 +23,7 @@ Your node is live at `https://your-domain.com` with automatic SSL.
|
||||
|-------------|---------|
|
||||
| **Server** | 2GB RAM, 2 CPU cores, 20GB SSD (minimum) |
|
||||
| **Domain** | A domain or subdomain pointing to your server |
|
||||
| **Docker** | Version 24.0+ with Docker Compose 2.20+ |
|
||||
|
||||
**Install Docker (Ubuntu/Debian):**
|
||||
```bash
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
sudo usermod -aG docker $USER
|
||||
newgrp docker
|
||||
```
|
||||
| **Docker** | Installed automatically by `install.sh` when missing on supported Linux hosts |
|
||||
|
||||
---
|
||||
|
||||
@@ -53,6 +42,15 @@ Optional (advanced):
|
||||
- `NEXT_PUBLIC_NODE_DOMAIN` to override the node domain (defaults to `DOMAIN`)
|
||||
- `NEXT_PUBLIC_APP_URL` to override the public app URL used by background jobs (auto-derived from the node domain)
|
||||
- `ALLOW_LOCALHOST=1` to allow `localhost` in production containers for local testing
|
||||
- Shared S3 storage env vars are available if you want app-level fallback storage
|
||||
|
||||
Optional shared storage env vars:
|
||||
- `STORAGE_ENDPOINT`
|
||||
- `STORAGE_REGION`
|
||||
- `STORAGE_BUCKET`
|
||||
- `STORAGE_ACCESS_KEY`
|
||||
- `STORAGE_SECRET_KEY`
|
||||
- `STORAGE_PUBLIC_BASE_URL`
|
||||
|
||||
**Port Configuration:**
|
||||
- `PORT=auto` (default) — Automatically finds an available port between 3000-3020
|
||||
@@ -131,8 +129,7 @@ docker compose exec caddy caddy validate --config /etc/caddy/Caddyfile
|
||||
# Verify image exists
|
||||
docker pull ghcr.io/cyph3rasi/synapsis:latest
|
||||
|
||||
# Check available tags at:
|
||||
# https://github.com/cyph3rasi/synapsis/pkgs/container/synapsis
|
||||
# Check the published package tags in GitHub Container Registry
|
||||
```
|
||||
|
||||
---
|
||||
@@ -166,9 +163,9 @@ echo "0 2 * * * /opt/synapsis/backup.sh" | sudo crontab -
|
||||
To build locally instead of using pre-built images:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/cyph3rasi/synapsis.git
|
||||
git clone https://github.com/GnosysLabs/Synapsis.git
|
||||
cd synapsis/docker
|
||||
docker compose -f docker-compose.build.yml up -d --build
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
REPO="${REPO:-GnosysLabs/Synapsis}"
|
||||
REF="${REF:-}"
|
||||
INSTALL_DIR="${1:-${INSTALL_DIR:-/opt/synapsis}}"
|
||||
REPO_API="https://api.github.com/repos/${REPO}"
|
||||
PUBLIC_INSTALL_URL="${PUBLIC_INSTALL_URL:-https://synapsis.social/install.sh}"
|
||||
|
||||
resolve_ref() {
|
||||
if [ -n "${REF}" ]; then
|
||||
REF_SOURCE="custom override"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "🔎 Resolving latest Synapsis release"
|
||||
latest_tag=$(
|
||||
curl -fsSL "${REPO_API}/releases/latest" 2>/dev/null \
|
||||
| sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' \
|
||||
| head -n 1
|
||||
)
|
||||
|
||||
if [ -n "${latest_tag}" ]; then
|
||||
REF="${latest_tag}"
|
||||
REF_SOURCE="latest GitHub release"
|
||||
return
|
||||
fi
|
||||
|
||||
REF="main"
|
||||
REF_SOURCE="main fallback"
|
||||
echo "⚠️ Could not resolve the latest release, falling back to ${REF}" >&2
|
||||
}
|
||||
|
||||
require_command() {
|
||||
if ! command -v "$1" >/dev/null 2>&1; then
|
||||
echo "❌ Required command not found: $1" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
download_file() {
|
||||
source_path="$1"
|
||||
target_path="$2"
|
||||
echo "⬇️ Downloading ${source_path}"
|
||||
curl -fsSL "${RAW_BASE}/${source_path}" -o "${target_path}"
|
||||
}
|
||||
|
||||
set_env_value() {
|
||||
file="$1"
|
||||
key="$2"
|
||||
value="$3"
|
||||
|
||||
escaped_value=$(printf '%s\n' "$value" | sed -e 's/[\/&]/\\&/g')
|
||||
sed -i.bak -E "s|^${key}=.*$|${key}=${escaped_value}|" "$file"
|
||||
rm -f "${file}.bak"
|
||||
}
|
||||
|
||||
generate_db_password() {
|
||||
openssl rand -base64 24 | tr -d '\n' | tr '/+' '_-' | cut -c1-32
|
||||
}
|
||||
|
||||
install_docker_if_needed() {
|
||||
if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
|
||||
echo "🐳 Docker is already installed"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "❌ Docker is not installed and this installer is not running as root." >&2
|
||||
echo " Re-run it as root or with sudo so Synapsis can install Docker for you." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🐳 Docker not found, installing Docker"
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl enable --now docker >/dev/null 2>&1 || true
|
||||
elif command -v service >/dev/null 2>&1; then
|
||||
service docker start >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "❌ Docker installation did not finish successfully." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker compose version >/dev/null 2>&1; then
|
||||
echo "⚠️ Docker was installed, but 'docker compose' is not available yet." >&2
|
||||
echo " Install the Docker Compose plugin before starting Synapsis." >&2
|
||||
fi
|
||||
}
|
||||
|
||||
require_command curl
|
||||
require_command chmod
|
||||
require_command mkdir
|
||||
require_command cp
|
||||
|
||||
resolve_ref
|
||||
RAW_BASE="https://raw.githubusercontent.com/${REPO}/${REF}"
|
||||
|
||||
echo "========================================"
|
||||
echo " Synapsis Docker Installer"
|
||||
echo "========================================"
|
||||
echo " Repo: ${REPO}"
|
||||
echo " Ref: ${REF} (${REF_SOURCE})"
|
||||
echo " Install dir: ${INSTALL_DIR}"
|
||||
echo "========================================"
|
||||
|
||||
install_docker_if_needed
|
||||
mkdir -p "${INSTALL_DIR}"
|
||||
|
||||
download_file "docker-compose.yml" "${INSTALL_DIR}/docker-compose.yml"
|
||||
download_file "docker/Caddyfile" "${INSTALL_DIR}/Caddyfile"
|
||||
download_file "docker/caddy-entrypoint.sh" "${INSTALL_DIR}/caddy-entrypoint.sh"
|
||||
download_file "docker/.env.example" "${INSTALL_DIR}/.env.example"
|
||||
|
||||
chmod 755 "${INSTALL_DIR}/caddy-entrypoint.sh"
|
||||
|
||||
if [ ! -f "${INSTALL_DIR}/.env" ]; then
|
||||
cp "${INSTALL_DIR}/.env.example" "${INSTALL_DIR}/.env"
|
||||
echo "📝 Created ${INSTALL_DIR}/.env"
|
||||
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
set_env_value "${INSTALL_DIR}/.env" "AUTH_SECRET" "$(openssl rand -hex 32)"
|
||||
set_env_value "${INSTALL_DIR}/.env" "DB_PASSWORD" "$(generate_db_password)"
|
||||
echo "🔐 Generated AUTH_SECRET and DB_PASSWORD"
|
||||
else
|
||||
echo "⚠️ openssl not found, leaving placeholder secrets in .env"
|
||||
fi
|
||||
|
||||
if [ -n "${DOMAIN:-}" ]; then
|
||||
set_env_value "${INSTALL_DIR}/.env" "DOMAIN" "${DOMAIN}"
|
||||
echo "🌐 Set DOMAIN=${DOMAIN}"
|
||||
fi
|
||||
|
||||
if [ -n "${ADMIN_EMAILS:-}" ]; then
|
||||
set_env_value "${INSTALL_DIR}/.env" "ADMIN_EMAILS" "${ADMIN_EMAILS}"
|
||||
echo "📧 Set ADMIN_EMAILS=${ADMIN_EMAILS}"
|
||||
fi
|
||||
else
|
||||
echo "📝 Existing ${INSTALL_DIR}/.env found, leaving it unchanged"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Review ${INSTALL_DIR}/.env"
|
||||
echo " 2. Start Synapsis:"
|
||||
echo " cd ${INSTALL_DIR} && docker compose up -d"
|
||||
echo ""
|
||||
echo "One-line usage examples:"
|
||||
echo " curl -fsSL ${PUBLIC_INSTALL_URL} | bash"
|
||||
echo " curl -fsSL ${PUBLIC_INSTALL_URL} | DOMAIN=synapsis.example.com ADMIN_EMAILS=you@example.com bash"
|
||||
Reference in New Issue
Block a user