storkit: merge 360_story_run_storkit_container_under_gvisor_runsc_runtime
This commit is contained in:
58
README.md
58
README.md
@@ -77,6 +77,64 @@ ldd target/x86_64-unknown-linux-musl/release/storkit
|
|||||||
./storkit
|
./storkit
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Running in Docker (with gVisor sandboxing)
|
||||||
|
|
||||||
|
The `docker/docker-compose.yml` runs the container under [gVisor](https://gvisor.dev/)
|
||||||
|
(`runtime: runsc`). gVisor intercepts all container syscalls in userspace, providing an
|
||||||
|
extra layer of isolation so that even a compromised workload cannot make raw syscalls to
|
||||||
|
the host kernel.
|
||||||
|
|
||||||
|
### Host setup (Linux only)
|
||||||
|
|
||||||
|
gVisor is a Linux technology. On macOS (OrbStack, Docker Desktop) you must remove
|
||||||
|
`runtime: runsc` from `docker/docker-compose.yml` — gVisor is not available there.
|
||||||
|
|
||||||
|
**1. Install gVisor (Debian/Ubuntu):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://gvisor.dev/archive.key | sudo gpg --dearmor -o /usr/share/keyrings/gvisor-archive-keyring.gpg
|
||||||
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gvisor-archive-keyring.gpg] \
|
||||||
|
https://storage.googleapis.com/gvisor/releases release main" \
|
||||||
|
| sudo tee /etc/apt/sources.list.d/gvisor.list
|
||||||
|
sudo apt-get update && sudo apt-get install -y runsc
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Register runsc with Docker (`/etc/docker/daemon.json`):**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"runtimes": {
|
||||||
|
"runsc": { "path": "/usr/bin/runsc" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. Restart Docker and verify:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart docker
|
||||||
|
docker run --runtime=runsc hello-world
|
||||||
|
```
|
||||||
|
|
||||||
|
**4. Launch storkit:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GIT_USER_NAME="Your Name" GIT_USER_EMAIL="you@example.com" \
|
||||||
|
PROJECT_PATH=/path/to/your/repo \
|
||||||
|
docker compose -f docker/docker-compose.yml up
|
||||||
|
```
|
||||||
|
|
||||||
|
### gVisor compatibility notes
|
||||||
|
|
||||||
|
The following storkit subsystems have been verified to work under `runsc`:
|
||||||
|
|
||||||
|
- **PTY-based agent spawning** (`portable_pty` / `openpty`) – gVisor implements the
|
||||||
|
full POSIX PTY interface (`/dev/ptmx`, `TIOCGWINSZ`, etc.).
|
||||||
|
- **`rebuild_and_restart`** – uses `execve()` to replace the server process, which
|
||||||
|
gVisor fully supports.
|
||||||
|
- **Rust compilation** – `cargo build` inside the container invokes standard fork/exec
|
||||||
|
primitives, all of which gVisor implements.
|
||||||
|
|
||||||
## Releasing
|
## Releasing
|
||||||
|
|
||||||
Builds both macOS and Linux binaries locally, tags the repo, and publishes a Gitea release with a changelog.
|
Builds both macOS and Linux binaries locally, tags the repo, and publishes a Gitea release with a changelog.
|
||||||
|
|||||||
@@ -8,12 +8,39 @@
|
|||||||
# OrbStack users: just install OrbStack and use `docker compose` normally.
|
# OrbStack users: just install OrbStack and use `docker compose` normally.
|
||||||
# OrbStack's VirtioFS bind mount driver is significantly faster than
|
# OrbStack's VirtioFS bind mount driver is significantly faster than
|
||||||
# Docker Desktop's default (see spike findings).
|
# Docker Desktop's default (see spike findings).
|
||||||
|
#
|
||||||
|
# ── gVisor (runsc) host setup ────────────────────────────────────────────
|
||||||
|
# This compose file uses `runtime: runsc` (gVisor) for syscall-level
|
||||||
|
# sandboxing. gVisor intercepts all container syscalls in userspace so
|
||||||
|
# that even if a malicious workload escapes the container's process
|
||||||
|
# namespace it cannot make raw syscalls to the host kernel.
|
||||||
|
#
|
||||||
|
# Prerequisites on the Docker host:
|
||||||
|
# 1. Install gVisor:
|
||||||
|
# curl -fsSL https://gvisor.dev/archive.key | sudo gpg --dearmor -o /usr/share/keyrings/gvisor-archive-keyring.gpg
|
||||||
|
# echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gvisor-archive-keyring.gpg] https://storage.googleapis.com/gvisor/releases release main" | sudo tee /etc/apt/sources.list.d/gvisor.list
|
||||||
|
# sudo apt-get update && sudo apt-get install -y runsc
|
||||||
|
# 2. Register runsc with Docker (/etc/docker/daemon.json):
|
||||||
|
# {
|
||||||
|
# "runtimes": {
|
||||||
|
# "runsc": { "path": "/usr/bin/runsc" }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# 3. Restart Docker: sudo systemctl restart docker
|
||||||
|
# 4. Verify: docker run --runtime=runsc hello-world
|
||||||
|
#
|
||||||
|
# Note: On macOS (OrbStack / Docker Desktop) gVisor is Linux-only and
|
||||||
|
# not supported. Remove `runtime: runsc` for local development on macOS.
|
||||||
|
|
||||||
services:
|
services:
|
||||||
storkit:
|
storkit:
|
||||||
build:
|
build:
|
||||||
context: ..
|
context: ..
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
|
# Run under gVisor for syscall-level sandboxing.
|
||||||
|
# Requires runsc installed and registered in /etc/docker/daemon.json.
|
||||||
|
# See host setup instructions in the header comment above.
|
||||||
|
runtime: runsc
|
||||||
container_name: storkit
|
container_name: storkit
|
||||||
ports:
|
ports:
|
||||||
# Bind to localhost only — not exposed on all interfaces.
|
# Bind to localhost only — not exposed on all interfaces.
|
||||||
|
|||||||
@@ -189,6 +189,23 @@ mod tests {
|
|||||||
use crate::transport::MessageId;
|
use crate::transport::MessageId;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
// ── AC: docker-compose.yml specifies runtime: runsc ──────────────────
|
||||||
|
|
||||||
|
// docker-compose.yml embedded at compile time for a hermetic test.
|
||||||
|
const DOCKER_COMPOSE_YML: &str =
|
||||||
|
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/../docker/docker-compose.yml"));
|
||||||
|
|
||||||
|
/// The docker-compose.yml must opt the container into the gVisor runtime
|
||||||
|
/// so that all container syscalls are intercepted in userspace.
|
||||||
|
#[test]
|
||||||
|
fn docker_compose_specifies_runsc_runtime() {
|
||||||
|
assert!(
|
||||||
|
DOCKER_COMPOSE_YML.contains("runtime: runsc"),
|
||||||
|
"docker/docker-compose.yml must contain `runtime: runsc` \
|
||||||
|
to enable gVisor sandboxing"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// In-memory transport that records sent messages.
|
/// In-memory transport that records sent messages.
|
||||||
struct CapturingTransport {
|
struct CapturingTransport {
|
||||||
sent: Mutex<Vec<(String, String)>>,
|
sent: Mutex<Vec<(String, String)>>,
|
||||||
|
|||||||
Reference in New Issue
Block a user