Deploy Self-Hosted

Step-by-step guide to deploy Virtual Signer using Docker Compose

Deploy the Virtual Signer on your own infrastructure using Docker Compose for a streamlined, containerised deployment. 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 (8 recommended), 8GB RAM (16GB recommended), and 100GB of SSD 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-signer

2. Create Docker Compose Configuration

Create a docker-compose.yml file with the following content:

version: "3.8"

services:
  virtual-signer:
    container_name: virtual-signer-${ENVIRONMENT:-prod}
    image: iofinnet/io-vault-virtual-signer:${VS_VERSION:-latest}
    restart: unless-stopped
    
    # Port mappings
    ports:
      - "8180:8180"  # API port
      - "9480:9480"  # Prometheus metrics
    
    # Environment configuration
    env_file:
      - ${ENV_FILE_PATH:-./docker.env}
    
    # Volume for data persistence
    volumes:
      - vsigner-data:/var/vsigner
    
    # Logging configuration
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "10"
        compress: "true"
    
    # Health check
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8180/version"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

# Named volumes for data persistence
volumes:
  vsigner-data:
    driver: local

# Network configuration
networks:
  default:
    name: virtual-signer-network
    driver: bridge

3. Configure Environment Variables

Create a docker.env file with your Virtual Signer configuration:

# Core Configuration
EDG_VS_ENV=prod
EDG_VS_Port=8180
EDG_VS_PrometheusPort=9480

# API Authentication (from Virtual Signer app)
EDG_VS_AuthClientId=your_client_id_here
EDG_VS_AuthClientSecret=your_client_secret_here
EDG_VS_OrganisationId=your_org_id_here

# Approval Mode Configuration
# Options: AlwaysApprove, SmartContract, API
EDG_VS_ApprovalMode=SmartContract

# 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

Create a .env file for Docker Compose variables:

# Docker Compose Configuration
ENVIRONMENT=prod
VS_VERSION=latest
ENV_FILE_PATH=./docker.env

4. Deploy the Virtual Signer

Pull the latest image and start the container:

# Pull the latest Virtual Signer image
docker-compose pull

# Start the Virtual Signer in detached mode
docker-compose up -d

# Verify the deployment
docker-compose ps

# View logs
docker-compose logs -f virtual-signer

Initial Setup and Verification

Verify Operation

Check that your Virtual Signer is running correctly:

# Test version endpoint
curl http://localhost:8180/version

# Check Prometheus metrics
curl http://localhost:9480/metrics

# View container resource usage
docker stats virtual-signer

Managing 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 down

Updating the Virtual Signer

To update to a new version, modify the VS_VERSION in your .env file or pull the latest image:

# Update to latest version
docker-compose pull
docker-compose down
docker-compose up -d

# Use a specific version
VS_VERSION=v1.2.3 docker-compose up -d

Viewing Logs

Monitor your Virtual Signer's operation through Docker logs:

# View recent logs
docker-compose logs --tail=100 virtual-signer

# Follow logs in real-time
docker-compose logs -f virtual-signer

# View logs for a specific time period
docker-compose logs --since="2024-01-01" --until="2024-01-02" virtual-signer

Data 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="virtual-signer-prod"

# Create backup directory
mkdir -p "$BACKUP_DIR"

# Stop container for consistent backup
docker-compose stop

# Create backup of volume
docker run --rm \
  -v vsigner-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 vsigner-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 -d

Advanced Configuration

Custom Network Configuration

deploy:
  resources:
    limits:
      cpus: '8'      # Increase for high-volume signing
      memory: 16G    # Increase for multiple concurrent operations
    reservations:
      cpus: '4'
      memory: 8G

Monitoring Integration

Prometheus Scraping

Configure your Prometheus server to scrape Virtual Signer metrics:

# prometheus.yml
scrape_configs:
  - job_name: 'virtual-signer'
    static_configs:
      - targets: ['virtual-signer-host:9480']
    metrics_path: '/metrics'
    scrape_interval: 30s

Grafana Dashboard

Import pre-built dashboards or create custom visualisations for Virtual Signer metrics including signing operations per second, key generation latency, active vault connections, and error rates by type.

Troubleshooting

Container Won't Start

If the container fails to start, check the logs for specific error messages:

docker-compose logs virtual-signer | tail -50

Common issues include incorrect API credentials in docker.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 virtual-signer sh -c "
  nc -zv mqtt.vault.iofinnet.com 8084 &&
  nc -zv api.iofinnet.com 443
"

High Memory Usage

Monitor and manage memory consumption:

# Check current usage
docker stats virtual-signer

# Restart to clear memory
docker-compose restart virtual-signer

# Adjust memory limits if needed
# Edit docker-compose.yml deploy.resources section

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:

  1. Configure monitoring and alerting for your Virtual Signer instance
  2. Set up automated backups with regular testing of restore procedures
  3. Review the Self-Hosting documentation for detailed technical information
  4. Implement your approval policies via smart contracts or API endpoints
  5. Test signing operations in a development environment before production use

For additional support, consult the Configuration Reference or contact io.finnet support.