Standalone Deployment Overview
This guide explains how to deploy ApiCharge as a standalone application directly on your server or virtual machine. Standalone deployment gives you more control over the environment and allows for custom integration with your infrastructure.
Prerequisites
- Stellar RPC server (required, must be running separately)
- Redis server (optional, but recommended for production)
- HTTPS certificate (for production deployments)
- Server with sufficient resources (see System Requirements)
Installation Steps
Download the ApiCharge Native Binary
ApiCharge is distributed as a self-contained, native binary that doesn't require .NET runtime installation.
Early Access Program
The ApiCharge native binary is currently available through our Early Access Program. Contact our team or use your Early Access credentials to download the appropriate release for your platform.
Extraction and Permissions
After downloading, extract the archive to your application directory and set the appropriate permissions:
# Extract the downloaded archive
tar -xzf apicharge-release.tar.gz -C /opt/apicharge/app
# Make the binary executable
chmod +x /opt/apicharge/app/ApiChargePrototype
Verify the installation by running:
/opt/apicharge/app/ApiChargePrototype --version
Prepare Installation Directory
Create a directory where you'll place the ApiCharge native binary and its configuration files:
The ApiCharge binary requires its configuration file (appsettings.json) to be in the same directory as the executable, following standard .NET Core conventions.
The binary will automatically create any additional required directories during runtime based on your configuration settings.
Configure ApiCharge
Create the main configuration file appsettings.json
in the /opt/apicharge/config
directory:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
},
"File": {
"Path": "/opt/apicharge/logs/apicharge.log",
"FileSizeLimitBytes": 10485760,
"MaxRollingFiles": 10
}
},
"GlobalSettings": {
"UseNetwork": "Testnet",
"ToleratedClockSkew": "00:02:00",
"QuoteValidityDuration": "01:00:00",
"SigningKeyEnvironmentVariable": "APICHARGE_SIGNING_KEY",
"StellarEndpointRPC": "https://soroban-testnet.stellar.org",
"StellarNetworkPassphraseEnvironmentVariable": "APICHARGE_NETWORK_PASSPHRASE",
"AllowSelfSignedServerCertificates": false,
"AllowedServerCertificateThumbprints": [],
"AllowedServerCertificateIssuers": []
},
"ApiChargeQuotes": {
"Quotes": [
{
"RouteId": "basic-route",
"Duration": 3600,
"MicroUnitPrice": 100000,
"RateLimiters": [
{
"$type": "CallCount",
"Count": 100
},
{
"$type": "DataLimitDownload",
"Bytes": 10485760
}
]
},
{
"RouteId": "premium-route",
"Duration": 3600,
"MicroUnitPrice": 500000,
"RateLimiters": [
{
"$type": "CallCount",
"Count": 1000
},
{
"$type": "DataLimitDownload",
"Bytes": 104857600
}
]
}
]
},
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://0.0.0.0:5000"
},
"Https": {
"Url": "https://0.0.0.0:5001",
"Certificate": {
"Path": "/opt/apicharge/config/certificate.pfx",
"Password": "CERTIFICATE_PASSWORD_HERE"
}
}
}
},
"Redis": {
"ConnectionString": "localhost:6379,abortConnect=false,connectTimeout=5000",
"InstanceName": "ApiCharge-"
},
"RateLimiterPersistence": {
"UseRedis": true,
"PersistenceIntervalSeconds": 30,
"RedisExpiryMultiplier": 2
},
"Routes": {
"Clusters": [
{
"ClusterId": "defaultCluster",
"Destinations": [
{
"Address": "http://localhost:8080"
}
]
}
],
"Routes": [
{
"RouteId": "basic-route",
"ClusterId": "defaultCluster",
"Match": {
"Path": "/api/basic/{**remainder}"
}
},
{
"RouteId": "premium-route",
"ClusterId": "defaultCluster",
"Match": {
"Path": "/api/premium/{**remainder}"
}
}
]
}
}
Modify this configuration based on your specific requirements. For detailed configuration options, see the Configuration documentation.
Configure Environment Variables
Create an environment variables file at /opt/apicharge/scripts/env.sh
:
#!/bin/bash
# Signing key (replace with your actual Stellar secret key)
export APICHARGE_SIGNING_KEY="SDH3X...YOUR_STELLAR_SECRET_KEY"
# Network passphrase
export APICHARGE_NETWORK_PASSPHRASE="Test SDF Network ; September 2015"
# Environment
export ASPNETCORE_ENVIRONMENT="Production"
export DOTNET_ENVIRONMENT="Production"
# Paths
export ASPNETCORE_CONTENTROOT="/opt/apicharge/app"
export ASPNETCORE_URLS="http://0.0.0.0:5000;https://0.0.0.0:5001"
# Certificate password if using PFX
export CERTIFICATE_PASSWORD="your_cert_password_here"
Make the script executable:
chmod +x /opt/apicharge/scripts/env.sh
Set Up Stellar RPC Server
The standalone ApiCharge binary requires a separately running Stellar RPC server. You have two options:
Option 1: Connect to an existing Stellar RPC server
Update your appsettings.json to point to your Stellar RPC server:
"ApiChargeProxy": {
"Global": {
"StellarEndpointRPC": "http://localhost:8000",
// Other settings...
}
}
Option 2: Run your own Stellar RPC server
Follow the Stellar Soroban RPC documentation to set up your own RPC server. This is recommended for production environments to ensure reliability and performance.
For more details on Stellar RPC server integration, see the Stellar RPC Server Integration section.
Deploy the Application
ApiCharge is distributed as a platform-specific, self-contained native binary through our Early Access Program. Native binaries are available for Windows, Linux, and macOS platforms.
Extract your platform-specific ApiCharge native binary to the application directory:
cd /opt/apicharge/app
# For Linux x64 (example)
tar -xzf apicharge-linux-x64.tar.gz
chmod +x ApiChargePrototype
# For Windows x64 (example)
# Extract apicharge-win-x64.zip to C:\apicharge\app
# For macOS x64/arm64 (example)
tar -xzf apicharge-osx-x64.tar.gz # or apicharge-osx-arm64.tar.gz
chmod +x ApiChargePrototype
These native binaries are compiled with AOT (Ahead-of-Time) technology, which results in improved startup performance and reduced memory footprint. Since they are self-contained, they don't require any .NET runtime to be installed on the target system.
Running the Application
The ApiCharge native binary can be run directly on any supported platform. You'll need to set the required environment variables and specify the listening URLs.
Windows
set APICHARGE_SIGNING_KEY=SDH3X...YOUR_STELLAR_SECRET_KEY
set APICHARGE_NETWORK_PASSPHRASE=Test SDF Network ; September 2015
set ASPNETCORE_ENVIRONMENT=Production
ApiChargePrototype.exe --urls="http://0.0.0.0:5000;https://0.0.0.0:5001"
Linux/macOS
export APICHARGE_SIGNING_KEY=SDH3X...YOUR_STELLAR_SECRET_KEY
export APICHARGE_NETWORK_PASSPHRASE="Test SDF Network ; September 2015"
export ASPNETCORE_ENVIRONMENT=Production
./ApiChargePrototype --urls="http://0.0.0.0:5000;https://0.0.0.0:5001"
For a complete list of environment variables, see the Environment Variables documentation.
For production deployments, you may want to create a startup script or service definition appropriate for your operating system.
Create Systemd Service
For production deployments, create a systemd service file at /etc/systemd/system/apicharge.service
:
[Unit]
Description=ApiCharge API Monetization Service
After=network.target redis.service
[Service]
Type=simple
User=apicharge
Group=apicharge
WorkingDirectory=/opt/apicharge/app
ExecStart=/opt/apicharge/scripts/start.sh
Restart=always
RestartSec=10
SyslogIdentifier=apicharge
EnvironmentFile=/opt/apicharge/scripts/env.sh
# Security enhancements
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
ProtectHome=true
[Install]
WantedBy=multi-user.target
Create a dedicated user for the service:
sudo useradd -r -s /bin/false apicharge
sudo chown -R apicharge:apicharge /opt/apicharge
Enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable apicharge
sudo systemctl start apicharge
Configure Logging
ApiCharge logs to both the console and file by default. To configure log rotation, install and configure logrotate:
sudo apt-get install logrotate
sudo nano /etc/logrotate.d/apicharge
Add the following configuration:
/opt/apicharge/logs/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 apicharge apicharge
sharedscripts
postrotate
systemctl reload apicharge
endscript
}
Verify Installation
Check that the service is running correctly:
sudo systemctl status apicharge
curl http://localhost:5000/apicharge/health
If everything is configured correctly, the health endpoint should return a 200 OK status.
Configuration Examples
Basic Configuration
Here's a minimal configuration for testing purposes:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"GlobalSettings": {
"UseNetwork": "Testnet",
"SigningKeyEnvironmentVariable": "APICHARGE_SIGNING_KEY",
"StellarNetworkPassphraseEnvironmentVariable": "APICHARGE_NETWORK_PASSPHRASE"
},
"ApiChargeQuotes": {
"Quotes": [
{
"RouteId": "test-route",
"Duration": 3600,
"MicroUnitPrice": 100000,
"RateLimiters": [
{
"$type": "CallCount",
"Count": 100
}
]
}
]
},
"Routes": {
"Clusters": [
{
"ClusterId": "testCluster",
"Destinations": [
{
"Address": "http://localhost:8080"
}
]
}
],
"Routes": [
{
"RouteId": "test-route",
"ClusterId": "testCluster",
"Match": {
"Path": "/api/{**remainder}"
}
}
]
}
}
Production Configuration
For production environments, consider this more comprehensive configuration:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
},
"File": {
"Path": "/opt/apicharge/logs/apicharge.log",
"FileSizeLimitBytes": 10485760,
"MaxRollingFiles": 10
}
},
"GlobalSettings": {
"UseNetwork": "Mainnet",
"ToleratedClockSkew": "00:01:00",
"QuoteValidityDuration": "01:00:00",
"SigningKeyEnvironmentVariable": "APICHARGE_SIGNING_KEY",
"StellarEndpointRPC": "https://soroban.stellar.org",
"StellarNetworkPassphraseEnvironmentVariable": "APICHARGE_NETWORK_PASSPHRASE",
"AllowSelfSignedServerCertificates": false
},
"ApiChargeQuotes": {
"Quotes": [
{
"RouteId": "basic-api",
"Duration": 3600,
"MicroUnitPrice": 100000,
"RateLimiters": [
{
"$type": "CallCount",
"Count": 100
},
{
"$type": "DataLimitDownload",
"Bytes": 10485760
}
]
},
{
"RouteId": "standard-api",
"Duration": 3600,
"MicroUnitPrice": 250000,
"RateLimiters": [
{
"$type": "CallCount",
"Count": 500
},
{
"$type": "DataLimitDownload",
"Bytes": 52428800
}
]
},
{
"RouteId": "premium-api",
"Duration": 3600,
"MicroUnitPrice": 500000,
"RateLimiters": [
{
"$type": "CallCount",
"Count": 1000
},
{
"$type": "DataLimitDownload",
"Bytes": 104857600
}
]
}
]
},
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"Https": {
"Url": "https://0.0.0.0:5001",
"Certificate": {
"Path": "/opt/apicharge/config/certificate.pfx",
"Password": "CERTIFICATE_PASSWORD_HERE"
}
}
},
"AddServerHeader": false
},
"Redis": {
"ConnectionString": "redis.example.com:6379,password=YOUR_REDIS_PASSWORD,ssl=true,abortConnect=false",
"InstanceName": "ApiCharge-Prod-"
},
"RateLimiterPersistence": {
"UseRedis": true,
"PersistenceIntervalSeconds": 10,
"RedisExpiryMultiplier": 2
},
"Routes": {
"Clusters": [
{
"ClusterId": "apiCluster",
"Destinations": [
{
"Address": "https://api-backend-1.example.com",
"Health": {
"Active": {
"Enabled": true,
"Interval": "00:00:10",
"Timeout": "00:00:10",
"Path": "/health"
}
}
},
{
"Address": "https://api-backend-2.example.com",
"Health": {
"Active": {
"Enabled": true,
"Interval": "00:00:10",
"Timeout": "00:00:10",
"Path": "/health"
}
}
}
],
"HttpClient": {
"MaxConnectionsPerServer": 100,
"DangerousAcceptAnyServerCertificate": false,
"RequestHeaderEncoding": "utf-8",
"ResponseHeaderEncoding": "utf-8"
},
"LoadBalancingPolicy": {
"Type": "RoundRobin"
},
"HealthCheck": {
"Active": {
"Enabled": true,
"Interval": "00:00:10",
"Timeout": "00:00:05",
"Path": "/health"
},
"Passive": {
"Enabled": true,
"ReactivationPeriod": "00:00:10"
}
}
}
],
"Routes": [
{
"RouteId": "basic-api",
"ClusterId": "apiCluster",
"Match": {
"Path": "/api/basic/{**remainder}",
"Methods": [ "GET" ]
},
"Transforms": [
{ "PathPattern": "/api/v1/{**remainder}" }
]
},
{
"RouteId": "standard-api",
"ClusterId": "apiCluster",
"Match": {
"Path": "/api/standard/{**remainder}",
"Methods": [ "GET", "POST" ]
},
"Transforms": [
{ "PathPattern": "/api/v1/{**remainder}" },
{ "RequestHeadersCopy": "true" },
{ "RequestHeaderOriginalHost": "true" }
]
},
{
"RouteId": "premium-api",
"ClusterId": "apiCluster",
"Match": {
"Path": "/api/premium/{**remainder}"
},
"Transforms": [
{ "PathPrefix": "/api/v2" },
{ "RequestHeadersCopy": "true" },
{ "RequestHeaderOriginalHost": "true" },
{ "X-Forwarded": "proto,host,for,prefix" }
]
}
]
}
}
Stellar RPC Server Management
For standalone deployments with the native binary, you must use an external Stellar RPC server:
External RPC Server Configuration
Configure your ApiCharge to connect to an external Stellar RPC server by setting the StellarEndpointRPC in your appsettings.json:
{
"ApiChargeProxy": {
"Global": {
"UseNetwork": "Testnet",
"StellarEndpointRPC": "http://localhost:8000",
// Other settings...
}
}
}
You can use:
- A locally running Stellar RPC instance
- A shared Stellar RPC server in your infrastructure
- A public Stellar RPC endpoint (not recommended for production)
Benefits of External RPC Server
Using an external Stellar RPC server offers several advantages:
- Share the RPC server across multiple ApiCharge instances
- Scale the RPC server independently
- Use specialized hardware for the blockchain operations
- Implement custom monitoring and management
For more details, see the Stellar RPC Server Integration documentation.
Logging Configuration
ApiCharge uses the standard .NET logging framework to capture information about the service's operations. Proper logging configuration is essential for monitoring, troubleshooting, and auditing your ApiCharge service.
Basic logging configuration in appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
For detailed information about logging configuration options, see the Logging Configuration documentation.
Maintenance and Operations
Backup Strategy
Regularly back up these critical components:
- Configuration Files -
/opt/apicharge/config/
- Data Files -
/opt/apicharge/data/
- Environment Variables - especially your signing keys
- Redis Data - if using Redis for persistence
Monitoring
Monitor ApiCharge using standard HTTP monitoring tools:
- Health Check Endpoint -
/apicharge/health
- Metrics Endpoint -
/metrics
(Prometheus format) - System Metrics - CPU, memory, disk usage, and network traffic
- Logs - Monitor logs for errors and warnings
Updating ApiCharge
To update ApiCharge to a new version:
# Stop the service
sudo systemctl stop apicharge
# Backup current version
cp -r /opt/apicharge/app /opt/apicharge/app.bak
# Download and extract new version
cd /opt/apicharge
wget https://github.com/apicharge/apicharge/releases/download/v1.1.0/apicharge-standalone.zip
unzip -o apicharge-standalone.zip -d app
rm apicharge-standalone.zip
# Update permissions
chown -R apicharge:apicharge /opt/apicharge/app
# Start the service
sudo systemctl start apicharge
# Verify the update
curl http://localhost:5000/apicharge/health
Troubleshooting
Common issues and solutions for standalone deployments:
Service Won't Start
- Check the systemd journal:
sudo journalctl -u apicharge
- Verify environment variables are correctly set
- Ensure the ApiCharge user has permissions to all required directories
- Check for port conflicts:
sudo netstat -tuln | grep 5000
Authentication Errors
- Verify your Stellar signing key is valid and correctly set in environment variables
- Check that the network passphrase matches your
UseNetwork
setting - Ensure clock synchronization between servers
Blockchain Connection Issues
- Check Soroban RPC server connectivity:
curl http://localhost:8000/health
- Verify network connectivity to external Stellar services if using them
- Check disk space for blockchain data
For more troubleshooting tips, see the Troubleshooting documentation.
Next Steps
After setting up your standalone deployment, consider exploring:
- Clustered Deployment - For scaling to multiple instances
- Authentication Flow - Understanding how clients authenticate
- Purchase Flow - How payments and ApiCharge Subscriptions work