xbp universal build and deployment toolkit
xbp helps you build deploy and manage rust nextjs nodejs python expressjs and more integrates tightly with nginx and modern cloud devops workflows modular scriptable and built with extensibility in mind
current version: 10.8.4
Coverage XBP vs PM2
- Process manager
- Zero downtime reloads
- Terminal based monitoring
- web based monitor interface
- synthetic application overview
- track bugs and exceptions
- custom metrics
- consult application logs
- monitor node.js v8 behavior
- Receive emails / slack notifications
- server health check monitoring
- in-situ cpu and memory profiling
- transaction tracing
- advanced rule-based alerting
- custom dashboards
- long term data retention
- dedicated or on-premise install
- go / python integration
features
- deploy and manage rust js nextjs python expressjs and custom multi language projects
- nginx integration and config templating
- modular cli with portable library core
- easy yaml config ssh support secrets management
- lightweight minimal dependencies cross platform
- multi service deployment support with pm2 integration
- version management via api integration
- service based configuration with validation
quickstart
# install rust cargo required
# or build from source
# list all running network ports
# filter by port number
# list all services in current project
# build a service
# redeploy a service
installation
- release binaries see releases
- from source requires rust 1.72+
configuration
xbp uses configuration files located in .xbp/xbp.json, .xbp/xbp.yaml, or in the project root. both json and yaml formats are supported.
configuration file locations
xbp searches for configuration files in the following order:
.xbp/xbp.yamlor.xbp/xbp.json(recommended)xbp.yamlorxbp.json(project root)
xbp.json schema
minimal configuration
complete json schema with all fields
multi service example with all features
xbp.yaml schema
xbp also supports yaml format which is more readable and supports comments.
minimal yaml configuration
project_name: my-app
port: 3000
build_dir: /path/to/project
complete yaml schema with all fields
# Core configuration (all required)
project_name: string # project name
port: 3000 # main application port 1-65535
build_dir: /path/to/project # absolute path to project directory
# Application configuration (optional)
app_type: rust # application type: rust, nextjs, nodejs, python, expressjs
build_command: cargo build --release # command to build the application
start_command: ./target/release/my-app # command to start the application
install_command: cargo fetch # command to install dependencies
# Environment variables (optional)
environment:
NODE_ENV: production
RUST_LOG: info
DATABASE_URL: postgresql://localhost/mydb
# Multi-service configuration (optional)
services:
- name: api # unique service name (required)
target: rust # one of: python, expressjs, nextjs, rust (required)
branch: main # git branch to deploy from (required)
port: 3000 # service port number (required)
root_directory: apps/api # relative or absolute path to service root (optional)
url: https://api.example.com # service url for healthchecks (optional)
healthcheck_path: /health # path for healthcheck requests (optional)
restart_policy: on_failure # pm2 restart policy (optional, defaults to on_failure)
restart_policy_max_failure_count: 10 # max failures before stopping (optional, defaults to 10)
start_wrapper: pm2 # wrapper for start command (optional, typically pm2)
force_run_from_root: false # if true runs commands from project root (optional, defaults to false)
environment:
RUST_LOG: info
DATABASE_URL: postgresql://localhost/db
commands:
pre: rustup update stable # command to run before install (optional)
install: cargo fetch # command to install dependencies (optional)
build: cargo build --release # command to build the service (optional)
start: ./target/release/api # command to start the service (optional)
dev: cargo watch -x run # command to run in development mode (optional)
# Monitoring configuration (optional)
monitor_url: https://api.example.com/health # url to monitor for health checks
monitor_method: GET # http method for monitoring: GET, POST, etc
monitor_expected_code: 200 # expected http status code (defaults to 200)
monitor_interval: 60 # interval between health checks in seconds (defaults to 60)
# Logging configuration (optional)
log_files:
- /var/log/app/api.log
- /var/log/app/frontend.log
- /home/user/.pm2/logs/api-out.log
# Kafka configuration (optional)
kafka_brokers: localhost:9092 # kafka broker addresses, format: host:port or host1:port1,host2:port2
kafka_topic: application-logs # kafka topic for logs
kafka_public_url: https://kafka.example.com:9092 # public kafka url
# Legacy fields for backward compatibility (optional)
target: rust # deprecated - use app_type instead
branch: main # git branch name for legacy single service
crate_name: my_api # rust crate name for legacy single service
npm_script: start # npm script to run for legacy single service
url: https://example.com # public url for legacy single service
multi service yaml example with all features
project_name: my-microservices
port: 3000
build_dir: /home/user/projects/microservices
services:
- name: api
target: rust
branch: main
port: 3000
root_directory: apps/api
url: https://api.example.com
healthcheck_path: /health
restart_policy: on_failure
restart_policy_max_failure_count: 10
start_wrapper: pm2
force_run_from_root: false
environment:
RUST_LOG: info
DATABASE_URL: postgresql://localhost/db
commands:
pre: rustup update stable
install: cargo fetch
build: cargo build --release
start: ./target/release/api
dev: cargo watch -x run
- name: frontend
target: nextjs
branch: main
port: 3001
root_directory: apps/frontend
url: https://app.example.com
healthcheck_path: /api/health
restart_policy: always
start_wrapper: pm2
force_run_from_root: false
environment:
NODE_ENV: production
NEXT_PUBLIC_API_URL: https://api.example.com
commands:
pre: npm install -g pnpm
install: pnpm install
build: pnpm run build
start: pnpm run start
dev: pnpm run dev
- name: worker
target: python
branch: main
port: 3002
root_directory: apps/worker
restart_policy: on_failure
start_wrapper: pm2
environment:
PYTHONPATH: /home/user/projects/microservices/apps/worker
commands:
install: pip install -r requirements.txt
start: python main.py
monitor_url: https://api.example.com/health
monitor_method: GET
monitor_expected_code: 200
monitor_interval: 60
log_files:
- /var/log/app/api.log
- /var/log/app/frontend.log
- /home/user/.pm2/logs/api-out.log
kafka_brokers: localhost:9092
kafka_topic: application-logs
kafka_public_url: https://kafka.example.com:9092
environment:
NODE_ENV: production
LOG_LEVEL: info
service configuration field reference
required fields
- name - unique service name
- target - one of:
python,expressjs,nextjs,rust - branch - git branch to deploy from
- port - service port number (1-65535)
optional fields
- root_directory - relative or absolute path to service root (defaults to project root)
- url - service url for healthchecks
- healthcheck_path - path for healthcheck requests
- restart_policy - pm2 restart policy (defaults to
on_failure) - restart_policy_max_failure_count - max failures before stopping (defaults to 10)
- start_wrapper - wrapper for start command, typically
pm2 - force_run_from_root - if true, runs commands from project root instead of root_directory (defaults to false)
- environment - object containing environment variables for the service
- commands - object containing pre, install, build, start, dev commands
configuration validation
xbp validates service configurations and will error if:
- duplicate service names found
- duplicate ports found
- duplicate urls found
- invalid target type (not one of: python, expressjs, nextjs, rust)
- missing required fields (project_name, port, build_dir for top level; name, target, branch, port for services)
commands
service management
xbp serviceslist all services from current xbp.json configxbp service <command> <service-name>run command for a service- commands: build install start dev
- example:
xbp service build zeus
xbp service --help <service-name>show help for a specific servicexbp redeploy <service-name>redeploy a specific service via pm2
deployment
xbp redeploy [<service-name>]redeploy using redeploy.sh legacy or specific servicexbp redeploy_v2 [-p <password>] [-u <username>] [-h <host>] [-d <project-dir>]remotely redeploy using redeploy.sh
general
xbp ports [-p <port>] [--kill] [-n]list active ports and processes optionally search nginx configsxbp setuprun initial setup commandsxbp configdisplay xbp.json contentsxbp install <package>install a packagexbp logs [<project>]view pm2 logsxbp listlist pm2 processesxbp -llist pm2 processes shortcutxbp curl [<url>]fetch url and display response
redeploy workflow
when you run xbp redeploy <service-name> the following happens
- git reset --hard to clean local changes
- git pull origin to get latest code
- fetch version from api.xbp.app/version?project_name=
- create dist folder at /home/{USER}/.xbp/dist/{version}/
- run pre command if configured
- run install command if configured
- run build command if configured
- stop existing pm2 process for the service
- copy build artifacts to dist folder
- start pm2 process with wrapped start command
- write logs to .xbp/logs/{service-name}/
- update version via api increment endpoint
- cleanup stopped and errored pm2 processes
service commands
service commands respect the root_directory and force_run_from_root settings
- if force_run_from_root is true commands run from project root
- if root_directory is set and force_run_from_root is false commands run from root_directory
- if neither is set commands run from project root
start commands are automatically wrapped with pm2 when start_wrapper is set to pm2
the start command will be executed as pm2 start "{start_command}" --name {name} -- --port {port}
pm2 integration
xbp integrates with pm2 for process management
- processes are named using the service name
- logs are written to .xbp/logs/{service-name}/stdout.log and stderr.log
- pm2 save is called after deployments to persist process list
- stopped and errored processes are automatically cleaned up
version management
xbp integrates with the xbp version api for version tracking
- versions are fetched from api.xbp.app/version?project_name=
- versions are incremented via api.xbp.app/version/increment after successful deployment
- version folders are created at /home/{USER}/.xbp/dist/{version}/
logging
xbp writes logs to multiple locations
- general logs: /var/log/xbp/ or ~/.xbp/logs/
- service logs: .xbp/logs/{service-name}/stdout.log and stderr.log
- pm2 logs: redirected to service log directories
logs are rotated when they exceed 10mb
architecture
/src/main.rscli entrypoint command parsing and dispatch/src/lib.rscore library module exports/src/commands/cli subcommand implementationsservice.rsservice management commandsredeploy_service.rsservice redeployment logicpm2.rspm2 process managementconfig_cmd.rsconfiguration display- and more
/src/strategies/deployment strategies and config managementdeployment_config.rsconfig loading validation and service managementproject_detector.rsproject type detectiondeployment_executor.rsdeployment execution
/src/utils/utility functionsversion.rsversion api integration
/src/logging.rsstructured async logging/src/config.rsssh and yaml config management
backward compatibility
xbp maintains backward compatibility with legacy single service configurations if no services array is found in xbp.json the top level config is treated as a single service this allows existing projects to continue working without modification
examples
list all services
build a service
install dependencies for a service
start a service with pm2
run dev mode for a service
redeploy a service
show help for a service
contributing
prs welcome please document new modules and keep interfaces generic and reusable see src/lib.rs for api docs all code must follow rust conventions documentation should be lowercase with minimal punctuation
license
mit