Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
9 changes: 9 additions & 0 deletions src/playground/.devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "Playground Apps Manager",
"dockerComposeFile": "docker-compose.yaml",
"service": "app",
"shutdownAction": "none",
"workspaceFolder": "/workspace",
"initializeCommand": "DOCKER_GID=`getent group docker | cut -d: -f3` && echo \"DOCKER_GID=${DOCKER_GID}\" > .env && mkdir -p apps && chmod 777 apps",
"remoteUser": "root"
}
27 changes: 27 additions & 0 deletions src/playground/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# example

Web-based manager for creating and deploying custom devcontainer applications

## Access

Once deployed in Workbench, access the web interface at the app URL (port 8080).

For local testing:
1. Create Docker network: `docker network create app-network`
2. Run the app: `devcontainer up --workspace-folder .`
3. Access at: `http://localhost:8080`

## Customization

Edit the following files to customize your app:

- `.devcontainer.json` - Devcontainer configuration and features
- `docker-compose.yaml` - Docker Compose configuration (change the `command` to customize ttyd options)
- `devcontainer-template.json` - Template options and metadata

## Usage

1. Fork the repository
2. Modify the configuration files as needed
3. In Workbench UI, create a custom app pointing to your forked repository
4. Select this app template (example)
12 changes: 12 additions & 0 deletions src/playground/caddy/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
debug
admin 0.0.0.0:2019
}

http://:8080 {
# Dynamic routes will be added here via API
route {
# Default route to playground UI
reverse_proxy playground:8080
}
}
6 changes: 6 additions & 0 deletions src/playground/devcontainer-template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"id": "playground",
"version": "1.0.0",
"name": "Playground Apps Manager",
"description": "Web-based manager for creating and deploying custom devcontainer applications"
}
79 changes: 79 additions & 0 deletions src/playground/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
services:
app:
# The container name must be "application-server"
container_name: "application-server"
image: "caddy:2.11-alpine"
restart: always
volumes:
- ./caddy:/etc/caddy:ro
- caddy_data:/data
ports:
- 8080:8080
networks:
- app-network
- playground-apps

playground:
build:
context: ./playground
container_name: "playground"
user: "playground:${DOCKER_GID}"
restart: always
depends_on:
app:
condition: service_started
db:
condition: service_healthy
environment:
PORT: "8080"
DB_HOST: "db"
DB_PORT: "5432"
DB_NAME: "playground"
DB_USER: "playground_user"
DB_PASSWORD: "playground_password"
CADDY_HOST: "application-server"
CADDY_PORT: "2019"
volumes:
# mount Host machine's docker.sock to container's docker.sock
- /var/run/docker.sock:/var/run/docker.sock
# mount Host machine's /etc/group to container's /etc/host-group
- /etc/group:/etc/host-group
# mount apps directory for devcontainer builds
- ./apps:/workspace/apps
# mount startup scripts from parent directory
- ./startupscript:/workspace/startupscript
# mount features directory for devcontainer features
- ../../features:/workspace/features:ro
networks:
- playground-apps
- playground

db:
image: "postgres:18-alpine"
restart: always
environment:
POSTGRES_USER: "playground_user"
POSTGRES_PASSWORD: "playground_password"
POSTGRES_DB: "playground"
volumes:
- pg_data:/var/lib/postgresql/data
networks:
- playground
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s

volumes:
caddy_data:
pg_data:

networks:
# The Docker network must be named "app-network". This is an external network
# that is created outside of this docker-compose file.
app-network:
external: true
playground:
playground-apps:
35 changes: 35 additions & 0 deletions src/playground/playground/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
FROM golang:1.25-alpine AS build

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download
COPY . .

RUN go build -o /playground .

FROM alpine:latest

# Install Node.js, npm, Docker CLI, docker-compose, buildx, ttyd, bash, and devcontainer CLI
RUN apk add --no-cache nodejs npm docker-cli docker-cli-compose docker-cli-buildx ttyd bash && \
npm install -g @devcontainers/cli

RUN addgroup -S playground -g 1001 && adduser -S playground -u 1001 -G playground

WORKDIR /workspace
COPY --chown=playground:playground --from=build /playground /playground

# Create startup script to run ttyd in background and playground in foreground
RUN cat > /start.sh <<'EOF'
#!/bin/sh
ttyd --writable --port 7681 --base-path /_shell bash &
exec /playground
EOF

RUN chmod +x /start.sh

USER playground

EXPOSE 8080 7681

CMD [ "/start.sh" ]
Loading