Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
01ca850
client sdk local emulator
BilalG1 Mar 13, 2026
f8fcf9d
Squashed commit of the following:
mantrakp04 Mar 18, 2026
0010642
Refactor QEMU emulator setup and consolidate cloud-init configurations
mantrakp04 Mar 18, 2026
c2e4698
Refactor local emulator configuration management and remove obsolete …
mantrakp04 Mar 18, 2026
4508f24
Enhance Dockerfile for local emulator and server setup
mantrakp04 Mar 19, 2026
dec62a0
Refactor QEMU emulator build and snapshot handling
mantrakp04 Mar 19, 2026
580ff10
Refactor local emulator setup and consolidate services
mantrakp04 Mar 19, 2026
e3592bb
Add base image fingerprinting for QEMU snapshots
mantrakp04 Mar 19, 2026
5a729ec
Enhance configuration and permissions in local emulator setup
mantrakp04 Mar 19, 2026
c1a15ff
Enhance local emulator configuration and file management
mantrakp04 Mar 19, 2026
0496cd2
Add QEMU emulator build workflow and emulator command integration
mantrakp04 Mar 19, 2026
4a43a88
Update emulator configuration and enhance CLI functionality
mantrakp04 Mar 19, 2026
fe16a71
Merge branch 'dev' into emu-with-a-q
mantrakp04 Mar 19, 2026
5d98b44
Remove deprecated configuration files and streamline emulator CLI com…
mantrakp04 Mar 19, 2026
3321e5c
Update QEMU emulator scripts to improve KVM detection and service sta…
mantrakp04 Mar 19, 2026
8336d48
Refactor local emulator type handling and architecture detection
mantrakp04 Mar 19, 2026
298062a
Enhance local emulator configuration handling and file management
mantrakp04 Mar 19, 2026
25f8b1c
Gate server and admin emulator requests on credential init
BilalG1 Mar 19, 2026
578593a
Enhance QEMU emulator build workflow and local emulator configuration
mantrakp04 Mar 19, 2026
80ee1ab
Merge branch 'dev' into emu-with-a-q
mantrakp04 Mar 19, 2026
42bc125
Enhance setBranchConfigOverride for local emulator file handling
mantrakp04 Mar 19, 2026
4be8a82
Update QEMU emulator build workflow for improved performance and reli…
mantrakp04 Mar 19, 2026
f3514f8
Refactor QEMU emulator build and local emulator configuration
mantrakp04 Mar 20, 2026
d5d2a09
Increase EMULATOR_READY_TIMEOUT in QEMU emulator build workflow
mantrakp04 Mar 20, 2026
e509947
Enhance local emulator setup with environment generation and configur…
mantrakp04 Mar 20, 2026
ad2db19
Refactor local emulator configuration validation and enhance CLI tests
mantrakp04 Mar 20, 2026
a233e64
Update local emulator environment handling and documentation
mantrakp04 Mar 20, 2026
14f8164
Enhance local emulator project handling and configuration validation
mantrakp04 Mar 23, 2026
9d0f7c1
Refactor local emulator scripts and configuration management
mantrakp04 Mar 23, 2026
77d87fd
Refactor local emulator setup and enhance GitHub Actions workflow
mantrakp04 Mar 23, 2026
bef4aab
Enhance QEMU emulator build workflow and add documentation
mantrakp04 Mar 24, 2026
6d9d4e7
Merge branch 'dev' into emu-with-a-q
mantrakp04 Mar 24, 2026
771ed15
Update CLI tests for emulator commands
mantrakp04 Mar 24, 2026
bc1f951
local emulator allow localhost callback, add ssh debugging, fix file …
BilalG1 Mar 24, 2026
815320a
Merge branch 'client-sdk-local-emulator-support' into emulator-perms-…
BilalG1 Mar 24, 2026
7345567
emulator and client sdk changes
BilalG1 Mar 25, 2026
0907f50
fix emulator race conditions, update ports to 167xx, improve onboardi…
BilalG1 Mar 26, 2026
3cd32cc
Merge remote-tracking branch 'origin/emu-with-a-q' into emulator-perm…
BilalG1 Mar 26, 2026
de0a5da
lint / typecheck fixes
BilalG1 Mar 27, 2026
00390be
fix tests
BilalG1 Mar 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Enhance QEMU emulator build workflow and add documentation
- Updated the GitHub Actions workflow to include specific paths for the QEMU emulator build, ensuring that changes in the local emulator directory trigger the workflow.
- Added a new README.md file for the QEMU local emulator, detailing its architecture, usage, and scripts for building and running the emulator, improving clarity for developers.
- Documented the build process and optimizations taken, providing comprehensive guidance for users on how to utilize the local emulator effectively.

These changes improve the usability and maintainability of the QEMU emulator setup, facilitating a smoother development experience.
  • Loading branch information
mantrakp04 committed Mar 24, 2026
commit bef4aab9559c1fed4b546d95dd9fc7ebd4eb5255
3 changes: 3 additions & 0 deletions .github/workflows/qemu-emulator-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
- main
- dev
pull_request:
paths:
- 'docker/local-emulator/**'
- '.github/workflows/qemu-emulator-build.yaml'
workflow_dispatch:
inputs:
publish:
Expand Down
121 changes: 121 additions & 0 deletions docker/local-emulator/qemu/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# QEMU Local Emulator

The local emulator packages the entire Stack Auth backend (PostgreSQL, Redis, ClickHouse, MinIO, Inbucket, Svix, QStash, Dashboard, and Backend) into a single QEMU virtual machine image. Users run it via the `stack emulator` CLI commands.

## Architecture

```
Host machine
└─ QEMU VM (Debian 13 cloud image)
└─ Docker container (all-in-one image from ../Dockerfile)
├─ PostgreSQL 16
├─ Redis 7
├─ ClickHouse
├─ MinIO
├─ Inbucket
├─ Svix
├─ QStash
├─ Stack Dashboard (→ host:26700)
└─ Stack Backend (→ host:26701)
```

Only four services are exposed to the host via port forwarding:

| Service | Host Port | Description |
|-----------|-----------|--------------------------|
| Dashboard | 26700 | Stack Auth dashboard UI |
| Backend | 26701 | Stack Auth API server |
| MinIO | 26702 | S3-compatible storage |
| Inbucket | 26703 | Email testing interface |

All other services (PostgreSQL, Redis, ClickHouse, Svix, QStash) remain internal to the VM.

## Scripts

| Script | Purpose |
|--------------------|----------------------------------------------------------------|
| `build-image.sh` | Builds a QEMU disk image for a target architecture |
| `run-emulator.sh` | Manages the VM lifecycle: `start`, `stop`, `reset`, `status`, `bench` |
| `common.sh` | Shared helpers: host detection, QEMU binary selection, firmware lookup, ISO creation |

## Building an Image

```bash
# Build for current architecture
./docker/local-emulator/qemu/build-image.sh

# Build for a specific architecture (arm64 or amd64)
./docker/local-emulator/qemu/build-image.sh arm64

# Build both
./docker/local-emulator/qemu/build-image.sh both
```

The build process:
1. Builds the all-in-one Docker image from `../Dockerfile` and exports it as a tarball
2. Downloads a Debian 13 cloud base image
3. Boots a QEMU VM with cloud-init provisioning (`cloud-init/emulator/user-data`)
4. Cloud-init loads the Docker image and runs a full startup cycle to warm caches
5. Shuts down and compresses the disk image to `images/stack-emulator-<arch>.qcow2`

Default resources: 4 CPUs, 4096 MB RAM. Override with `EMULATOR_CPUS` / `EMULATOR_RAM_MB`.

### Why a single Docker image?

The `../Dockerfile` bundles all services into one image rather than using separate containers. This keeps the QEMU disk image size small — separate images would each carry their own base layers, significantly inflating the final qcow2.

## Running the Emulator

```bash
# Via CLI (recommended)
stack emulator start
stack emulator stop
stack emulator reset # wipe data
stack emulator status

# Via script directly
EMULATOR_ARCH=arm64 ./docker/local-emulator/qemu/run-emulator.sh start
```

The VM uses an overlay disk (`run/vm/disk.qcow2`) on top of the base image, so data persists across stop/start cycles. Use `reset` to wipe the overlay and start fresh.

### Hardware acceleration

- **macOS**: Uses HVF (Hypervisor.framework) for native-arch VMs
- **Linux**: Uses KVM when available
- **Cross-arch**: Falls back to TCG (software emulation) — significantly slower

## Optimizations Taken

- **Single bundled Docker image** to minimize qcow2 size
- **Cloud-init provisioning** pre-warms all services during build so first boot is fast
- **Overlay disks** avoid copying the multi-GB base image on each start
- **Compressed qcow2** images (`-c` flag) reduce download size
- **Only 4 ports forwarded** to minimize host-side surface area

## Possible Future Optimizations

- External server for reads and writes to relative dir instead of full host access allowing snapshots
- Or copying the config file on start with --config-file <path> enforced and writing the config file to host directory on stop

## Updating the Image

1. Make changes to the `../Dockerfile`, `../entrypoint.sh`, or cloud-init config
2. Rebuild: `./docker/local-emulator/qemu/build-image.sh <arch>`
3. The CI workflow (`.github/workflows/qemu-emulator-build.yaml`) builds and publishes images on push to `main`/`dev`
4. Users pull the latest via `stack emulator pull`

## Directory Layout

```
qemu/
├── build-image.sh # Image builder
├── run-emulator.sh # VM lifecycle manager
├── common.sh # Shared utilities
├── cloud-init/
│ └── emulator/
│ ├── meta-data # VM instance metadata
│ └── user-data # Provisioning script
├── images/ # Built qcow2 images (gitignored)
└── run/ # Runtime state: overlay disk, PID, logs (gitignored)
```