Skip to content

Commit ebdec3d

Browse files
Add Playground Apps Manager - Web-based devcontainer app deployment system (#294)
## Summary Introduces the Playground Apps Manager - a web-based system for creating, managing, and deploying custom devcontainer-based applications with real-time monitoring and build log streaming. ## Overview The Playground Apps Manager provides a self-service interface for users to create and manage containerized applications using devcontainer configurations. Apps are built with the devcontainer CLI and run as isolated containers with reverse-proxy routing through Caddy. ## Key Features ### App Management - **Web UI**: Full-featured interface for CRUD operations on apps - **Dynamic Routing**: Automatic Caddy configuration for reverse-proxy routing to each app - **Container Lifecycle**: Start, stop, and monitor container status - **Real-time Status**: Live updates for app and container states ### Build System - **Devcontainer-based**: Uses devcontainer CLI for building and starting containers - **Live Build Logs**: Real-time streaming of build output to playground logs - **Platform Support**: Builds as `linux/amd64` for maximum compatibility - **Async Building**: Apps build in background with status tracking ### Optional Features Built-in support for common feature sets: - **Workbench CLI** (`wb`): Java 17, AWS CLI, gcloud CLI, startup scripts (~4 min build) - **Workbench Tools** (`workbench-tools`): Bioinformatics toolkit including bcftools, bedtools, plink, plink2, samtools, VEP, REGENIE (~8 min build) Features are automatically installed during devcontainer build with proper configuration. ### Example Apps Quick-start templates for common use cases: - **ttyd**: Web-based terminal access - **JupyterLab**: Interactive notebook environment ### Monitoring & Debugging - **Container Logs**: View logs for individual app containers - **Playground Logs**: System-level logs for build processes - **Auto-refresh**: Toggle auto-refresh (3s interval) for real-time log monitoring - **Smart Scrolling**: Maintains scroll position during log updates <img width="1494" height="465" alt="image" src="https://github.com/user-attachments/assets/5e990bee-f995-4f7e-a1fc-82072154230e" /> <img width="822" height="1114" alt="image" src="https://github.com/user-attachments/assets/32929fcf-eb27-4a21-96f6-bacb3cb1cf97" /> <img width="822" height="780" alt="image" src="https://github.com/user-attachments/assets/28dc93bc-2913-4080-9fd0-d6b6e8c45713" /> 🤖 Generated with Claude Code
1 parent 76c40da commit ebdec3d

20 files changed

Lines changed: 3215 additions & 0 deletions

src/playground/.devcontainer.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "Playground Apps Manager",
3+
"dockerComposeFile": "docker-compose.yaml",
4+
"service": "app",
5+
"shutdownAction": "none",
6+
"workspaceFolder": "/workspace",
7+
"initializeCommand": "DOCKER_GID=`getent group docker | cut -d: -f3` && echo \"DOCKER_GID=${DOCKER_GID}\" > .env && mkdir -p apps && chmod 777 apps",
8+
"remoteUser": "root"
9+
}

src/playground/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# example
2+
3+
Web-based manager for creating and deploying custom devcontainer applications
4+
5+
## Access
6+
7+
Once deployed in Workbench, access the web interface at the app URL (port 8080).
8+
9+
For local testing:
10+
1. Create Docker network: `docker network create app-network`
11+
2. Run the app: `devcontainer up --workspace-folder .`
12+
3. Access at: `http://localhost:8080`
13+
14+
## Customization
15+
16+
Edit the following files to customize your app:
17+
18+
- `.devcontainer.json` - Devcontainer configuration and features
19+
- `docker-compose.yaml` - Docker Compose configuration (change the `command` to customize ttyd options)
20+
- `devcontainer-template.json` - Template options and metadata
21+
22+
## Usage
23+
24+
1. Fork the repository
25+
2. Modify the configuration files as needed
26+
3. In Workbench UI, create a custom app pointing to your forked repository
27+
4. Select this app template (example)

src/playground/caddy/Caddyfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
debug
3+
admin 0.0.0.0:2019
4+
}
5+
6+
http://:8080 {
7+
# Dynamic routes will be added here via API
8+
route {
9+
# Default route to playground UI
10+
reverse_proxy playground:8080
11+
}
12+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"id": "playground",
3+
"version": "1.0.0",
4+
"name": "Playground Apps Manager",
5+
"description": "Web-based manager for creating and deploying custom devcontainer applications"
6+
}

src/playground/docker-compose.yaml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
services:
2+
app:
3+
# The container name must be "application-server"
4+
container_name: "application-server"
5+
image: "caddy:2.11-alpine"
6+
restart: always
7+
volumes:
8+
- ./caddy:/etc/caddy:ro
9+
- caddy_data:/data
10+
ports:
11+
- 8080:8080
12+
networks:
13+
- app-network
14+
- playground-apps
15+
16+
playground:
17+
build:
18+
context: ./playground
19+
container_name: "playground"
20+
user: "playground:${DOCKER_GID}"
21+
restart: always
22+
depends_on:
23+
app:
24+
condition: service_started
25+
db:
26+
condition: service_healthy
27+
environment:
28+
PORT: "8080"
29+
DB_HOST: "db"
30+
DB_PORT: "5432"
31+
DB_NAME: "playground"
32+
DB_USER: "playground_user"
33+
DB_PASSWORD: "playground_password"
34+
CADDY_HOST: "application-server"
35+
CADDY_PORT: "2019"
36+
CLOUD: "${templateOption:cloud}"
37+
volumes:
38+
# mount Host machine's docker.sock to container's docker.sock
39+
- /var/run/docker.sock:/var/run/docker.sock
40+
# mount Host machine's /etc/group to container's /etc/host-group
41+
- /etc/group:/etc/host-group
42+
# mount apps directory for devcontainer builds
43+
- ./apps:/workspace/apps
44+
# mount startup scripts from parent directory
45+
- ./startupscript:/workspace/startupscript
46+
# mount features directory for devcontainer features
47+
- ../../features:/workspace/features:ro
48+
networks:
49+
- playground-apps
50+
- playground
51+
52+
db:
53+
image: "postgres:18-alpine"
54+
restart: always
55+
environment:
56+
POSTGRES_USER: "playground_user"
57+
POSTGRES_PASSWORD: "playground_password"
58+
POSTGRES_DB: "playground"
59+
volumes:
60+
- pg_data:/var/lib/postgresql/data
61+
networks:
62+
- playground
63+
healthcheck:
64+
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
65+
interval: 10s
66+
timeout: 5s
67+
retries: 5
68+
start_period: 10s
69+
70+
volumes:
71+
caddy_data:
72+
pg_data:
73+
74+
networks:
75+
# The Docker network must be named "app-network". This is an external network
76+
# that is created outside of this docker-compose file.
77+
app-network:
78+
external: true
79+
playground:
80+
playground-apps:
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
FROM golang:1.25-alpine AS build
2+
3+
WORKDIR /app
4+
5+
COPY go.mod go.sum ./
6+
RUN go mod download
7+
COPY . .
8+
9+
RUN go build -o /playground .
10+
11+
FROM alpine:latest
12+
13+
# Install Node.js, npm, Docker CLI, docker-compose, buildx, ttyd, bash, and devcontainer CLI
14+
RUN apk add --no-cache nodejs npm docker-cli docker-cli-compose docker-cli-buildx ttyd bash && \
15+
npm install -g @devcontainers/cli
16+
17+
RUN addgroup -S playground -g 1001 && adduser -S playground -u 1001 -G playground
18+
19+
WORKDIR /workspace
20+
COPY --chown=playground:playground --from=build /playground /playground
21+
22+
# Create startup script to run ttyd in background and playground in foreground
23+
RUN cat > /start.sh <<'EOF'
24+
#!/bin/sh
25+
ttyd --writable --port 7681 --base-path /_shell bash &
26+
exec /playground
27+
EOF
28+
29+
RUN chmod +x /start.sh
30+
31+
USER playground
32+
33+
EXPOSE 8080 7681
34+
35+
CMD [ "/start.sh" ]

src/playground/playground/go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/verily-src/workbench-app-devcontainers/src/playground/playground
2+
3+
go 1.25.5
4+
5+
require github.com/lib/pq v1.10.9

src/playground/playground/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
2+
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=

0 commit comments

Comments
 (0)