app
JLCPCB Parts Library
Public Made by Adomby adom
Check the JLCPCB / LCSC parts library before you fab — Basic vs Extended tier, LCSC stock and assembly pricing, so you avoid surprise feeder-setup fees. CLI, a Hydrogen app, and a shared backend.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
#!/usr/bin/env bash
# adom-jlcpcb service container bootstrap.
# Run ONCE on a freshly created default-light container.
# Usage: bash service/deploy.sh
#
# Unlike adom-mouser / adom-digikey (Rust backends proxying external APIs),
# JLCPCB is a Node.js HTTP server backed by a LOCAL 1.3GB SQLite + FTS5
# database (from CDFER/jlcpcb-parts-database). No API credentials needed —
# all queries run locally against the DB.
set -euo pipefail
REPO_URL="${ADOM_JLCPCB_REPO_URL:-https://github.com/adom-inc/adom-jlcpcb.git}"
REPO_DIR="${ADOM_JLCPCB_REPO:-$HOME/adom-jlcpcb}"
BACKEND_DIR="$REPO_DIR/service/backend"
PORT="${JLCPCB_PORT:-8774}"
ok() { printf ' \033[32m✓\033[0m %s\n' "$1"; }
info() { printf ' \033[2m%s\033[0m\n' "$1"; }
fail() { printf ' \033[31m✗\033[0m %s\n' "$1" >&2; exit 1; }
echo "== adom-jlcpcb service deploy =="
# 1. Prereqs
if ! command -v node >/dev/null; then
info "installing node + npm + build-essential + cron..."
sudo apt-get update -qq
sudo apt-get install -y -qq nodejs npm build-essential python3 cron jq >/dev/null
ok "node $(node --version) / npm $(npm --version)"
else
ok "node already present ($(node --version))"
fi
sudo service cron start >/dev/null 2>&1 || sudo systemctl start cron 2>/dev/null || true
if ! command -v cargo >/dev/null; then
info "installing rustup (for in-place CLI rebuilds; users pull the binary from wiki)..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
sh -s -- -y --default-toolchain stable --profile minimal >/dev/null 2>&1 || \
info "rustup install failed; CLI will only come from wiki"
[ -f "$HOME/.cargo/env" ] && . "$HOME/.cargo/env"
fi
# 2. Clone repo
if [ -d "$REPO_DIR/.git" ]; then
ok "repo already cloned at $REPO_DIR"
cd "$REPO_DIR" && git fetch --quiet origin main && git reset --hard origin/main
else
info "cloning $REPO_URL..."
git clone "$REPO_URL" "$REPO_DIR" || fail "git clone failed (is the repo private? set up gh auth first)"
ok "cloned to $REPO_DIR"
fi
# 3. Build + install Rust CLI (optional)
cd "$REPO_DIR"
if command -v cargo >/dev/null; then
info "building Rust CLI..."
cargo build --release >/dev/null 2>&1 && \
sudo install -m 0755 target/release/adom-jlcpcb /usr/local/bin/adom-jlcpcb && \
ok "installed /usr/local/bin/adom-jlcpcb ($(adom-jlcpcb --version))" || \
info "CLI build failed; consumer containers still get the binary from the wiki"
fi
# 4. Node backend deps + SQLite DB
cd "$BACKEND_DIR"
info "npm install (better-sqlite3 compiles natively — 1-2 min)..."
npm install --no-audit --no-fund --omit=dev 2>&1 | tail -1
ok "node_modules installed"
if [ ! -f "$BACKEND_DIR/jlcpcb-components.sqlite3" ]; then
info "downloading SQLite DB (~1.3GB, 2-5 min)..."
node setup-db.js
ok "SQLite DB ready"
else
ok "SQLite DB already present"
fi
# 5. Crons — watchdog + daily DB refresh + hourly smoke
WATCHDOG_CRON="*/2 * * * * $REPO_DIR/service/watchdog.sh >> /tmp/adom-jlcpcb-watchdog.log 2>&1"
DB_CRON="0 4 * * * JLCPCB_DB_PATH=$BACKEND_DIR/jlcpcb-components.sqlite3 $REPO_DIR/service/backend/cron/update-db.sh >> /tmp/adom-jlcpcb-db-refresh.log 2>&1"
SMOKE_CRON="15 * * * * $REPO_DIR/tests/cron-smoke.sh >> /tmp/adom-jlcpcb-smoke.log 2>&1"
(crontab -l 2>/dev/null | grep -v -E 'adom-jlcpcb|service/backend/cron/update-db' || true; \
echo "$WATCHDOG_CRON"; \
echo "$DB_CRON"; \
echo "$SMOKE_CRON") | crontab -
ok "crons installed (watchdog 2m · DB refresh daily 04:00 · smoke hourly :15)"
chmod +x "$REPO_DIR/service/watchdog.sh" "$REPO_DIR/service/backend/cron/update-db.sh" "$REPO_DIR/tests/cron-smoke.sh" "$REPO_DIR/tests/smoke.sh" 2>/dev/null || true
# 6. First launch + health check
info "running watchdog to start Node server..."
bash "$REPO_DIR/service/watchdog.sh" || true
sleep 5
HEALTH=$(curl -sf --max-time 10 "http://127.0.0.1:$PORT/health" || true)
[ -z "$HEALTH" ] && fail "Node server did not come up — check /tmp/adom-jlcpcb-server.log"
ok "Node backend healthy on port $PORT"
echo " $(echo "$HEALTH" | head -c 250)"
echo
echo "Next steps (run from your MAIN container):"
echo " 1. adom-cli carbon containers port-add <this-slug> --port $PORT --prefix jlcpcb"
echo " 2. curl the public URL + /health to confirm"