Module: VIBE
Deploy an AI coding sandbox with Pigsty: Code-Server, JupyterLab, Node.js, Claude Code, and Codex CLI.
The VIBE module provides a browser-based dev environment with Code-Server, JupyterLab, Node.js, Claude Code, and Codex CLI,
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 |
| Codex CLI | CLI installation; configuration is not managed | - | CLI |
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/Codex as needed
Documentation
1 - Configuration
VIBE module configuration for Code-Server, JupyterLab, Node.js, Claude Code, and Codex CLI.
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 installation, config, and observability |
| Codex CLI | codex_enabled | Enabled | CLI installation only; configuration is not managed |
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
codex_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: []
Notes:
- When
nodejs_registry is empty and region=china, default registry is https://registry.npmmirror.com npm_packages installs additional global npm packages and is empty by default- Claude Code and Codex CLI are installed by their own dedicated tasks
Claude Code
The claude task installs the CLI (claude_install) and writes its configuration (claude_config).
claude_enabled: true
claude_package: '@anthropic-ai/claude-code'
claude_env:
ANTHROPIC_API_KEY: sk-ant-xxx
When Claude or Codex is enabled, VIBE ensures that the Node.js runtime is installed. Override claude_package to use a different Claude npm package.
Generated files:
~/.claude.json~/.claude/settings.json
claude_env is merged with default OpenTelemetry env vars, sending telemetry to VictoriaMetrics / VictoriaLogs.
Codex CLI
The codex task runs npm install -g @openai/codex. VIBE installs Codex CLI only; it does not write Codex configuration or connect it to VIBE’s Claude Code observability.
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 (18 total).
VIBE module has 18 parameters, grouped as:
- Common
- Code-Server
- JupyterLab
- Node.js
- Claude Code
- Codex CLI
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: []
claude_enabled: true
claude_package: '@anthropic-ai/claude-code'
claude_env: {}
codex_enabled: true
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
Additional global npm packages, tagged nodejs_pkg; empty by default.
Claude Code and Codex CLI are installed by their own dedicated tasks and do not need to be added here.
Claude Code
claude_enabled
Enable Claude Code installation and configuration. claude_install installs the CLI, while claude_config writes its configuration.
claude_package
The npm package used for Claude Code; defaults to @anthropic-ai/claude-code.
claude_env
Extra env vars merged into default OpenTelemetry config.
Default env vars include:
CLAUDE_CODE_ENABLE_TELEMETRY=1OTEL_METRICS_EXPORTER=otlpOTEL_LOGS_EXPORTER=otlpOTEL_EXPORTER_OTLP_METRICS_PROTOCOL=http/protobufOTEL_EXPORTER_OTLP_LOGS_PROTOCOL=http/protobufOTEL_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/logsOTEL_RESOURCE_ATTRIBUTES=ip=<inventory_hostname>,job=claude
Codex CLI
codex_enabled
Whether to install Codex CLI; defaults to true. When enabled, codex_install runs npm install -g @openai/codex.
VIBE installs Codex CLI only; it does not manage Codex configuration or configure OpenTelemetry for it.
3 - Playbook
VIBE module Ansible playbook guide.
VIBE provides the vibe.yml playbook to deploy Code-Server, JupyterLab, Node.js, Claude Code, and Codex CLI.
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 and additional npm packages
│ ├── nodejs_install
│ ├── nodejs_config
│ └── nodejs_pkg
├── codex # Codex CLI
│ └── codex_install
└── claude # Claude Code
├── claude_install
└── claude_config
Notes:
jupyter_install uses uv pip, it does not create venvnodejs_pkg installs only the additional packages declared in npm_packages; the list is empty by defaultclaude_install installs Claude CLI with claude_package, while claude_config writes the ~/.claude configurationcodex_install installs @openai/codex and does not manage Codex configuration
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
./vibe.yml -l <host> -t codex
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
./vibe.yml -l <host> -e codex_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_install subtask installs Claude CLI, while claude_config writes the configuration files.
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 claude_install
# or install manually
npm install -g @anthropic-ai/claude-code
Override claude_package if you need a different npm package.
Codex CLI
VIBE installs @openai/codex through codex_install, but does not manage Codex configuration:
which codex
codex --version
./vibe.yml -l <host> -t codex_install
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",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_METRICS_PROTOCOL": "http/protobuf",
"OTEL_EXPORTER_OTLP_LOGS_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 claude_install completed:
which claude
npm list -g --depth=0 | grep '@anthropic-ai/claude-code'
./vibe.yml -l <host> -t claude_install
If claude_enabled is disabled, install manually:
npm install -g @anthropic-ai/claude-code
Use claude_package to select a different npm package.
Codex CLI not found
which codex
npm list -g --depth=0 | grep '@openai/codex'
./vibe.yml -l <host> -t codex_install
Confirm that codex_enabled: true. VIBE installs Codex CLI only and does not generate Codex configuration.
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