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 displayprice: 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 IDcid: Campaign ID
If you see an empty seatbid array []:
- No ads matched your request criteria
- Try removing the
kvtargeting: 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:
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:
- Click Explore in the left sidebar
- Select Tempo as the data source
- Search for recent traces to see the complete request flow
- 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:
- API Reference - Complete endpoint documentation
- Architecture Overview - How the system works
- Campaign Management - Create and configure campaigns
- Targeting - Configure audience targeting
- Dimension Registration - Custom targeting attributes
Configure for production:
- Security Configuration - API keys, token secrets
- Performance Tuning - Optimization strategies
- Monitoring - Production observability
Advanced features:
- Programmatic Demand - Integrate OpenRTB bidders
- CTR Optimization - ML-based click prediction
- Forecasting Engine - Inventory prediction
- AdCP Integration - AI-powered campaign automation
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:
- Demo data not loaded - Re-run:
docker compose exec openadserve go run ./tools/fake_data - Targeting too restrictive - Remove
kvanddevice.ipfrom request - Wrong API key - Verify you're using
demo123 - Wrong publisher ID - Verify
ext.publisher_idis1
Demo page shows broken images
Issue: Demo page loads but ads don't appear
Solution:
- Check browser console (F12) for errors
- Verify API key in demo page JavaScript matches
demo123 - Clear browser cache and reload
- Check that port 8787 is accessible:
curl http://localhost:8787/health
Grafana shows no data
Issue: Dashboards are empty
Solution:
- Wait 30 seconds for Prometheus to scrape metrics
- Make a few ad requests to generate data
- Verify Prometheus is running:
docker compose ps prometheus - 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:
-
Set
CTR_OPTIMIZATION_ENABLED=truein your.envfile -
Restart services:
docker compose restart -
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
Related Topics
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