Skip to main content

Quick Start Guide

Get OpenAdServe running and serve your first ad in under 5 minutes. This guide walks you through starting the complete ad server stack, loading demo data, and making your first ad request with clear validation at every step.

Prerequisites

Before you begin, make sure you have:

  • Docker and Docker Compose installed (Get Docker)
  • curl for testing API endpoints (pre-installed on most systems)
  • Web browser for viewing the demo page

Check that Docker is running:

docker --version

You should see output like Docker version 24.0.0 or higher.

Step 1: Start All Services

Clone the repository and navigate to the project directory:

git clone https://github.com/patrickwarner/openadserve.git
cd openadserve

Copy the example environment configuration:

cp .env.example .env

Start the complete ad server stack with Docker Compose:

docker compose up -d

This launches the ad server along with PostgreSQL, Redis, ClickHouse, Prometheus, Grafana, and Tempo for distributed tracing.

What you should see:

[+] Running 9/9
✔ Network openadserve_default Created
✔ Container openadserve-postgres-1 Started
✔ Container openadserve-redis-1 Started
✔ Container openadserve-clickhouse-1 Started
✔ Container openadserve-tempo-1 Started
✔ Container openadserve-prometheus-1 Started
✔ Container openadserve-grafana-1 Started
✔ Container openadserve-loki-1 Started
✔ Container openadserve-1 Started

Step 2: Verify Services Are Running

Wait 30 seconds for all services to initialize, then check the health endpoint:

curl http://localhost:8787/health

Expected output:

{"status":"healthy"}

Success indicator: You receive a JSON response with "status":"healthy"

If you see connection refused:

  • Services are still starting up
  • Wait 15 more seconds and try again
  • If it persists after 60 seconds, check logs: docker compose logs openadserve

Verify all containers are running:

docker compose ps

What you should see: All services with STATE showing Up:

NAME                        STATE
openadserve-1 Up
openadserve-clickhouse-1 Up
openadserve-grafana-1 Up
openadserve-postgres-1 Up
openadserve-prometheus-1 Up
openadserve-redis-1 Up
openadserve-tempo-1 Up

Step 3: Load Demo Data

Populate the database with demo publishers, campaigns, and creatives:

docker compose exec openadserve go run ./tools/fake_data

Expected output:

Creating demo publisher...
Created publisher ID=1 with API key: demo123

Generating campaigns and line items...
✓ Created 15 campaigns
✓ Created 45 line items
✓ Created 135 creatives

Demo data successfully loaded!
Publisher ID: 1
API Key: demo123

Success indicator: You see "Demo data successfully loaded!" with the API key demo123

Note: This creates a demo publisher with ID 1 and API key demo123. You'll use this API key in the next step.

Step 4: View the Admin UI

OpenAdServe includes a web-based admin interface for managing campaigns, line items, and creatives.

Open the admin UI in your browser:

http://localhost:8787/static/admin/index.html

What you should see:

  • Publisher dashboard showing Publisher ID 1
  • List of campaigns created by the demo data generator
  • Line items with targeting rules, budgets, and pacing settings
  • Creatives associated with each line item

Explore the admin features:

  • Publishers: View and manage publisher accounts and API keys
  • Campaigns: Create and edit campaign settings
  • Line Items: Configure targeting, budgets, pacing, and frequency caps
  • Creatives: Upload and manage ad creatives (HTML, images, native)
  • Placements: Define ad slots and sizes

Success indicator: You see the admin dashboard with the 15 campaigns created by the demo data generator

Note: The admin UI provides a convenient way to traffic campaigns without using direct database access. See the Trafficking Guide for detailed instructions on creating campaigns.

Step 5: Serve Your First Ad

Now make your first ad request using the demo API key:

curl -X POST http://localhost:8787/ad \
-H "Content-Type: application/json" \
-H "X-API-Key: demo123" \
-d '{
"id": "test-request-1",
"imp": [{
"id": "1",
"tagid": "header",
"w": 728,
"h": 90
}],
"user": {"id": "user-123"},
"device": {
"ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
"ip": "8.8.8.8"
},
"ext": {
"publisher_id": 1,
"kv": {"page_position": "top"}
}
}'

Expected output (formatted for readability):

{
"id": "test-request-1",
"seatbid": [{
"bid": [{
"id": "1",
"impid": "1",
"crid": "3",
"cid": "101",
"adm": "<div style='width:728px;height:90px;background:#4A90E2;color:white;display:flex;align-items:center;justify-content:center;font-size:24px;'>Demo Ad Creative</div>",
"price": 2.50,
"impurl": "/impression?t=eyJhbGc...",
"clkurl": "/click?t=eyJhbGc...",
"evturl": "/event?t=eyJhbGc..."
}]
}]
}

Success indicator: You receive a JSON response with a seatbid array containing ad markup

What each field means:

  • adm: The HTML ad creative to display
  • price: The eCPM value of this line item (2.50 = $2.50 CPM)
  • impurl: Impression tracking URL (call when ad is viewed)
  • clkurl: Click tracking URL (redirect users through this URL)
  • crid: Creative ID
  • cid: Campaign ID

If you see an empty seatbid array []:

  • No ads matched your request criteria
  • Try removing the kv targeting: remove the "kv": {"page_position": "top"} line
  • Or wait a few seconds for demo data to fully load

Step 6: View the Demo Page

Open your browser and visit the demo page to see ads in action:

http://localhost:8787/static/demo/index.html

What you should see:

  • Multiple ad placements displaying demo creative content
  • Ads automatically refresh using the JavaScript SDK
  • Different placements showing different ad sizes

Try the native ad demo:

http://localhost:8787/static/demo/social-feed.html

This demonstrates advanced native ad integration with in-feed ads and background skin takeover.

Success indicator: You see colorful demo ads loading in the page placements

Step 7: View Analytics in Grafana

OpenAdServe includes pre-configured Grafana dashboards for monitoring ad performance.

Open Grafana in your browser:

http://localhost:3000

Default credentials:

  • Username: admin
  • Password: admin

(You'll be prompted to change the password on first login - you can skip this for local development)

Navigate to Dashboards from the left sidebar and explore:

  • Ad Server Performance: Request rates, latency percentiles, error rates
  • Campaign Analytics: Impressions, clicks, CTR by campaign
  • System Metrics: CPU, memory, database performance

What you should see:

  • Live metrics from your ad requests
  • The test request you made in Step 5 should appear in the dashboards
  • Request counts incrementing as you refresh the demo page

Explore distributed tracing:

  1. Click Explore in the left sidebar
  2. Select Tempo as the data source
  3. Search for recent traces to see the complete request flow
  4. Click any trace to see detailed span timings and logs

Next Steps

Congratulations! You've successfully set up OpenAdServe and served your first ad.

Learn more about the platform:

Configure for production:

Advanced features:

Troubleshooting

Services won't start

Issue: docker compose up fails with port conflicts

Solution: Another service is using the required ports. Stop conflicting services or change ports in docker-compose.yml:

# Check what's using port 8787
lsof -i :8787

# Kill the process or change PORT in .env file

Health check fails

Issue: /health endpoint returns connection refused

Solution:

# Check if the container is running
docker compose ps

# View container logs for errors
docker compose logs openadserve

# Restart the services
docker compose restart

No ads returned (empty seatbid)

Issue: Ad request returns {"id":"test-request-1","seatbid":[]}

Possible causes:

  1. Demo data not loaded - Re-run: docker compose exec openadserve go run ./tools/fake_data
  2. Targeting too restrictive - Remove kv and device.ip from request
  3. Wrong API key - Verify you're using demo123
  4. Wrong publisher ID - Verify ext.publisher_id is 1

Demo page shows broken images

Issue: Demo page loads but ads don't appear

Solution:

  1. Check browser console (F12) for errors
  2. Verify API key in demo page JavaScript matches demo123
  3. Clear browser cache and reload
  4. Check that port 8787 is accessible: curl http://localhost:8787/health

Grafana shows no data

Issue: Dashboards are empty

Solution:

  1. Wait 30 seconds for Prometheus to scrape metrics
  2. Make a few ad requests to generate data
  3. Verify Prometheus is running: docker compose ps prometheus
  4. Check Prometheus targets at http://localhost:9090/targets

Container time sync issues

Issue: Logs show incorrect timestamps

Solution: Ensure your system clock is accurate, then recreate the stack:

docker compose down
docker compose up -d

Still having issues?

Check the container logs for detailed error messages:

# View all logs
docker compose logs

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

# View specific service logs
docker compose logs openadserve
docker compose logs postgres
docker compose logs clickhouse

Optional: Prebid Server Integration

To enable programmatic demand through Prebid Server:

Start the stack with the Prebid profile:

docker compose --profile prebid up -d

This launches a Prebid Server container on http://localhost:8060.

Configure a programmatic line item pointing at:

http://prebid-server:8000/openrtb2/auction

See Programmatic Demand for complete setup instructions and bidder configuration.

Optional: Machine Learning CTR Optimization

Enable ML-based click-through rate predictions for CPC campaigns:

  1. Set CTR_OPTIMIZATION_ENABLED=true in your .env file

  2. Restart services:

    docker compose restart
  3. Bootstrap the model with training data:

    docker compose exec ctr-predictor python bootstrap.py

What you should see:

Loading training data...
Training model...
Model trained successfully!
Accuracy: 0.82

See CTR Optimization Documentation for detailed configuration and usage.

Clean Up

To stop all services and remove containers:

docker compose down

To also remove volumes (deletes all data):

docker compose down -v

Understanding the System

  • Systems Architecture - Learn how the ad server components work together and understand the request flow
  • Ad Decisioning - Understand how the system selects which ad to serve

Making Ad Requests

  • API Reference - Complete endpoint documentation for integrating ad requests
  • Integration Guide - JavaScript SDK and server-to-server integration patterns

Creating Campaigns

  • Campaign Management - Create and configure campaigns, line items, and creatives
  • Targeting - Configure audience targeting for your campaigns