mirror of
https://github.com/BaaRai/ARTEX.git
synced 2026-11-13 11:40:53 +08:00
The Dockerfile copied a pre-built binary from dist/<arch>/artex into the runtime image, but dist/ is git-ignored, so a fresh `git clone` has no such file and `docker compose up -d --build` fails with "/dist/amd64/artex: not found". Build the binary from source in the image instead: a Node 22 stage runs the frontend static export, a Go 1.26 stage runs build.sh with the same flags as the release binaries job (CGO-free cross-compile, -trimpath, pinned version), and the runtime stage copies the compiled binary. No build-context binary is needed, so a clean clone builds. Drop the now-obsolete dist/ warning in install.sh.
133 lines
5.0 KiB
Bash
Executable File
133 lines
5.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ARTEX install script: 1) all-Docker 2) local build & run
|
|
set -euo pipefail
|
|
cd "$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
info(){ printf '\033[36m[*]\033[0m %s\n' "$*"; }
|
|
ok(){ printf '\033[32m[+]\033[0m %s\n' "$*"; }
|
|
warn(){ printf '\033[33m[!]\033[0m %s\n' "$*"; }
|
|
die(){ printf '\033[31m[x]\033[0m %s\n' "$*" >&2; exit 1; }
|
|
ask(){ local p="$1" d="${2:-}" a; read -rp "$p${d:+ [$d]}: " a; echo "${a:-$d}"; }
|
|
rand(){ head -c 18 /dev/urandom | base64 | tr -dc 'A-Za-z0-9' | head -c 24; }
|
|
# json_str prints $1 as a JSON string literal: backslash, double quote and the
|
|
# control characters read -r can return are escaped.
|
|
json_str(){
|
|
local s="$1"
|
|
s="${s//\\/\\\\}"; s="${s//\"/\\\"}"
|
|
s="${s//$'\t'/\\t}"; s="${s//$'\r'/\\r}"
|
|
printf '"%s"' "$s"
|
|
}
|
|
# sed_repl escapes $1 for the replacement side of s|...|...|: \, | and &.
|
|
sed_repl(){ printf '%s' "$1" | sed 's/[\\|&]/\\&/g'; }
|
|
|
|
# ── docker environment check / auto-install ───────────────────
|
|
ensure_docker(){
|
|
if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
|
|
ok "docker and docker compose detected"; return
|
|
fi
|
|
warn "docker / docker compose not detected"
|
|
case "$(uname -s)" in
|
|
Linux)
|
|
if [ "$(ask 'Install Docker automatically? (y/n)' y)" = y ]; then
|
|
curl -fsSL https://get.docker.com | sh
|
|
sudo usermod -aG docker "$USER" || true
|
|
ok "Docker installed (re-login required for the group change to take effect)"
|
|
else
|
|
die "please install docker yourself and retry"
|
|
fi ;;
|
|
Darwin) die "on macOS please install Docker Desktop: https://www.docker.com/products/docker-desktop/" ;;
|
|
*) die "please install docker yourself and retry" ;;
|
|
esac
|
|
}
|
|
|
|
# ── 1) All-Docker ───────────────────────────────
|
|
install_docker(){
|
|
ensure_docker
|
|
if [ ! -f .env ]; then
|
|
cp .env.example .env 2>/dev/null || true
|
|
local pw key
|
|
pw="$(ask 'Postgres password (press Enter to generate randomly)' "$(rand)")"
|
|
key="$(ask 'ANTHROPIC_API_KEY (may be empty, configure later in the UI)' '')"
|
|
sed -i.bak "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(sed_repl "$pw")|" .env
|
|
sed -i.bak "s|^ANTHROPIC_API_KEY=.*|ANTHROPIC_API_KEY=$(sed_repl "$key")|" .env
|
|
rm -f .env.bak
|
|
ok ".env generated (POSTGRES_PASSWORD set)"
|
|
else
|
|
info "reusing existing .env"
|
|
fi
|
|
info "building the image from this checkout and starting..."
|
|
docker compose up -d --build
|
|
ok "started → http://localhost:8787"
|
|
info "view logs: docker compose logs -f artex"
|
|
}
|
|
|
|
# ── 2) Local build & run ──────────────────────────────
|
|
install_local(){
|
|
echo "Database setup:"
|
|
echo " 1) Connect to an existing PostgreSQL"
|
|
echo " 2) Start a PostgreSQL with Docker (requires docker)"
|
|
case "$(ask 'Choose' 1)" in
|
|
2)
|
|
ensure_docker
|
|
local pw; pw="$(ask 'Postgres password (press Enter for random)' "$(rand)")"
|
|
docker run -d --name artex-pg -p 5432:5432 \
|
|
-e POSTGRES_USER=artex -e POSTGRES_PASSWORD="$pw" -e POSTGRES_DB=artex \
|
|
-v artex-pg:/var/lib/postgresql/data postgres:16-alpine
|
|
DB_HOST=127.0.0.1 DB_PORT=5432 DB_USER=artex DB_PASS="$pw" DB_NAME=artex DB_SSL=disable ;;
|
|
*)
|
|
DB_HOST="$(ask 'Database host' 127.0.0.1)"
|
|
DB_PORT="$(ask 'Port' 5432)"
|
|
DB_USER="$(ask 'User' artex)"
|
|
DB_PASS="$(ask 'Password' '')"
|
|
DB_NAME="$(ask 'Database name' artex)"
|
|
DB_SSL="$(ask 'sslmode (disable/require)' disable)" ;;
|
|
esac
|
|
|
|
# generate config.json (string values JSON-escaped: a password may contain " or \)
|
|
case "$DB_PORT" in (*[!0-9]*|'') die "port must be a number: $DB_PORT" ;; esac
|
|
cat > config.json <<JSON
|
|
{
|
|
"database": {
|
|
"host": $(json_str "$DB_HOST"),
|
|
"port": ${DB_PORT},
|
|
"user": $(json_str "$DB_USER"),
|
|
"password": $(json_str "$DB_PASS"),
|
|
"dbname": $(json_str "$DB_NAME"),
|
|
"sslmode": $(json_str "$DB_SSL")
|
|
}
|
|
}
|
|
JSON
|
|
ok "config.json generated"
|
|
|
|
# go environment check
|
|
command -v go >/dev/null 2>&1 || die "Go not detected; please install Go (>=1.26) first: https://go.dev/dl/"
|
|
ok "Go: $(go version)"
|
|
|
|
# embedding the frontend requires node to produce the static assets
|
|
if command -v npm >/dev/null 2>&1; then
|
|
info "building frontend static assets..."
|
|
( cd web && npm ci && npm run build:static )
|
|
rm -rf server/webui/dist && cp -r web/out server/webui/dist
|
|
info "compiling embedded single binary..."
|
|
CGO_ENABLED=0 go build -tags embedui -trimpath -o artex ./cmd/artex
|
|
else
|
|
warn "npm not detected: building a backend WITHOUT the embedded frontend (run npm run dev separately for the frontend)"
|
|
CGO_ENABLED=0 go build -o artex ./cmd/artex
|
|
fi
|
|
ok "build complete → ./artex"
|
|
|
|
info "starting... (Ctrl-C to exit)"
|
|
./artex
|
|
}
|
|
|
|
echo "=============================="
|
|
echo " ARTEX Install"
|
|
echo " 1) All-Docker install"
|
|
echo " 2) Run locally (go build)"
|
|
echo "=============================="
|
|
case "$(ask 'Choose' 1)" in
|
|
1) install_docker ;;
|
|
2) install_local ;;
|
|
*) die "invalid choice" ;;
|
|
esac
|