Skip to content

BYOC Deployment - DigitalOcean

Overview

This guide shows you how to deploy your Uniswap V2 adapter on DigitalOcean using their App Platform and Managed Databases. You'll use the same Docker image from the previous steps.


Prerequisites

Before starting, ensure you have:

  • Docker image: Built and pushed to a public registry (GitHub Container Registry or Docker Hub)
  • DigitalOcean account: Sign up at digitalocean.com
  • API keys: Alchemy, CoinGecko, and Absinthe API keys ready

Step 1: Create Managed PostgreSQL Database

1a: Navigate to Databases

  1. Log into your DigitalOcean dashboard
  2. Click "Create" in the top navigation
  3. Select "Databases"

1b: Configure Database

  1. Database Engine: PostgreSQL
  2. Version: 15 (latest stable)
  3. Data Center Region: Choose closest to your users
  4. VPC Network: Default VPC
  5. Configuration:
    • Basic: $15/month (1 GB RAM, 1 vCPU, 10 GB storage)
    • Professional: $60/month (2 GB RAM, 1 vCPU, 25 GB storage)
  6. Database Name: absinthe-adapter
  7. Project: Default or create new project

1c: Security Settings

  1. Trusted Sources: Add your IP address for initial setup
  2. Connection Pooling: Enabled (recommended)
  3. Click "Create Database"

1d: Get Connection Details

After creation (takes 3-5 minutes):

  1. Go to your database dashboard
  2. Click "Connection Details"
  3. Copy the Connection String (starts with postgresql://)
  4. Save this for later use

Step 2: Deploy App Platform Service

2a: Create New App

  1. Click "Create""Apps"
  2. Choose "Docker Hub" or "Container Registry"
  3. Enter your Docker image:
    ghcr.io/yourusername/your-adapter:latest
    or
    ghcr.io/absinthelabs/absinthe-abs-app:latest

2b: Configure App Settings

  1. App Name: uniswap-v2-adapter
  2. Region: Same as your database
  3. Plan:
    • Basic: $5/month (512 MB RAM, 1 vCPU)
    • Professional: $12/month (1 GB RAM, 1 vCPU)
  4. HTTP Port: Remove this (not needed for background services)

2c: Environment Variables

In the Environment Variables section, add:

RPC_URL_MAINNET=<your-ethereum-rpc-url>
RPC_URL_BASE=<your-base-rpc-url>
RPC_URL_HEMI=https://rpc.hemi.network/rpc
RPC_URL_POLYGON=<your-polygon-rpc-url>
 
ABS_CONFIG='{"balanceFlushIntervalHours":48,"dexProtocols":[{"type":"uniswap-v2","chainId":43111,"toBlock":0,"protocols":[{"name":"weth-usdc.e","contractAddress":"0xaf6ed58980b5a0732423469dd9f3f69d9dc6dab5","fromBlock":865348,"pricingStrategy":"coingecko","token0":{"coingeckoId":"weth","decimals":18},"token1":{"coingeckoId":"usd-coin","decimals":6},"preferredTokenCoingeckoId":"token1"},{"name":"hemibtc-usdc.e","contractAddress":"0x0621bae969de9c153835680f158f481424c0720a","fromBlock":1451314,"pricingStrategy":"coingecko","token0":{"coingeckoId":"bitcoin","decimals":8},"token1":{"coingeckoId":"usd-coin","decimals":6},"preferredTokenCoingeckoId":"token1"},{"name":"weth-hemibtc","contractAddress":"0x225283e4d46ab82561a285998517a9175f3e0f06","fromBlock":1435768,"pricingStrategy":"coingecko","token0":{"coingeckoId":"weth","decimals":18},"token1":{"coingeckoId":"hemibtc","decimals":8},"preferredTokenCoingeckoId":"token1"},{"name":"vusd-usdc.e","contractAddress":"0xf23eec60263de9b0c8472c58be10feba28d9eb53","fromBlock":1326101,"pricingStrategy":"coingecko","token0":{"coingeckoId":"vusd","decimals":18},"token1":{"coingeckoId":"usd-coin","decimals":6},"preferredTokenCoingeckoId":"token1"}]},{"type":"izumi","chainId":42161,"toBlock":0,"protocols":[{"name":"hemibtc-usdc.e","contractAddress":"0x0621bae969de9c153835680f158f481424c0720a","fromBlock":1451314,"pricingStrategy":"coingecko","token0":{"coingeckoId":"bitcoin","decimals":18},"token1":{"coingeckoId":"usd-coin","decimals":6},"preferredTokenCoingeckoId":"token1"},{"name":"vusd-weth","contractAddress":"0xa43fe16908251ee70ef74718545e4fe6c5ccec9f","fromBlock":1274620,"pricingStrategy":"coingecko","token0":{"coingeckoId":"vesper-vdollar","decimals":18},"token1":{"coingeckoId":"weth","decimals":18},"preferredTokenCoingeckoId":"token1"}]}],"txnTrackingProtocols":[{"type":"printr","name":"printr-base","contractAddress":"0xbdc9a5b600e9a10609b0613b860b660342a6d4c0","factoryAddress":"0x33128a8fc17869897dce68ed026d694621f6fdfd","chainId":8453,"toBlock":0,"fromBlock":30000000},{"type":"vusd-mint","name":"vusd-mint","contractAddress":"0xFd22Bcf90d63748288913336Cd38BBC0e681e298","chainId":1,"toBlock":0,"fromBlock":22017054},{"type":"demos","name":"demos","contractAddress":"0x70468f06cf32b776130e2da4c0d7dd08983282ec","chainId":43111,"toBlock":0,"fromBlock":1993447},{"type":"voucher","name":"voucher","contractAddress":"0xa26b04b41162b0d7c2e1e2f9a33b752e28304a49","chainId":1,"toBlock":0,"fromBlock":21557766}],"stakingProtocols":[{"type":"hemi","name":"hemi-staking","contractAddress":"0x4f5e928763cbfaf5ffd8907ebbb0dabd5f78ba83","chainId":43111,"toBlock":0,"fromBlock":1226394},{"type":"vusd-bridge","name":"vusd-bridge","contractAddress":"0x5eaa10F99e7e6D177eF9F74E519E319aa49f191e","chainId":1,"toBlock":0,"fromBlock":22695105}],"univ3Protocols":[{"type":"uniswap-v3","chainId":43111,"factoryAddress":"0xCdBCd51a5E8728E0AF4895ce5771b7d17fF71959","factoryDeployedAt":507517,"positionsAddress":"0xe43ca1Dee3F0fc1e2df73A0745674545F11A59F5","toBlock":0,"pools":[{"name":"weth-hemibtc","contractAddress":"0xd8a6e60661aa3e53bcd77cc0d20f462c2d9376b9","fromBlock":1370183},{"name":"weth-hemibtc","contractAddress":"0x3f1228f4bd8de23dec4e1fcf81f16ed7fde5d1a8","fromBlock":1335038},{"name":"weth-hemibtc","contractAddress":"0xe31377f1f1e200a24e8c2d5b059829635b8c34ea","fromBlock":1328544},{"name":"weth-hemibtc-3000","contractAddress":"0x51109fa53e904c17daeb320d56166900e23707d3","fromBlock":1271574},{"name":"weth-usdc.e-10000","contractAddress":"0xb46335caccccb3fdc2a3f40d9fd253f5f76919a0","fromBlock":1171886},{"name":"weth-usdc.e-500","contractAddress":"0x62a567bab98e96968e29b3815ea9b8c7bee56d6e","fromBlock":1164129},{"name":"weth-usdc.e-100","contractAddress":"0xc863ddd8ac2157f3a6fe85c9c383b98812cf1986","fromBlock":1283712},{"name":"weth-usdc.e-3000","contractAddress":"0x9580d4519c9f27642e21085e763e761a74ef3735","fromBlock":865336},{"name":"hemibtc-usdc.e","contractAddress":"0x57dac018e4c5f12dc917e4b4f77706f12fd1652b","fromBlock":1458961},{"name":"vusd-usdc.e","contractAddress":"0xda44564df732decfd93ba8539803c5a8df241954","fromBlock":1335361},{"name":"vusd-usdc.e-500","contractAddress":"0x3ecabba99bef583b58b8f0af6dd853cd9ed75ce3","fromBlock":1271042},{"name":"vusd-usdc.e-3000","contractAddress":"0x3e014a9ef5f45454d9bddb15741ce8a04e7d96f5","fromBlock":1342356},{"name":"vusd-usdc.e-10000","contractAddress":"0x8025ba536e4ed403acb87ec939d8b8b45527b3ce","fromBlock":1413533},{"name":"hemibtc-usdt-100","contractAddress":"0xd0c7fa41cd5079cf9c89f6cf85147b6499c05990","fromBlock":1420959},{"name":"hemibtc-usdt-500","contractAddress":"0x2450def5f751c569339d458384b80c2e96185404","fromBlock":1630644},{"name":"hemibtc-usdt-3000","contractAddress":"0x0c07240c009469cbf4e393484f692064dfef15ed","fromBlock":1518680},{"name":"usdc.e-usdt-3000","contractAddress":"0xc36a310bd93e2927452de563faaa89a86822a21f","fromBlock":1384088},{"name":"usdc.e-usdt-500","contractAddress":"0x6ab24c166b4e0a2f6edab3a65a7c2d9cd6dc7a06","fromBlock":1325792},{"name":"usdc.e-usdt-100","contractAddress":"0x94504f06f31bf4224eba82c58b280400b85e6df3","fromBlock":1341456},{"name":"msusd-vusd-500","contractAddress":"0x9a0943b78004530557dc3f4aabcc4a67ebc0fbfb","fromBlock":1336788},{"name":"weth-mseth-500","contractAddress":"0x805ac209d1f84fbc11dcdd3956040b1a1a2d4b44","fromBlock":1332745},{"name":"hemibtc-usdc.e-10000","contractAddress":"0x92787e904d925662272f3776b8a7f0b8f92f9bb5","fromBlock":1375049},{"name":"hemibtc-usdc.e-3000","contractAddress":"0xf5819f1b4db39f78c2ca1758a89c70cbbafe3bd8","fromBlock":1435746},{"name":"hemibtc-usdc.e-500","contractAddress":"0x343d7f2ec94d56f74a78a4a20e6de892785cc2bc","fromBlock":1421793}]}],"zebuProtocols":[{"type":"zebu","name":"zebu-new","toBlock":0,"clients":[{"name":"xyz-1","contractAddress":"0xD71954165a026924cA771C53164FB0a781c54C83","chainId":137,"fromBlock":61059459},{"name":"xyz-2","contractAddress":"0x3e4768dB375094b753929B7A540121d970fcb24e","chainId":137,"fromBlock":61059459},{"name":"xyz-3","contractAddress":"0x5859Ff44A3BDCD00c7047E68B94e93d34aF0fd71","chainId":8453,"fromBlock":15286409},{"name":"xyz-4","contractAddress":"0xE3EB2347bAE4E2C6905D7B832847E7848Ff6938c","chainId":137,"fromBlock":61695150},{"name":"xyz-5","contractAddress":"0x19633c8006236f6c016a34B9ca48e98AD10418B4","chainId":137,"fromBlock":64199277},{"name":"xyz-6","contractAddress":"0x0c18F35EcfF53b7c587bD754fc070b683cB9063B","chainId":8453,"fromBlock":20328800},{"name":"xyz-7","contractAddress":"0xDD4d9ae148b7c821b8157828806c78BD0FeCE8C4","chainId":137,"fromBlock":73490308}]},{"type":"zebu","name":"zebu-legacy","toBlock":0,"clients":[{"name":"xyz-1","contractAddress":"0xd7829F0EFC16086a91Cf211CFbb0E4Ef29D16BEE","chainId":8453,"fromBlock":27296063}]}]}'
ABSINTHE_API_URL=https://adapters.absinthe.network
ABSINTHE_API_KEY=<your-api-key>
COINGECKO_API_KEY=<your-coingecko-api-key>
 
REDIS_URL="redis://localhost:6379"
DB_URL=postgresql://postgres:postgres@localhost:5432/postgres

Replace the DB_URL value with the Connection String you copied from your DigitalOcean managed database in Step 1d.

2d: Resource Configuration

  1. CPU: 1 vCPU
  2. Memory: 1 GB (minimum recommended)
  3. Instance Count: 1
  4. Auto-scaling: Disabled (not needed for adapters)

Step 3: Configure Database Access

3a: Add App Platform to Trusted Sources

  1. Go back to your database dashboard
  2. Click "Settings" tab
  3. Scroll to "Trusted Sources"
  4. Click "Add Trusted Source"
  5. Select "Apps"
  6. Choose your deployed app
  7. Click "Save"

This allows your app to connect to the database securely.

3b: Verify Connection

  1. Go to your app dashboard
  2. Click "Runtime Logs"
  3. Look for successful database connection messages:

Step 4: Monitor Deployment

4a: Application Logs

Monitor your app in real-time:

  1. Go to Apps → Your app name
  2. Click "Runtime Logs"
  3. Watch for:
    • Successful startup messages
    • Database connection confirmation
    • Block processing logs
    • Any error messages

4b: Database Monitoring

Check database performance:

  1. Go to Databases → Your database name
  2. Click "Insights" tab
  3. Monitor:
    • Connection count: Should stay stable
    • CPU usage: Typically low for indexers
    • Memory usage: Monitor for growth patterns

4c: Resource Usage

Monitor app resources:

  1. In your app dashboard, click "Insights"
  2. Watch:
    • CPU: Should be steady during block processing
    • Memory: May grow gradually with cache usage
    • Restart count: Should remain at 0

Cost Optimization Tips

  1. Start with Basic: Upgrade only if you need more performance
  2. Monitor usage: Use DigitalOcean's built-in monitoring
  3. Database sizing: Most adapters work fine with Basic database tier
  4. Regional placement: Keep app and database in same region

Scaling Considerations

When to Upgrade

Database:
  • Connection limit reached (Basic: 25 connections)
  • Storage approaching limit (Basic: 10 GB)
  • High CPU usage consistently
App Platform:
  • Memory usage consistently above 80%
  • CPU usage consistently above 70%
  • Processing lag during high-volume periods

Horizontal Scaling

For multiple chains:

  1. Deploy separate apps for each chain
  2. Use shared database or separate databases per chain
  3. Configure different ABS_CONFIG for each deployment

Security Best Practices

Environment Variables

  • Never commit API keys to version control
  • Use DigitalOcean's encrypted environment variables
  • Rotate API keys regularly

Database Security

  • Enable SSL/TLS connections (default)
  • Use strong passwords
  • Regularly update trusted sources
  • Monitor connection logs

Network Security

  • Keep database and app in same VPC
  • Use private networking when possible
  • Regularly review trusted sources

Your Uniswap V2 adapter is now running on DigitalOcean! 🌊