Docs: fix self hosting local deploy protocol (#433)

* fix: skip Docker check in ensure-postgres.sh when remote DATABASE_URL is set

When DATABASE_URL points to a non-localhost host, the script now skips
all Docker operations and only verifies remote DB connectivity via
pg_isready directly.

* fix: honor DATABASE_URL for remote postgres preflight

* fix(make): clarify stop output for remote database

* docs: add local deployment protocol guidance to SELF_HOSTING.md

Clarify that local deployments without TLS should use http:// and ws://
instead of https:// and wss://.

---------

Co-authored-by: Junlong Liu <junlong.liu@shopee.com>
This commit is contained in:
Junlong 2026-04-07 14:08:06 +08:00 committed by GitHub
parent d450b3d454
commit 0263ecce9e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 91 additions and 16 deletions

View file

@ -69,7 +69,12 @@ stop:
@echo "Stopping services..."
@-lsof -ti:$(PORT) | xargs kill -9 2>/dev/null
@-lsof -ti:$(FRONTEND_PORT) | xargs kill -9 2>/dev/null
@echo "✓ App processes stopped. Shared PostgreSQL is still running on localhost:5432."
@case "$(DATABASE_URL)" in \
""|*@localhost:*|*@localhost/*|*@127.0.0.1:*|*@127.0.0.1/*|*@\[::1\]:*|*@\[::1\]/*) \
echo "✓ App processes stopped. Shared PostgreSQL is still running on localhost:$(POSTGRES_PORT)." ;; \
*) \
echo "✓ App processes stopped. Remote PostgreSQL was not affected." ;; \
esac
# Full verification: typecheck + unit tests + Go tests + E2E
check:

View file

@ -257,8 +257,14 @@ Each team member who wants to run AI agents locally needs to:
```bash
# Point CLI to your server
#
# For production deployments with TLS:
export MULTICA_APP_URL=https://app.example.com
export MULTICA_SERVER_URL=wss://api.example.com/ws
#
# For local deployments without TLS:
# export MULTICA_APP_URL=http://localhost:3000
# export MULTICA_SERVER_URL=ws://localhost:8080/ws
# Login (opens browser)
multica login
@ -267,6 +273,8 @@ Each team member who wants to run AI agents locally needs to:
multica daemon start
```
> **Note:** Use `https://` and `wss://` for production deployments behind a TLS-terminating reverse proxy. For local or development deployments without TLS, use `http://` and `ws://` instead.
The daemon auto-detects installed agent CLIs and registers itself with the server. When an agent is assigned a task in Multica, the daemon picks it up, creates an isolated workspace, runs the agent, and reports results back.
## Upgrading

View file

@ -17,26 +17,88 @@ set +a
POSTGRES_DB="${POSTGRES_DB:-multica}"
POSTGRES_USER="${POSTGRES_USER:-multica}"
POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-multica}"
DATABASE_URL="${DATABASE_URL:-}"
export PGPASSWORD="$POSTGRES_PASSWORD"
echo "==> Ensuring shared PostgreSQL container is running on localhost:5432..."
docker compose up -d postgres
db_host=""
db_port="${POSTGRES_PORT:-5432}"
db_name="$POSTGRES_DB"
echo "==> Waiting for PostgreSQL to be ready..."
until docker compose exec -T postgres pg_isready -U "$POSTGRES_USER" -d postgres > /dev/null 2>&1; do
sleep 1
done
parse_database_url() {
local rest authority hostport path port_part
echo "==> Ensuring database '$POSTGRES_DB' exists..."
db_exists="$(docker compose exec -T postgres \
psql -U "$POSTGRES_USER" -d postgres -Atqc "SELECT 1 FROM pg_database WHERE datname = '$POSTGRES_DB'")"
rest="${DATABASE_URL#*://}"
rest="${rest%%\?*}"
authority="${rest%%/*}"
path="${rest#*/}"
if [ "$db_exists" != "1" ]; then
docker compose exec -T postgres \
psql -U "$POSTGRES_USER" -d postgres -v ON_ERROR_STOP=1 \
-c "CREATE DATABASE \"$POSTGRES_DB\"" \
> /dev/null
if [ "$authority" = "$rest" ]; then
path=""
fi
hostport="${authority##*@}"
if [[ "$hostport" == \[* ]]; then
db_host="${hostport#\[}"
db_host="${db_host%%]*}"
port_part="${hostport#*\]}"
if [[ "$port_part" == :* ]] && [ -n "${port_part#:}" ]; then
db_port="${port_part#:}"
fi
else
db_host="${hostport%%:*}"
if [[ "$hostport" == *:* ]] && [ -n "${hostport##*:}" ]; then
db_port="${hostport##*:}"
fi
fi
if [ -n "$path" ]; then
db_name="${path%%/*}"
fi
}
if [ -n "$DATABASE_URL" ]; then
parse_database_url
fi
echo "✓ PostgreSQL ready. Application database: $POSTGRES_DB"
is_local() {
[ -z "$DATABASE_URL" ] || [ "$db_host" = "localhost" ] || [ "$db_host" = "127.0.0.1" ] || [ "$db_host" = "::1" ]
}
if is_local; then
# ---------- Local: use Docker ----------
echo "==> Ensuring shared PostgreSQL container is running on localhost:5432..."
docker compose up -d postgres
echo "==> Waiting for PostgreSQL to be ready..."
until docker compose exec -T postgres pg_isready -U "$POSTGRES_USER" -d postgres > /dev/null 2>&1; do
sleep 1
done
echo "==> Ensuring database '$POSTGRES_DB' exists..."
db_exists="$(docker compose exec -T postgres \
psql -U "$POSTGRES_USER" -d postgres -Atqc "SELECT 1 FROM pg_database WHERE datname = '$POSTGRES_DB'")"
if [ "$db_exists" != "1" ]; then
docker compose exec -T postgres \
psql -U "$POSTGRES_USER" -d postgres -v ON_ERROR_STOP=1 \
-c "CREATE DATABASE \"$POSTGRES_DB\"" \
> /dev/null
fi
echo "✓ PostgreSQL ready (local Docker). Database: $POSTGRES_DB"
else
# ---------- Remote: skip Docker, verify connectivity ----------
echo "==> Remote database detected (host: $db_host). Skipping Docker."
if command -v pg_isready > /dev/null 2>&1; then
echo "==> Waiting for PostgreSQL at $db_host:$db_port to be ready..."
until pg_isready -d "$DATABASE_URL" > /dev/null 2>&1; do
sleep 1
done
echo "✓ PostgreSQL ready (remote: $db_host:$db_port). Database: $db_name"
else
echo "==> pg_isready not found. Skipping remote connectivity preflight."
echo "✓ PostgreSQL configured (remote: $db_host:$db_port). Database: $db_name"
fi
fi