Merge 87b1a75df0 into 9aab48ec64
commit
36051b8cb7
|
|
@ -0,0 +1,74 @@
|
|||
# DevContainer for Velxio
|
||||
|
||||
This devcontainer provides a ready-to-use development environment for Velxio with:
|
||||
|
||||
- Python 3.12 + FastAPI backend setup
|
||||
- Node.js 20 + React/Vite frontend setup
|
||||
- arduino-cli with AVR and RP2040 cores
|
||||
- Built wokwi-libs (avr8js, rp2040js, wokwi-elements)
|
||||
- Persistent volumes for node_modules and arduino cache
|
||||
|
||||
## What's Included
|
||||
|
||||
### Automatically Installed
|
||||
- **Arduino AVR** — Arduino Uno, Nano, Mega emulation
|
||||
- **RP2040** — Raspberry Pi Pico / Pico W emulation
|
||||
- **Frontend tooling** — TypeScript, ESLint, Tailwind CSS
|
||||
- **Backend tooling** — Python virtual environment with all dependencies
|
||||
|
||||
### Not Included (Manual Setup)
|
||||
- **ESP32 Emulation (QEMU)** — Requires platform-specific compilation
|
||||
|
||||
## Why ESP32 QEMU is Manual
|
||||
|
||||
ESP32 emulation requires building QEMU from the lcgamboa fork, which:
|
||||
- Takes 15-30 minutes to compile
|
||||
- Requires platform-specific tools (MSYS2 on Windows, build-essential on Linux)
|
||||
- Generates 40-60 MB libraries excluded from git
|
||||
- Is optional — AVR and RP2040 work without it
|
||||
|
||||
**For Docker users:** ESP32 emulation is pre-built and included in the official image.
|
||||
|
||||
**For development:** If you need ESP32 emulation, see [docs/ESP32_EMULATION.md](../docs/ESP32_EMULATION.md)
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. Open this repository in VS Code with the Dev Containers extension
|
||||
2. VS Code will automatically build and start the devcontainer
|
||||
3. Wait for `post-create.sh` to complete (~5-6 minutes)
|
||||
4. Start the backend: `cd backend && source venv/bin/activate && uvicorn app.main:app --reload --port 8001`
|
||||
5. Start the frontend: `cd frontend && npm run dev`
|
||||
6. Open http://localhost:5173
|
||||
|
||||
## Optimization Notes
|
||||
|
||||
- **Shallow clones** — wokwi-libs use `--depth=1` for faster setup (not recursive submodules)
|
||||
- **Parallel builds** — Backend, frontend, and wokwi-libs build concurrently
|
||||
- **Volume mounts** — node_modules and arduino cache persist between rebuilds
|
||||
- **User-local tools** — arduino-cli installs to `~/.local/bin` (no sudo required)
|
||||
|
||||
## Ports Forwarded
|
||||
|
||||
- **5173** — Frontend (Vite dev server)
|
||||
- **8001** — Backend (FastAPI)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Builds are slow
|
||||
First-time setup takes 5-6 minutes. Subsequent container starts use `post-start.sh` which only syncs dependencies (~30 seconds).
|
||||
|
||||
### Permission errors on volumes
|
||||
The `post-create.sh` script fixes ownership automatically. If you still see errors, rebuild the container.
|
||||
|
||||
### Arduino cores missing
|
||||
Check that arduino-cli is in PATH:
|
||||
```bash
|
||||
arduino-cli version
|
||||
arduino-cli core list # should show arduino:avr and rp2040:rp2040
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Getting Started](../docs/getting-started.md) — Manual setup instructions
|
||||
- [ESP32 Emulation](../docs/ESP32_EMULATION.md) — Full ESP32 setup guide
|
||||
- [Architecture](../docs/ARCHITECTURE.md) — Project architecture overview
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"name": "Velxio",
|
||||
"image": "mcr.microsoft.com/devcontainers/python:3.12",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": "20",
|
||||
"installGlobally": true
|
||||
}
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-python.python",
|
||||
"ms-vscode.vscode-typescript-next",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"bradlc.vscode-tailwindcss"
|
||||
]
|
||||
}
|
||||
},
|
||||
"remoteUser": "vscode",
|
||||
"waitFor": "postCreateCommand",
|
||||
"mounts": [
|
||||
"source=velxio-arduino-cache,target=/home/vscode/.arduino15,type=volume",
|
||||
"source=velxio-frontend-nodemodules,target=${containerWorkspaceFolder}/frontend/node_modules,type=volume"
|
||||
],
|
||||
"postCreateCommand": "bash .devcontainer/post-create.sh",
|
||||
"postStartCommand": "bash .devcontainer/post-start.sh",
|
||||
"remoteEnv": {
|
||||
"PATH": "${containerEnv:PATH}:/home/vscode/.local/bin:${containerWorkspaceFolder}/frontend/node_modules/.bin:${containerWorkspaceFolder}/backend/venv/bin"
|
||||
},
|
||||
"forwardPorts": [5173, 8001],
|
||||
"portsAttributes": {
|
||||
"5173": {
|
||||
"label": "Frontend (Vite)",
|
||||
"onAutoForward": "notify"
|
||||
},
|
||||
"8001": {
|
||||
"label": "Backend (FastAPI)",
|
||||
"onAutoForward": "notify"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Get the workspace root (devcontainer sets this as pwd, but we can also derive it from script location)
|
||||
WORKSPACE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$WORKSPACE_ROOT"
|
||||
|
||||
# Get current user dynamically
|
||||
CURRENT_USER=$(whoami)
|
||||
|
||||
echo "==> Fixing ownership for mounted volumes..."
|
||||
for d in frontend/node_modules wokwi-libs/avr8js/node_modules wokwi-libs/rp2040js/node_modules wokwi-libs/wokwi-elements/node_modules "$HOME/.arduino15"; do
|
||||
sudo chown -R "$CURRENT_USER:$CURRENT_USER" "$d" 2>/dev/null || true
|
||||
done
|
||||
|
||||
echo "==> Cloning wokwi-libs (shallow, faster than submodules)..."
|
||||
# Only clone the 3 libs we actually use (avr8js, rp2040js, wokwi-elements)
|
||||
# Shallow clone with --depth=1 is much faster than recursive submodule init
|
||||
for lib in avr8js rp2040js wokwi-elements wokwi-boards; do
|
||||
if [ ! -d "wokwi-libs/$lib/.git" ]; then
|
||||
rm -rf "wokwi-libs/$lib"
|
||||
git clone --depth=1 "https://github.com/wokwi/$lib.git" "wokwi-libs/$lib"
|
||||
else
|
||||
echo " -> wokwi-libs/$lib already exists, skipping clone"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "==> Installing arduino-cli (user-local)..."
|
||||
if ! command -v arduino-cli &> /dev/null; then
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR="$HOME/.local/bin" sh
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
fi
|
||||
|
||||
echo "==> Installing Arduino cores (this may take a few minutes)..."
|
||||
arduino-cli core update-index
|
||||
if ! arduino-cli core list | grep -q "arduino:avr"; then
|
||||
arduino-cli core install arduino:avr
|
||||
fi
|
||||
|
||||
# Add RP2040 board manager (guard against duplicates)
|
||||
if ! arduino-cli config get board_manager.additional_urls | grep -q "rp2040"; then
|
||||
arduino-cli config add board_manager.additional_urls https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
|
||||
fi
|
||||
if ! arduino-cli core list | grep -q "rp2040:rp2040"; then
|
||||
arduino-cli core install rp2040:rp2040
|
||||
fi
|
||||
|
||||
# Note: ESP32 emulation (QEMU lcgamboa) is NOT installed by this script.
|
||||
# It requires platform-specific builds (MSYS2 on Windows, 15-30 min compile time)
|
||||
# and generates 40-60 MB libraries that are excluded from git.
|
||||
# - Docker images include pre-built QEMU libs automatically
|
||||
# - Development without ESP32 emulation works fine (AVR/RP2040 only)
|
||||
# - For full ESP32 support, see: docs/ESP32_EMULATION.md
|
||||
# - Backend auto-detects and falls back to UART-only mode if libs are missing
|
||||
|
||||
echo "==> Installing root dependencies (tsx, typescript for build scripts)..."
|
||||
HUSKY=0 npm install &
|
||||
ROOT_PID=$!
|
||||
|
||||
echo "==> Setting up Python virtual environment (base layer)..."
|
||||
(cd backend
|
||||
python3 -m venv venv
|
||||
./venv/bin/pip install wheel setuptools
|
||||
./venv/bin/pip install -r requirements.txt) &
|
||||
BACKEND_PID=$!
|
||||
|
||||
echo "==> Installing frontend dependencies..."
|
||||
(cd frontend
|
||||
HUSKY=0 npm install) &
|
||||
FRONTEND_PID=$!
|
||||
|
||||
echo "==> Building wokwi-libs in parallel (avr8js, rp2040js, wokwi-elements)..."
|
||||
# Local wokwi-libs are cloned from GitHub instead of using npm packages.
|
||||
# This allows us to modify the emulators and components for Velxio-specific behavior.
|
||||
# Build outputs go to dist/ directories and are resolved via Vite aliases.
|
||||
(cd wokwi-libs/avr8js
|
||||
HUSKY=0 npm install
|
||||
npm run build) &
|
||||
AVR_PID=$!
|
||||
|
||||
(cd wokwi-libs/rp2040js
|
||||
HUSKY=0 npm install
|
||||
npm run build) &
|
||||
RP2040_PID=$!
|
||||
|
||||
(cd wokwi-libs/wokwi-elements
|
||||
HUSKY=0 npm install
|
||||
npm run build) &
|
||||
ELEMENTS_PID=$!
|
||||
|
||||
echo " -> Waiting for all parallel builds to complete..."
|
||||
wait $ROOT_PID && echo " ✓ Root deps installed"
|
||||
wait $BACKEND_PID && echo " ✓ Backend deps installed"
|
||||
wait $FRONTEND_PID && echo " ✓ Frontend deps installed"
|
||||
wait $AVR_PID && echo " ✓ avr8js built"
|
||||
wait $RP2040_PID && echo " ✓ rp2040js built"
|
||||
wait $ELEMENTS_PID && echo " ✓ wokwi-elements built"
|
||||
|
||||
echo "==> Dev environment ready!"
|
||||
echo ""
|
||||
echo "To start development:"
|
||||
echo " Backend: cd backend && source venv/bin/activate && uvicorn app.main:app --reload --port 8001"
|
||||
echo " Frontend: cd frontend && npm run dev"
|
||||
echo ""
|
||||
echo "Note: AVR/RP2040 emulation is ready. For ESP32 emulation (QEMU), see docs/ESP32_EMULATION.md"
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Get the workspace root
|
||||
WORKSPACE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$WORKSPACE_ROOT"
|
||||
|
||||
# Get current user dynamically
|
||||
CURRENT_USER=$(whoami)
|
||||
|
||||
echo "==> Fixing ownership for mounted volumes..."
|
||||
sudo chown -R "$CURRENT_USER:$CURRENT_USER" frontend/node_modules 2>/dev/null || true
|
||||
|
||||
echo "==> Syncing Python dependencies..."
|
||||
(cd backend
|
||||
source venv/bin/activate
|
||||
pip install -q -r requirements.txt)
|
||||
|
||||
echo "==> Syncing frontend dependencies..."
|
||||
cd frontend
|
||||
HUSKY=0 npm install
|
||||
|
|
@ -13,3 +13,12 @@
|
|||
[submodule "wokwi-libs/wokwi-features"]
|
||||
path = wokwi-libs/wokwi-features
|
||||
url = https://github.com/wokwi/wokwi-features.git
|
||||
|
||||
[submodule "wokwi-libs/wokwi-boards"]
|
||||
path = wokwi-libs/wokwi-boards
|
||||
url = https://github.com/wokwi/wokwi-boards.git
|
||||
|
||||
[submodule "wokwi-libs/qemu-lcgamboa"]
|
||||
path = wokwi-libs/qemu-lcgamboa
|
||||
url = https://github.com/lcgamboa/qemu.git
|
||||
branch = picsimlab-esp32
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
.PHONY: help dev dev-backend dev-frontend install clean
|
||||
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
help: ## Show available commands
|
||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " %-15s %s\n", $$1, $$2}'
|
||||
|
||||
dev: ## Start backend and frontend (requires tmux)
|
||||
@if command -v tmux >/dev/null 2>&1; then \
|
||||
tmux new-session -d -s velxio 'make dev-backend' \; split-window -h 'make dev-frontend' \; attach; \
|
||||
else \
|
||||
echo "Install tmux or run 'make dev-backend' and 'make dev-frontend' in separate terminals"; \
|
||||
fi
|
||||
|
||||
dev-backend: ## Start backend (port 8001)
|
||||
@cd backend && . venv/bin/activate && uvicorn app.main:app --reload --host 0.0.0.0 --port 8001
|
||||
|
||||
dev-frontend: ## Start frontend (port 5173)
|
||||
@cd frontend && npm run dev
|
||||
|
||||
install: ## Install dependencies
|
||||
@echo "Installing root dependencies (tsx, typescript for build scripts)..."
|
||||
@npm install
|
||||
@echo "Cloning wokwi-libs (shallow)..."
|
||||
@for lib in avr8js rp2040js wokwi-elements; do \
|
||||
if [ ! -d "wokwi-libs/$$lib/.git" ]; then \
|
||||
rm -rf "wokwi-libs/$$lib"; \
|
||||
git clone --depth=1 "https://github.com/wokwi/$$lib.git" "wokwi-libs/$$lib"; \
|
||||
fi; \
|
||||
done
|
||||
@echo "Installing backend dependencies..."
|
||||
@cd backend && python3 -m venv venv && . venv/bin/activate && pip install -r requirements.txt
|
||||
@echo "Installing frontend dependencies..."
|
||||
@cd frontend && npm install
|
||||
@echo "Building wokwi-libs..."
|
||||
@for lib in avr8js rp2040js wokwi-elements; do \
|
||||
echo "Building $$lib..."; \
|
||||
cd "wokwi-libs/$$lib" && npm install && npm run build && cd ../..; \
|
||||
done
|
||||
@echo "✓ All dependencies installed"
|
||||
|
||||
clean: ## Remove venv and node_modules
|
||||
@rm -rf backend/venv frontend/node_modules node_modules
|
||||
|
|
@ -292,6 +292,12 @@ docker compose -f docker-compose.prod.yml up -d
|
|||
git clone https://github.com/davidmonterocrespo24/velxio.git
|
||||
cd velxio
|
||||
|
||||
# With Makefile (Linux/macOS)
|
||||
make install
|
||||
make dev-backend
|
||||
make dev-frontend
|
||||
|
||||
# Or manually:
|
||||
# Backend
|
||||
cd backend
|
||||
python -m venv venv && source venv/bin/activate # Windows: venv\Scripts\activate
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ export default defineConfig({
|
|||
},
|
||||
},
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
port: 5173,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:8001',
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 33cc9a8740071031e30704141d2803b308ce0d32
|
||||
Loading…
Reference in New Issue