2026-03-06 20:14:50 +07:00
|
|
|
#!/bin/bash
|
|
|
|
|
set -e
|
|
|
|
|
|
fix(install): unblock self-hosting + drop forced wokwi clones
Resolves several install pain points reported by users (#108, #120) and
removes the obligatory upstream-clone step that confused contributors and
slowed down every Docker build.
Install fixes:
- nginx: server_name → catch-all default_server, drop Debian's stock site
so reverse-proxied users no longer get the "Welcome to nginx" page.
- entrypoint: auto-generate SECRET_KEY at first boot, persisted under
data/.secret_key. backend/.env is now optional in docker-compose.yml.
- backend: add greenlet>=3.0.0 (SQLAlchemy async dep that was missing on
some Python builds — caused uvicorn startup failures on WSL).
Wokwi libs come from npm:
- @wokwi/elements 1.9.2, avr8js 0.21.0, rp2040js 1.3.2 are pinned in
frontend/package.json. Vite aliases removed.
- Dockerfile.standalone no longer clones avr8js / rp2040js / wokwi-elements
/ wokwi-boards. Frontend stage is just COPY + npm install + build:docker.
- Board SVGs vendored under frontend/public/boards/ (10 deduped against
existing files, 2 truly new). third-party/wokwi-* clones become reference-
only credits — generate-component-metadata.ts skips gracefully when absent.
Production config split out:
- docker-compose.prod.yml, deploy/nginx.prod.conf, nginx-host-velxio*.conf,
update-third-party.bat removed. Production deployment lives in its own
repo: https://github.com/velxio/velxio-prod (host nginx + HTTPS + backups
+ pinned upstream commit).
Verified locally: 1161 frontend tests pass, build:docker completes clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 10:04:11 +07:00
|
|
|
# Auto-generate SECRET_KEY if not provided so the app boots out-of-the-box
|
|
|
|
|
# without requiring the user to create backend/.env first. Persists in the
|
|
|
|
|
# data volume so JWTs survive container restarts.
|
|
|
|
|
if [ -z "$SECRET_KEY" ]; then
|
|
|
|
|
SECRET_FILE="${DATA_DIR:-/app/data}/.secret_key"
|
|
|
|
|
mkdir -p "$(dirname "$SECRET_FILE")"
|
|
|
|
|
if [ ! -f "$SECRET_FILE" ]; then
|
|
|
|
|
echo "🔑 No SECRET_KEY provided — generating one (saved to $SECRET_FILE)"
|
|
|
|
|
head -c 48 /dev/urandom | base64 | tr -d '\n' > "$SECRET_FILE"
|
|
|
|
|
fi
|
|
|
|
|
export SECRET_KEY="$(cat "$SECRET_FILE")"
|
|
|
|
|
fi
|
|
|
|
|
|
2026-03-25 04:33:21 +07:00
|
|
|
# Ensure arduino-cli config and board manager URLs are set up
|
2026-03-25 03:30:56 +07:00
|
|
|
if [ ! -f /root/.arduino15/arduino-cli.yaml ]; then
|
2026-03-25 04:33:21 +07:00
|
|
|
echo "📦 Initializing arduino-cli config..."
|
2026-03-25 04:06:19 +07:00
|
|
|
arduino-cli config init 2>/dev/null || true
|
|
|
|
|
arduino-cli config add board_manager.additional_urls \
|
|
|
|
|
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json 2>/dev/null || true
|
|
|
|
|
arduino-cli config add board_manager.additional_urls \
|
|
|
|
|
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json 2>/dev/null || true
|
2026-04-29 10:21:26 +07:00
|
|
|
# ATTinyCore (Spence Konde) — needed for ATtiny85 FQBNs.
|
|
|
|
|
# Without this URL `core install ATTinyCore:avr` fails with
|
|
|
|
|
# "Platform 'ATTinyCore:avr' not found: platform not installed".
|
|
|
|
|
# See https://github.com/SpenceKonde/ATTinyCore
|
|
|
|
|
arduino-cli config add board_manager.additional_urls \
|
|
|
|
|
http://drazzy.com/package_drazzy.com_index.json 2>/dev/null || true
|
2026-05-31 10:17:23 +07:00
|
|
|
# STM32duino (STMicroelectronics:stm32) — needed for STM32 Blue/Black Pill
|
|
|
|
|
# FQBNs. Without this URL `core install STMicroelectronics:stm32` fails with
|
|
|
|
|
# "Platform 'STMicroelectronics:stm32' not found: platform not installed".
|
|
|
|
|
arduino-cli config add board_manager.additional_urls \
|
|
|
|
|
https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json 2>/dev/null || true
|
2026-03-25 03:30:56 +07:00
|
|
|
fi
|
|
|
|
|
|
2026-07-17 11:41:44 +07:00
|
|
|
# Seed board-manager indexes vendored into the image (issue #254).
|
|
|
|
|
# A /root/.arduino15 volume created by an older image can lack an index
|
|
|
|
|
# file that the config references; arduino-cli then fails instance init
|
|
|
|
|
# outright, which breaks EVERY compile — not just the boards from that
|
|
|
|
|
# index. A stale index is harmless, a missing one is fatal, so copy any
|
|
|
|
|
# vendored index the volume does not already have. `core update-index`
|
|
|
|
|
# below still refreshes whatever is reachable.
|
|
|
|
|
if [ -d /opt/arduino15-seed ]; then
|
|
|
|
|
for seed in /opt/arduino15-seed/package_*.json; do
|
|
|
|
|
[ -f "$seed" ] || continue
|
|
|
|
|
dest="/root/.arduino15/$(basename "$seed")"
|
|
|
|
|
if [ ! -f "$dest" ]; then
|
|
|
|
|
echo "Seeding board index $(basename "$seed") (missing from volume)"
|
|
|
|
|
cp "$seed" "$dest"
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
2026-03-25 06:39:56 +07:00
|
|
|
# Install missing cores.
|
2026-03-25 04:33:21 +07:00
|
|
|
# ESP32 core MUST be 2.0.17 (IDF 4.4.x) — newer 3.x is incompatible with QEMU ROM bins.
|
|
|
|
|
arduino-cli core update-index 2>/dev/null || true
|
|
|
|
|
arduino-cli core install arduino:avr 2>/dev/null || true
|
|
|
|
|
arduino-cli core install rp2040:rp2040 2>/dev/null || true
|
2026-05-22 20:15:53 +07:00
|
|
|
arduino-cli core install ATTinyCore:avr@1.4.1 2>/dev/null || true
|
2026-05-31 10:17:23 +07:00
|
|
|
arduino-cli core install STMicroelectronics:stm32 2>/dev/null || true
|
2026-03-25 06:39:56 +07:00
|
|
|
|
2026-04-01 06:53:56 +07:00
|
|
|
# ESP32 compilation now uses ESP-IDF instead of arduino-cli.
|
|
|
|
|
# arduino-cli ESP32 core is no longer needed for QEMU-compatible builds.
|
|
|
|
|
# If ESP-IDF is not available, fall back to arduino-cli ESP32 core.
|
|
|
|
|
if [ -f /opt/esp-idf/export.sh ]; then
|
|
|
|
|
echo "🔧 Sourcing ESP-IDF environment..."
|
2026-04-01 12:18:35 +07:00
|
|
|
. /opt/esp-idf/export.sh || true
|
2026-04-01 06:53:56 +07:00
|
|
|
echo "✅ ESP-IDF $(cat /opt/esp-idf/version.txt 2>/dev/null || echo 'unknown') ready"
|
|
|
|
|
else
|
|
|
|
|
echo "⚠️ ESP-IDF not found — falling back to arduino-cli for ESP32"
|
|
|
|
|
ESP32_VER=$(arduino-cli core list 2>/dev/null | grep esp32:esp32 | awk '{print $2}')
|
|
|
|
|
if [ -z "$ESP32_VER" ]; then
|
|
|
|
|
echo "📦 Installing ESP32 core 2.0.17..."
|
|
|
|
|
arduino-cli core install esp32:esp32@2.0.17
|
|
|
|
|
elif [[ "$ESP32_VER" != 2.0.17 ]]; then
|
|
|
|
|
echo "⚠️ ESP32 core is $ESP32_VER, need 2.0.17 — reinstalling..."
|
|
|
|
|
arduino-cli core install esp32:esp32@2.0.17
|
|
|
|
|
fi
|
2026-03-25 06:39:56 +07:00
|
|
|
fi
|
2026-03-25 04:33:21 +07:00
|
|
|
|
2026-03-06 20:14:50 +07:00
|
|
|
# Start FastAPI backend in the background on port 8001
|
|
|
|
|
echo "🚀 Starting Velxio Backend..."
|
|
|
|
|
uvicorn app.main:app --host 127.0.0.1 --port 8001 &
|
2026-04-16 10:57:30 +07:00
|
|
|
UVICORN_PID=$!
|
2026-03-06 20:14:50 +07:00
|
|
|
|
2026-04-16 10:57:30 +07:00
|
|
|
# Wait for backend to be healthy before starting nginx
|
2026-03-06 20:14:50 +07:00
|
|
|
sleep 2
|
|
|
|
|
|
2026-04-16 10:57:30 +07:00
|
|
|
# Start Nginx in the background (not exec — we need to monitor both)
|
2026-03-06 20:14:50 +07:00
|
|
|
echo "🌐 Starting Nginx Web Server on port 80..."
|
2026-04-16 10:57:30 +07:00
|
|
|
nginx -g "daemon off;" &
|
|
|
|
|
NGINX_PID=$!
|
|
|
|
|
|
|
|
|
|
# Exit as soon as either process dies so Docker can restart the container.
|
|
|
|
|
# wait -n requires bash 4.3+ (standard on Debian Bullseye / Ubuntu 20.04+).
|
|
|
|
|
wait -n $UVICORN_PID $NGINX_PID
|
|
|
|
|
EXIT_CODE=$?
|
|
|
|
|
|
|
|
|
|
echo "⚠️ A process exited (code $EXIT_CODE) — shutting down container"
|
|
|
|
|
kill $UVICORN_PID $NGINX_PID 2>/dev/null || true
|
|
|
|
|
wait $UVICORN_PID $NGINX_PID 2>/dev/null || true
|
|
|
|
|
exit $EXIT_CODE
|