Deploy Self-Hosted
Deployment of Virtual Signer on your own hardware with Docker Compose
Deploy the Virtual Signer on your own infrastructure using Docker Compose for a streamlined, containerised deployment on your own physical hardware. This guide provides practical steps to get your Virtual Signer running quickly on standard Linux servers.
For architectural details and security considerations, see the Self-Hosting documentation.
Prerequisites
Before beginning deployment, ensure your system meets these requirements:
System Requirements
Your deployment system needs Docker version 20.10 or later and Docker Compose version 2.0 or later installed and operational. The host machine should have at least 4 CPU cores, 8GB RAM and 100GB of storage for application data and logs. A stable internet connection with low latency is essential for MPC coordination and blockchain interactions.
Network Configuration
Configure your firewall to allow outbound connections to mqtt.vault.iofinnet.com on port 8084 for MPC coordination and api.iofinnet.com on port 443 for API access. You'll also need connectivity to your blockchain RPC endpoint and any smart contract endpoints if using smart contract approval mode. For inbound traffic, open port 8180 for the Virtual Signer API and port 9480 for Prometheus metrics collection.
API Credentials
Before deployment, obtain your API credentials from the Virtual Signer application at app.iofinnet.com. You'll need your Client ID, Client Secret, and Organisation ID for the configuration.
Quick Start
The fastest way to deploy is using our pre-configured Docker Compose setup:
1. Create Project Directory
# Create and enter the Virtual Signer directory
mkdir -p ~/virtual-signer && cd ~/virtual-signer2. Create Docker Compose Configuration
Create a docker-compose.yml file with the following content:
name: io-vault
services:
# MPC Core Service - handles MPC cryptographic operations and SEV-SNP attestation
vs-server:
image: iofinnet/io-vault-virtual-signer-server:latest
container_name: io-vault-vs-server
ports:
- "${VS_SERVER_PORT:-8181}:8181" # MPC Core API
- "${VS_SERVER_METRICS:-2112}:2112" # Prometheus metrics
environment:
EDG_VS_ENV: "${VS_ENV:-prod}"
EDG_VS_Port: "8181"
EDG_VS_PrometheusPort: "2112"
EDG_VS_LogLevel: "${VS_LOG_LEVEL:-info}"
# AMD SEV-SNP device - only needed on x86_64 with SEV hardware
# Comment out for ARM64 or non-SEV x86_64 deployments
devices:
- "/dev/sev-guest:/dev/sev-guest:rw"
volumes:
- vs_data:/var/vsigner
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8181/api/v1/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
logging:
driver: json-file
options:
max-size: "100m"
max-file: "10"
compress: "true"
restart: unless-stopped
init: true
networks:
- vsigner-net
# VS Light Service - handles signing requests and approvals
vs-light:
image: iofinnet/io-vault-virtual-signer-light:latest
container_name: io-vault-vs-light
depends_on:
vs-server:
condition: service_healthy
ports:
- "${VS_LIGHT_PORT:-8182}:8182" # VS Light API
- "${VS_LIGHT_METRICS:-2113}:2113" # Prometheus metrics
environment:
EDG_VS_ENV: "${VS_ENV:-prod}"
EDG_VS_Port: "8182"
EDG_VS_PrometheusPort: "2113"
EDG_VS_MPCCorePort: "8181"
EDG_VS_LogLevel: "${VS_LOG_LEVEL:-info}"
# Authentication (required - obtain from app.iofinnet.com)
EDG_VS_AuthClientId: "${VS_AUTH_CLIENT_ID:?VS_AUTH_CLIENT_ID is required}"
EDG_VS_AuthClientSecret: "${VS_AUTH_CLIENT_SECRET:?VS_AUTH_CLIENT_SECRET is required}"
EDG_VS_OrgId: "${VS_ORG_ID:?VS_ORG_ID is required}"
# Approval mode: AlwaysApprove, SmartContract, or API
EDG_VS_ApprovalMode: "${VS_APPROVAL_MODE:-AlwaysApprove}"
# Smart Contract approval mode (optional)
EDG_VS_ApprovalNodeRPCAddress: "${VS_APPROVAL_RPC_ADDRESS:-}"
EDG_VS_ApprovalSmartContractAddress: "${VS_APPROVAL_CONTRACT_ADDRESS:-}"
# API approval mode (optional)
EDG_VS_ExternalTransactionApprovalURL: "${VS_EXTERNAL_TX_APPROVAL_URL:-}"
EDG_VS_ExternalReshareApprovalURL: "${VS_EXTERNAL_RESHARE_APPROVAL_URL:-}"
EDG_VS_ApprovalHTTPPublicKeyHex: "${VS_APPROVAL_PUBLIC_KEY_HEX:-}"
volumes:
- vs_data:/var/vsigner
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8182/api/v1/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
logging:
driver: json-file
options:
max-size: "100m"
max-file: "10"
compress: "true"
restart: unless-stopped
init: true
networks:
- vsigner-net
volumes:
vs_data:
driver: local
networks:
vsigner-net:
driver: bridge
3. Configure Environment Variables
Create a .env file with your Virtual Signer configuration:
# io.finnet Virtual Signer - Environment Configuration
# Copy this file to .env and fill in your values
# =============================================================================
# REQUIRED - Authentication (obtain from app.iofinnet.com)
# =============================================================================
VS_AUTH_CLIENT_ID=your-client-id
VS_AUTH_CLIENT_SECRET=your-client-secret
VS_ORG_ID=your-org-id
# =============================================================================
# OPTIONAL - Configuration
# =============================================================================
# Environment: prod, staging, dev
VS_ENV=prod
# Approval mode: AlwaysApprove, SmartContract, or API
# For approval modes other than the default, extra environment variables are needed.
# See: https://docs.iofinnet.com/docs/policy-modes-1
VS_APPROVAL_MODE=AlwaysApprove
# Smart Contract Configuration (if using Smart Contract mode)
# EDG_VS_SCConfigRPCAddress=https://polygon-rpc.com/
# EDG_VS_SCConfigContractAddress=0x34a18dc10bD405435b22f70Ed8Df2D9E089A3813
# API Approval Configuration (if using API mode)
# EDG_VS_ExternalTransactionApprovalUrl=https://your-api.com/approve
# EDG_VS_ApprovalHttpPublicKeyHex=your_public_key_hex
# Log level: debug, info, warn, error
VS_LOG_LEVEL=info
# =============================================================================
# OPTIONAL - Port mappings (defaults shown)
# =============================================================================
# VS Server (mpccore)
VS_SERVER_PORT=8181
VS_SERVER_METRICS=2112
# VS Light
VS_LIGHT_PORT=8182
VS_LIGHT_METRICS=21134. Deploy the Virtual Signer
Pull the latest image and start the container:
# Start the Virtual Signer in detached mode
docker compose up -d
# Verify the deployment
docker compose ps
# View logs
docker compose logs -f vs-lightInitial Setup and Verification
Verify Operation
Check that your Virtual Signer is running correctly:
# Test version endpoint
curl http://localhost:8182/api/v1/version
# Check Prometheus metrics
curl http://localhost:2112/metrics
curl http://localhost:2113/metrics
# View container resource usage
docker compose statsManaging Your Deployment
Starting and Stopping
Control your Virtual Signer deployment with standard Docker Compose commands:
# Stop the Virtual Signer
docker compose stop
# Start a stopped instance
docker compose start
# Restart the Virtual Signer
docker compose restart
# Stop and remove containers (data is preserved in volumes)
docker compose downUpdating the Virtual Signer
To update to a new version, pull the latest image:
# Update to latest version
docker compose pull
docker compose down
docker compose up -dYou can find available versions on our Docker hub: https://hub.docker.com/u/iofinnet
Viewing Logs
Monitor your Virtual Signer's operation through Docker logs:
# Follow logs in real-time
docker compose logs -f vs-light
docker compose logs -f vs-serverData Persistence
The Virtual Signer stores critical data that must be preserved between container restarts and updates. Docker volumes automatically handle this persistence, storing encrypted key shares, device credentials, and operational state. The named volume vsigner-data contains all persistent data mapped to /var/vsigner inside the container.
Backup Procedures
Regular backups protect against data loss and enable disaster recovery:
#!/bin/bash
# Backup script for Virtual Signer data
BACKUP_DIR="/backup/virtual-signer"
DATE=$(date +%Y%m%d_%H%M%S)
CONTAINER_NAME="vs-light"
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Stop container for consistent backup
docker compose stop
# Create backup of volume
docker run --rm \
-v vs_data:/source:ro \
-v "$BACKUP_DIR":/backup \
alpine tar czf "/backup/vs_backup_$DATE.tar.gz" -C /source .
# Restart container
docker compose start
echo "Backup completed: $BACKUP_DIR/vs_backup_$DATE.tar.gz"Restore Procedures
To restore from a backup:
#!/bin/bash
# Restore script for Virtual Signer data
BACKUP_FILE="/backup/virtual-signer/vs_backup_20240101_120000.tar.gz"
# Stop container
docker compose down
# Restore volume from backup
docker run --rm \
-v vs_data:/target \
-v "$(dirname $BACKUP_FILE)":/backup:ro \
alpine tar xzf "/backup/$(basename $BACKUP_FILE)" -C /target
# Start container with restored data
docker compose up -dAdvanced Configuration
Increasing maximum resources for containers
deploy:
resources:
limits:
cpus: '8' # Increase for high-volume signing
memory: 16G # Increase for multiple concurrent operations
reservations:
cpus: '4'
memory: 8GMonitoring Integration
Prometheus Scraping
Configure your Prometheus server to scrape Virtual Signer metrics:
# prometheus.yml
scrape_configs:
- job_name: 'virtual-signer-server'
static_configs:
- targets: ['virtual-signer-host:2112']
metrics_path: '/metrics'
scrape_interval: 30s
- job_name: 'virtual-signer-light'
static_configs:
- targets: ['virtual-signer-host:2113']
metrics_path: '/metrics'
scrape_interval: 30sTroubleshooting
Container Won't Start
If the container fails to start, check the logs for specific error messages:
docker compose logs vs-light | tail -50
docker compose logs vs-server | tail -50Common issues include incorrect API credentials in .env, network connectivity problems reaching io.vault services, port conflicts with other services, or insufficient system resources.
Connection Issues
Verify network connectivity to required endpoints:
# Test connectivity from container
docker compose exec vs-light /bin/bash -c '
</dev/tcp/mqtt.vault.iofinnet.com/8084 &&
</dev/tcp/api.iofinnet.com/443 &&
echo 'OK'
'Data Recovery
If you lose your persistent data without backups, you'll need to create new Virtual Signer devices through the io.vault application. Previous keys and signing capabilities cannot be recovered without the encrypted key shares stored in the Docker volume.
Security Considerations
Self-hosted deployments require careful attention to security. Implement firewall rules to restrict access to Virtual Signer ports, use VPN or private networks for management access, enable audit logging for all administrative actions, and regularly update Docker and the host operating system. Consider encrypting the Docker volume at the filesystem level using LUKS or similar technologies for additional protection of data at rest.
Next Steps
After successful deployment:
- Configure monitoring and alerting for your Virtual Signer instance
- Set up automated backups with regular testing of restore procedures
- Review the Self-Hosting documentation for detailed technical information
- Implement your approval policies via smart contracts or API endpoints
- Test signing operations in a development environment before production use
For additional support, consult the Configuration Reference or contact io.finnet support.
Updated 19 days ago