Module: VIBE
Deploy an AI coding sandbox with Pigsty: Code-Server, JupyterLab, Node.js, and Claude Code.
The VIBE module provides a browser-based dev environment with Code-Server, JupyterLab, Node.js, and Claude Code,
and can work with JUICE shared storage and PGSQL database capabilities.
VIBE depends on NODE and INFRA:
NODE provides base software and Python uv environmentINFRA provides Nginx reverse proxy, Grafana and portal entry
Components
| Component | Description | Local Port | Access Path |
|---|
| Code-Server | VS Code in browser | 8443 | /code/ |
| JupyterLab | Interactive notebooks | 8888 | /jupyter/ |
| Node.js | Runtime and npm | - | CLI |
| Claude Code | CLI + observability config | - | CLI / Grafana |
Notes:
- Code-Server listens on
127.0.0.1:8443, exposed via Nginx - JupyterLab listens on
0.0.0.0:8888, base path /jupyter/ - Module default is
jupyter_enabled: false, while conf/vibe.yml template explicitly enables Jupyter
Quick Start
./configure -c vibe
./deploy.yml # NODE + INFRA + PGSQL
./juice.yml # optional shared storage
./vibe.yml # VIBE
Default entry points (via infra_portal.home):
- Code-Server:
https://<domain>/code/ - JupyterLab:
https://<domain>/jupyter/ - Claude Dashboard:
https://<domain>/ui/d/claude-code
Features
- Unified workspace:
vibe_data as root for Code-Server and Jupyter - Optional shared storage: work with
JUICE for multi-node sharing - Observability: Claude Code OpenTelemetry integrates with VictoriaMetrics/VictoriaLogs
- Composable: enable Code/Jupyter/Node.js/Claude as needed
Documentation
1 - Configuration
VIBE module configuration for Code-Server, JupyterLab, Node.js, and Claude Code.
VIBE supports enabling components on demand and exposes services via a unified workspace and Nginx portal.
Overview
| Component | Enable Param | Default | Description |
|---|
| Code-Server | code_enabled | Enabled | VS Code in browser |
| JupyterLab | jupyter_enabled | Disabled | Notebook / terminal / editor |
| Node.js | nodejs_enabled | Enabled | Node.js runtime and npm |
| Claude Code | claude_enabled | Enabled | CLI config and observability |
Note: module default is jupyter_enabled: false, while conf/vibe.yml explicitly sets it to true.
Config usually lives in cluster vars, and can be overridden at instance level:
all:
children:
infra:
hosts:
10.10.10.10:
vibe_data: /fs
code_enabled: true
jupyter_enabled: true
claude_enabled: true
Workspace
vibe_data is the unified workspace for VIBE:
- Code-Server default open directory
- JupyterLab
root_dir - Claude Code working dir
CLAUDE.md / AGENTS.md context files
The vibe_dir task creates the directory and context files, owned by node_user.
Code-Server
code_enabled: true
code_port: 8443
code_data: /data/code
code_password: Vibe.Coding
code_gallery: openvsx
Notes:
- Service listens on
127.0.0.1:<code_port> (default 8443), accessed via Nginx /code/ - Config file:
code_data/code-server/config.yaml (default /data/code/code-server/config.yaml) - Env file:
/etc/default/code, used to configure extension marketplace
Extension marketplace:
code_gallery: microsoft uses Microsoft marketplace- When
region=china, Open VSX defaults to Tsinghua mirror
JupyterLab
jupyter_enabled: true
jupyter_port: 8888
jupyter_data: /data/jupyter
jupyter_password: Vibe.Coding
jupyter_venv: /data/venv
Notes:
- Service listens on
0.0.0.0:<jupyter_port> (default 8888), base path /jupyter/ - Config file:
jupyter_data/jupyter_config.py (default /data/jupyter/jupyter_config.py) - Login token:
c.IdentityProvider.token - Venv is not created automatically, use
node_uv_env in NODE module beforehand
Create venv example:
Node.js
nodejs_enabled: true
nodejs_registry: ''
npm_packages:
- '@anthropic-ai/claude-code'
- happy-coder
Notes:
- When
nodejs_registry is empty and region=china, default registry is https://registry.npmmirror.com npm_packages are installed via npm install -g and available globally@anthropic-ai/claude-code is installed by default, so manual Claude CLI install is usually unnecessary
Claude Code
claude task only writes configuration (claude_config).
By default, Claude CLI is installed by the nodejs task through npm_packages (including @anthropic-ai/claude-code).
claude_enabled: true
claude_env:
ANTHROPIC_API_KEY: sk-ant-xxx
If nodejs_enabled is disabled or npm_packages is emptied, install Claude CLI manually.
Generated files:
~/.claude.json~/.claude/settings.json
claude_env is merged with default OpenTelemetry env vars, sending telemetry to VictoriaMetrics / VictoriaLogs.
Nginx Portal
VIBE exposes services through infra_portal.
By default, home domain includes /code/ and /jupyter/ paths.
For dedicated domains:
infra_portal:
code: { domain: code.pigsty, endpoint: "127.0.0.1:8443", websocket: true }
jupyter: { domain: jupyter.pigsty, endpoint: "127.0.0.1:8888", websocket: true }
2 - Parameters
VIBE module parameters (16 total).
VIBE module has 16 parameters, grouped as:
- Common
- Code-Server
- JupyterLab
- Node.js
- Claude Code
Overview
Default Parameters
Defined in roles/vibe/defaults/main.yml:
vibe_data: /fs
code_enabled: true
code_port: 8443
code_data: /data/code
code_password: Vibe.Coding
code_gallery: 'openvsx'
jupyter_enabled: false
jupyter_port: 8888
jupyter_data: /data/jupyter
jupyter_password: Vibe.Coding
jupyter_venv: /data/venv
nodejs_enabled: true
nodejs_registry: ''
npm_packages: [ '@anthropic-ai/claude-code' , 'happy-coder' ]
claude_enabled: true
claude_env: {}
Common
vibe_data
Workspace dir: default root for Code-Server and JupyterLab, and location for CLAUDE.md / AGENTS.md.
Code-Server
code_enabled
Enable Code-Server.
code_port
Listen port, bound to 127.0.0.1, forwarded by Nginx /code/.
code_data
Data dir, config file at code_data/code-server/config.yaml (default /data/code/code-server/config.yaml).
code_password
Login password, must be changed in production.
code_gallery
Extension marketplace: openvsx / microsoft.
When region=china and openvsx, Tsinghua mirror is used.
JupyterLab
jupyter_enabled
Enable JupyterLab.
Module default is false; conf/vibe.yml explicitly sets it to true to enable a full sandbox.
jupyter_port
Listen port, default 0.0.0.0:8888.
jupyter_data
Data dir, config file at jupyter_data/jupyter_config.py (default /data/jupyter/jupyter_config.py).
jupyter_password
Access token written to c.IdentityProvider.token.
jupyter_venv
Python venv path for JupyterLab, must be created beforehand (usually by NODE module).
Node.js
nodejs_enabled
Enable Node.js.
nodejs_registry
npm registry mirror; when empty and region=china, defaults to https://registry.npmmirror.com.
npm_packages
Global npm packages, tagged nodejs_pkg.
Defaults include @anthropic-ai/claude-code and happy-coder.
Claude Code
claude_enabled
Enable Claude Code config task (claude_config).
Claude CLI is installed by nodejs_pkg based on npm_packages by default.
claude_env
Extra env vars merged into default OpenTelemetry config.
Default env vars include:
CLAUDE_CODE_ENABLE_TELEMETRY=1CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1OTEL_METRICS_EXPORTER=otlpOTEL_LOGS_EXPORTER=otlpOTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://127.0.0.1:8428/opentelemetry/v1/metricsOTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://127.0.0.1:9428/insert/opentelemetry/v1/logs
3 - Playbook
VIBE module Ansible playbook guide.
VIBE module provides vibe.yml playbook to deploy Code-Server, JupyterLab, Node.js and Claude Code config.
vibe.yml includes only node_id and vibe roles, it does not include node/infra.
Run deploy.yml first, or explicitly run node.yml and infra.yml.
vibe.yml
vibe.yml:
- name: VIBE
hosts: all
become: true
gather_facts: no
roles:
- { role: node_id, tags: id }
- { role: vibe, tags: vibe }
Task Structure
vibe
├── vibe_dir # create workspace and context files
├── code # Code-Server
│ ├── code_install
│ ├── code_dir
│ ├── code_config
│ └── code_launch
├── jupyter # JupyterLab
│ ├── jupyter_install
│ ├── jupyter_dir
│ ├── jupyter_config
│ └── jupyter_launch
├── nodejs # Node.js runtime
│ ├── nodejs_install
│ ├── nodejs_config
│ └── nodejs_pkg
└── claude # Claude Code config
└── claude_config
Notes:
jupyter_install uses uv pip, it does not create venvclaude_config only writes ~/.claude config- Claude CLI is installed by
nodejs_pkg via npm_packages (includes @anthropic-ai/claude-code by default)
Common Commands
Full deploy:
Component-level:
./vibe.yml -l <host> -t code
./vibe.yml -l <host> -t jupyter
./vibe.yml -l <host> -t nodejs
./vibe.yml -l <host> -t claude
Config updates:
./vibe.yml -l <host> -t code_config,code_launch
./vibe.yml -l <host> -t jupyter_config,jupyter_launch
./vibe.yml -l <host> -t claude_config
Disable components:
./vibe.yml -l <host> -e code_enabled=false
./vibe.yml -l <host> -e jupyter_enabled=false
./vibe.yml -l <host> -e nodejs_enabled=false
./vibe.yml -l <host> -e claude_enabled=false
Deployment Order
./deploy.yml # NODE + INFRA + PGSQL
./juice.yml # optional shared storage
./vibe.yml # VIBE
Idempotency
vibe.yml is idempotent. Re-run after config changes.
4 - Administration
VIBE module operations and common admin tasks.
Service Management
systemctl status code-server
systemctl restart code-server
systemctl status jupyter
systemctl restart jupyter
Logs:
journalctl -u code-server -f
journalctl -u jupyter -f
Workspace and Context
vibe_dir creates these under vibe_data:
CLAUDE.mdAGENTS.md (symlink to CLAUDE.md)
Default locations (adjustable via vibe_data):
/fs/CLAUDE.md
/fs/AGENTS.md
Password and Auth
Code-Server
Edit config:
vi /data/code/code-server/config.yaml
systemctl restart code-server
Or via Ansible:
./vibe.yml -l <host> -e code_password='NewPassword' -t code_config,code_launch
JupyterLab
Config file: /data/jupyter/jupyter_config.py
Field: c.IdentityProvider.token
vi /data/jupyter/jupyter_config.py
systemctl restart jupyter
Code-Server Extensions
code-server --install-extension ms-python.python
code-server --list-extensions
code-server --uninstall-extension ms-python.python
Switch extension marketplace:
Redeploy:
./vibe.yml -l <host> -t code_config,code_launch
JupyterLab Environment
VIBE does not create venv automatically, ensure jupyter_venv exists:
Install/upgrade JupyterLab:
uv pip install --python /data/venv/bin/python jupyterlab ipykernel
systemctl restart jupyter
Install extensions (in venv):
source /data/venv/bin/activate
pip install jupyterlab-git
systemctl restart jupyter
Claude Code
The claude_config subtask only writes config files.
Claude CLI is installed globally by nodejs_pkg through npm_packages (which includes @anthropic-ai/claude-code by default).
which claude
claude --version
Config files:
~/.claude.json~/.claude/settings.json
Update config:
./vibe.yml -l <host> -t claude_config
Reinstall/install Claude CLI:
./vibe.yml -l <host> -t nodejs_pkg
# or install manually
npm install -g @anthropic-ai/claude-code
To configure for another user, run as that user or copy the files manually.
File Locations
| Component | Key Files |
|---|
| Code-Server | /data/code/code-server/config.yaml |
| Code-Server | /etc/default/code |
| Code-Server | /etc/systemd/system/code-server.service |
| JupyterLab | /data/jupyter/jupyter_config.py |
| JupyterLab | /etc/default/jupyter |
| JupyterLab | /etc/systemd/system/jupyter.service |
| Claude Code | ~/.claude.json / ~/.claude/settings.json |
Troubleshooting
Port checks:
ss -tlnp | grep 8443
ss -tlnp | grep 8888
Nginx entry:
nginx -t
systemctl status nginx
5 - Monitoring
VIBE monitoring, focusing on Claude Code observability.
VIBE monitoring mainly focuses on Claude Code OpenTelemetry data.
Code-Server and JupyterLab do not expose Prometheus metrics; use systemd and logs for health checks.
Claude Code Observability
VIBE writes default OpenTelemetry env vars into ~/.claude/settings.json:
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": 1,
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": 1,
"OTEL_LOG_USER_PROMPTS": 1,
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
"OTEL_EXPORTER_OTLP_METRICS_ENDPOINT": "http://127.0.0.1:8428/opentelemetry/v1/metrics",
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT": "http://127.0.0.1:9428/insert/opentelemetry/v1/logs",
"OTEL_RESOURCE_ATTRIBUTES": "ip=<host>,job=claude"
}
}
claude_env is merged with the defaults, and can be used for API keys or custom endpoints.
Grafana Dashboard
Grafana includes claude-code dashboard by default:
- Portal:
https://<domain>/ui/d/claude-code - Direct:
http://<ip>:3000/d/claude-code
Runtime Checks
systemctl status code-server
systemctl status jupyter
journalctl -u code-server -f
journalctl -u jupyter -f
Port checks:
ss -tlnp | grep 8443
ss -tlnp | grep 8888
Claude Logs Query
Via VictoriaLogs:
curl -G 'http://127.0.0.1:9428/select/logsql/query' \
--data-urlencode 'query=job:claude'
6 - FAQ
VIBE module frequently asked questions.
Deployment
code-server package not found
Ensure NODE and repo config are in place:
yum repolist # EL
apt update # Debian/Ubuntu
./infra.yml -t repo
JupyterLab installation failed
jupyter_venv must exist:
uv venv /data/venv
./vibe.yml -l <host> -t jupyter
Access
Cannot access /code/ or /jupyter/
- Check service status
- Check port listening
- Check Nginx config
systemctl status code-server
systemctl status jupyter
ss -tlnp | grep 8443
ss -tlnp | grep 8888
nginx -t
WebSocket connection fails
Ensure Nginx enables WebSocket (default is enabled).
If using custom infra_portal, set websocket: true.
Password and Token
Change Code-Server password
./vibe.yml -l <host> -e code_password='NewPass' -t code_config,code_launch
Change JupyterLab token
./vibe.yml -l <host> -e jupyter_password='NewToken' -t jupyter_config,jupyter_launch
Claude Code
CLI not found
First check whether nodejs_pkg completed (@anthropic-ai/claude-code is installed by default):
which claude
npm list -g --depth=0 | grep '@anthropic-ai/claude-code'
./vibe.yml -l <host> -t nodejs_pkg
If nodejs_enabled is disabled or npm_packages is overridden, install manually:
npm install -g @anthropic-ai/claude-code
API key not set
export ANTHROPIC_API_KEY=sk-ant-xxx
# or set in claude_env
Telemetry not showing
Check local VictoriaMetrics/VictoriaLogs:
curl http://127.0.0.1:8428/api/v1/status/buildinfo
curl http://127.0.0.1:9428/select/logsql/stats_query
Ensure OTEL endpoints in ~/.claude/settings.json are correct.
Extensions and Plugins
Code-Server extension install fails
- Check network
- Try switching
code_gallery - Or install VSIX manually
code-server --install-extension /path/to/extension.vsix
JupyterLab extension install fails
source /data/venv/bin/activate
pip install jupyterlab-git
systemctl restart jupyter