-
Notifications
You must be signed in to change notification settings - Fork 0
Deployment
| Requirement | Minimum | Recommended |
|---|---|---|
| OS | Ubuntu 22.04 LTS | Ubuntu 22.04 LTS |
| Python | 3.10 | 3.11 or 3.12 |
| RAM | 2 GB | 4 GB+ |
| Disk | 20 GB | 40 GB+ |
| CPU | 2 cores | 4 cores+ |
Required software:
- Python 3.10+ with
venv - nginx
- certbot (Let's Encrypt)
- git
Docker is the recommended deployment method for CI environments, local development, and any host where you prefer not to install external tools (Foundry, Slither, Mythril, Aderyn, Medusa) directly. The multi-stage Dockerfile bundles the complete 21-analyzer stack on Python 3.12 (image size ~1.5 GB).
cd sentinel-engine
docker build -t counterscarp-engine:5.1.0 .The project's docker-compose.yml defines four services:
| Service | Purpose |
|---|---|
counterscarp |
Main audit service (all 21 analyzers) |
doctor |
Diagnostics / health check |
heuristic |
Heuristic-only scan (no external tools required) |
symbolic |
Mythril symbolic execution only |
# Full audit
docker compose run --rm counterscarp scan /scan/MyContract.sol
# Health check
docker compose run --rm doctor
# Heuristic-only scan
docker compose run --rm heuristic scan /scan/MyContract.sol
# Symbolic execution only
docker compose run --rm symbolic scan /scan/MyContract.solTwo mount points are defined for contract input and report output:
| Mount | Purpose |
|---|---|
/scan |
Mount your contract source directory here |
/output |
Audit reports are written here |
docker compose run --rm \
-v /path/to/contracts:/scan \
-v /path/to/reports:/output \
counterscarp scan /scan/MyContract.solPre-configured in docker-compose.yml under deploy.resources:
| Resource | Limit |
|---|---|
| CPU | 4.0 cores |
| Memory | 4 GB |
Adjust these values in the deploy.resources section of docker-compose.yml to match your host's capacity.
All services include an automatic health check that runs counterscarp --doctor:
| Setting | Value |
|---|---|
| Interval | 60s |
| Timeout | 30s |
| Retries | 3 |
Use docker compose ps to view current health status for each service.
| Variable | Description |
|---|---|
COUNTERSCARP_PRO_LICENSE |
Set your Pro license key to enable premium features |
docker compose run --rm \
-e COUNTERSCARP_PRO_LICENSE=your-key \
counterscarp scan /scan/MyContract.solFor persistent configuration, add COUNTERSCARP_PRO_LICENSE to a .env file in the project root — Docker Compose picks it up automatically.
# Run the main service in the background
docker compose up -d counterscarp
# Follow live logs
docker compose logs -f counterscarp
# Stop all services
docker compose down- The
foundry-cachenamed volume persists the Foundry compilation cache across runs, significantly reducing re-compilation time. - Bind-mount a dedicated output directory so reports survive container restarts.
- Rotate or prune the
foundry-cachevolume periodically if disk space is constrained:docker volume rm sentinel-engine_foundry-cache.
The deploy/setup.sh script automates the full deployment. Run as root:
sudo bash deploy/setup.sh| Step | Action |
|---|---|
| 1/8 | Creates service user counterscarp (no login shell) |
| 2/8 | Clones/updates repository to /opt/counterscarp-engine
|
| 3/8 | Creates Python venv and installs counterscarp-engine[web]
|
| 4/8 | Creates uploads/ and results/ directories |
| 5/8 | Sets ownership to counterscarp:counterscarp
|
| 6/8 | Installs nginx config and reloads nginx |
| 7/8 | Obtains SSL certificate via certbot (if not already present) |
| 8/8 | Installs systemd service and starts it |
If you prefer to deploy manually:
# 1. Create service user
useradd -r -s /bin/false counterscarp
# 2. Setup directory (choose one method)
# Method A: Install from PyPI (recommended for production)
mkdir -p /opt/counterscarp-engine
cd /opt/counterscarp-engine
python3 -m venv venv
./venv/bin/pip install --upgrade pip
./venv/bin/pip install "counterscarp-engine[web]"
# Method B: Clone from GitHub (for development/customization)
# mkdir -p /opt/counterscarp-engine
# cd /opt/counterscarp-engine
# git clone https://github.com/RunTimeAdmin/counterscarp.git .
# python3 -m venv venv
# ./venv/bin/pip install --upgrade pip
# ./venv/bin/pip install -e ".[web]"
# 3. Create directories
mkdir -p /opt/counterscarp-engine/uploads
mkdir -p /opt/counterscarp-engine/results
# 4. Set ownership
chown -R counterscarp:counterscarp /opt/counterscarp-engine
# 5. Configure nginx
cp deploy/nginx-counterscarp.conf /etc/nginx/sites-available/counterscarp
ln -sf /etc/nginx/sites-available/counterscarp /etc/nginx/sites-enabled/counterscarp
nginx -t && systemctl reload nginx
# 6. SSL certificate
certbot certonly --nginx -d app.counterscarp.io --non-interactive --agree-tos -m your@email.com
# 7. Start service
cp deploy/counterscarp-engine.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable counterscarp-engine
systemctl start counterscarp-engineThe nginx configuration is located at deploy/nginx-counterscarp.conf:
server {
listen 80;
listen [::]:80;
server_name app.counterscarp.io;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name app.counterscarp.io;
ssl_certificate /etc/letsencrypt/live/app.counterscarp.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.counterscarp.io/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
client_max_body_size 10M;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 120s;
proxy_connect_timeout 10s;
}
location /static/ {
alias /opt/counterscarp-engine/webapp/static/;
expires 7d;
add_header Cache-Control "public, immutable";
}
}- Port 8001 — The app runs on port 8001 (not 8000) to avoid conflicts
-
client_max_body_size 10M— Matches the web app's 10 MB upload limit - Security headers — X-Frame-Options, X-Content-Type-Options, XSS-Protection, Referrer-Policy
-
Static file caching —
/static/served directly by nginx with 7-day cache - Proxy timeouts — 120s read timeout to handle long-running analyses
Warning: If you change the domain, update both the server_name and the SSL certificate paths.
sudo certbot certonly --nginx -d app.counterscarp.io --non-interactive --agree-tos -m your@email.comCertbot installs a systemd timer for automatic renewal. Verify it's active:
systemctl list-timers | grep certbotManual renewal test:
sudo certbot renew --dry-run| File | Path |
|---|---|
| Full chain | /etc/letsencrypt/live/app.counterscarp.io/fullchain.pem |
| Private key | /etc/letsencrypt/live/app.counterscarp.io/privkey.pem |
| SSL options | /etc/letsencrypt/options-ssl-nginx.conf |
| DH params | /etc/letsencrypt/ssl-dhparams.pem |
The service unit file is at deploy/counterscarp-engine.service:
[Unit]
Description=Counterscarp Engine Web Application
After=network.target
[Service]
Type=exec
User=counterscarp
Group=counterscarp
WorkingDirectory=/opt/counterscarp-engine
ExecStart=/opt/counterscarp-engine/venv/bin/uvicorn webapp.main:app --host 127.0.0.1 --port 8001 --workers 4
Restart=always
RestartSec=5
Environment=PYTHONUNBUFFERED=1
Environment=COUNTERSCARP_UPLOAD_DIR=/opt/counterscarp-engine/uploads
Environment=COUNTERSCARP_RESULTS_DIR=/opt/counterscarp-engine/results
[Install]
WantedBy=multi-user.target# Start the service
sudo systemctl start counterscarp-engine
# Stop the service
sudo systemctl stop counterscarp-engine
# Restart the service
sudo systemctl restart counterscarp-engine
# Check status
sudo systemctl status counterscarp-engine
# Enable auto-start on boot
sudo systemctl enable counterscarp-engine
# View live logs
sudo journalctl -u counterscarp-engine -f
# View recent logs
sudo journalctl -u counterscarp-engine -n 50Note: After modifying the unit file, always run systemctl daemon-reload before restarting.
Important: Stripe API keys and webhook secrets must be set via systemd override, never in code or version-controlled files.
sudo systemctl edit counterscarp-engineAdd the following:
[Service]
Environment="STRIPE_SECRET_KEY=sk_live_..."
Environment="STRIPE_WEBHOOK_SECRET=whsec_..."
Environment="STRIPE_PUBLISHABLE_KEY=pk_live_..."sudo systemctl daemon-reload
sudo systemctl restart counterscarp-enginesudo systemctl show counterscarp-engine --property=EnvironmentSecurity Notes:
- Never commit Stripe keys to Git (GitHub Push Protection will block)
- Use
sk_live_for production,sk_test_for testing - Webhook secrets are different for test and live modes
- Rotate keys immediately if accidentally exposed
Use the deploy/update.sh script:
sudo bash deploy/update.shThis script:
- Pulls latest code from
main - Reinstalls Python dependencies
- Fixes ownership
- Restarts the service
- Verifies health
cd /opt/counterscarp-engine
# Method A: Update from PyPI (if installed via pip)
./venv/bin/pip install --upgrade "counterscarp-engine[web]"
# Method B: Update from Git (if cloned)
# git pull origin main
# ./venv/bin/pip install -e ".[web]" --quiet
chown -R counterscarp:counterscarp /opt/counterscarp-engine
sudo systemctl restart counterscarp-enginecurl -s http://127.0.0.1:8001/health | python3 -m json.toolcurl http://127.0.0.1:8001/healthExpected response:
{"status": "ok", "timestamp": "2024-01-15T10:30:00.000000"}| Symptom | Likely Cause | Fix |
|---|---|---|
| 502 Bad Gateway | App not running | systemctl restart counterscarp-engine |
| 413 Request Entity Too Large | File exceeds 10 MB | Increase client_max_body_size in nginx config |
| SSL errors | Certificate expired | certbot renew && systemctl reload nginx |
| Slow responses | Analysis taking long | Increase proxy_read_timeout in nginx |
| Upload fails | Permissions wrong | chown -R counterscarp:counterscarp /opt/counterscarp-engine/uploads |
df -h /opt/counterscarp-engineUploads and results accumulate over time. Consider setting up a cron job to clean old audit data:
# Remove results older than 30 days
find /opt/counterscarp-engine/results -type d -mtime +30 -exec rm -rf {} +
find /opt/counterscarp-engine/uploads -type d -mtime +30 -exec rm -rf {} +ps aux | grep uvicorn
ss -tlnp | grep 8001# Follow live logs
sudo journalctl -u counterscarp-engine -f
# Last 100 lines
sudo journalctl -u counterscarp-engine -n 100
# Logs since yesterday
sudo journalctl -u counterscarp-engine --since yesterday
# Logs with specific severity
sudo journalctl -u counterscarp-engine -p err# Access log
sudo tail -f /var/log/nginx/access.log
# Error log
sudo tail -f /var/log/nginx/error.logJournal logs are auto-rotated by systemd. Configure retention:
# Keep only last 7 days of journal logs
sudo journalctl --vacuum-time=7dNginx logs are rotated by logrotate (installed by default on Ubuntu).
Counterscarp Engine • counterscarp.io
Scarpshield Wiki (Counterscarp Engine)
- Home
- Current Status
- Getting Started
- CLI Reference
- Configuration
- Web App Guide
- Deployment
- Report Formats
- Rules Catalog
- Architecture
- Plugin Development
- Contributing
- Security & Licensing
- Pricing & Pro Features
- FAQ & Troubleshooting
GitHub Repo | Web App | PyPI