Complete DOTA Setup Guide
This interactive guide will walk you through the entire process of setting up DOTA and sending your first OTA update. Follow these steps in order for a smooth experience.
β±οΈ 30-45 minutes to complete the full setup
π― What You'll Accomplishβ
By the end of this guide, you will:
- β Have DOTA Server running locally or in the cloud
- β Have the Web Panel configured and accessible
- β Have DOTA SDK integrated into your React Native app
- β Have CLI installed and authenticated
- β Successfully deploy your first OTA update
Step 1: Set Up DOTA Serverβ
The server is the heart of the DOTA ecosystem. Let's get it running first.
Prerequisitesβ
- Docker and Docker Compose installed
- Node.js 18 or higher
- Git
Quick Start with Dockerβ
1.1 Clone the Server Repository
git clone https://github.com/ds-horizon/delivr-server-ota.git
cd delivr-server-ota
1.2 Install Dependencies
npm install
1.3 Configure Environment
cp .env.example .env
# Edit .env with your preferred settings
1.4 Start the Server with Docker
docker-compose up
The server will start at http://localhost:3010
1.5 Verify Server is Running
curl http://localhost:3010/health
Expected response: {"status": "ok", "timestamp": "..."}
β Your DOTA Server is now running! Keep it running for the rest of the setup.
π Detailed Server Setup Guide β
Step 2: Set Up Web Panelβ
The Web Panel provides a visual interface for managing your apps and deployments.
Prerequisitesβ
- Node.js 18.18.0 (exact version)
- pnpm 10.17.0+
- DOTA Server running (from Step 1)
Setup Stepsβ
2.1 Clone the Web Panel Repository
git clone https://github.com/ds-horizon/delivr-web-panel.git
cd delivr-web-panel
2.2 Enable Corepack and Install pnpm
npm install -g corepack
corepack enable
npm install -g pnpm
2.3 Install Dependencies
pnpm install
2.4 Configure Environment
Create .env file:
# Google OAuth Configuration
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
# Backend API Configuration
DELIVR_BACKEND_URL=http://localhost:3010
You'll need to create OAuth credentials in Google Cloud Console:
- Create a new project
- Enable OAuth 2.0
- Add authorized redirect URI:
http://localhost:5173/auth/callback - Copy Client ID and Secret to
.env
2.5 Start the Web Panel
pnpm dev
The dashboard will be available at http://localhost:5173
2.6 Sign In and Create Your Organization
- Open
http://localhost:5173in your browser - Click "Sign in with Google"
- Create your organization (e.g., "My Company")
- You're now ready to create apps!
β Your DOTA Dashboard is now running and configured!
π Detailed Web Panel Setup Guide β
Step 3: Create Your App and Generate Deployment Keysβ
Now let's create your first app in the dashboard and get deployment keys.
3.1 Create Your App
- In the Web Panel, click "Create App" or "New Application"
- Enter your app details:
- App Name:
MyApp-iOS(orMyApp-Android) - Platform: iOS or Android
- Description: Optional
- App Name:
3.2 Generate Deployment Keys
After creating the app, you'll see two deployment keys generated:
- π‘ Staging - For testing and QA
- π’ Production - For live users
3.3 Copy the Deployment Keys
Copy both keys - you'll need them in the next step.
Keep these keys secure! They will be embedded in your mobile app and identify where updates should be delivered.
Step 4: Integrate DOTA SDK into Your React Native Appβ
Now let's add DOTA to your React Native application.
4.1 Install the SDKβ
Navigate to your React Native project:
cd /path/to/your/react-native-app
Install DOTA SDK:
- npm
- Yarn
npm install @d11/dota
yarn add @d11/dota
4.2 Platform-Specific Configurationβ
- Android
- iOS
Android Setupβ
In order to integrate DOTA into your Android project, perform the following steps:
- Edit
android/settings.gradleand add the DOTA module:
// ...
include ':app', ':d11_dota'
project(':d11_dota').projectDir = new File(rootProject.projectDir, '../node_modules/@d11/dota/android/app')
- In
android/app/build.gradle, add the dependency:
dependencies {
// ...
implementation project(':d11_dota')
// ...
}
- In
android/app/build.gradle, apply the DOTA build tasks at the end of the file:
// ...
apply from: "../../node_modules/@d11/dota/android/codepush.gradle"
// ...
- Update
MainApplicationto use DOTA:
- RN 0.73+ (Kotlin)
- RN 0.72 and below (Java)
// 1. Import the plugin class.
import com.microsoft.codepush.react.CodePush
class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
// ...
// 2. Add DOTA package for manual linking
add(
CodePush.getInstance(
resources.getString(R.string.CodePushDeploymentKey),
applicationContext,
BuildConfig.DEBUG
)
)
// 3. Let DOTA determine the JS bundle location on each start
override fun getJSBundleFile(): String {
return CodePush.getJSBundleFile()
}
}
}
// 1. Import the plugin class.
import com.microsoft.codepush.react.CodePush;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
// ...
// 2. Add DOTA package for manual linking
packages.add(CodePush.getInstance(
getResources().getString(R.string.CodePushDeploymentKey),
getApplicationContext(),
BuildConfig.DEBUG
));
// 3. Let DOTA determine the JS bundle location on each start
@Override
protected String getJSBundleFile() {
return CodePush.getJSBundleFile();
}
};
}
- Add the deployment key (copied at step 3) and server URL to
strings.xml:
<resources>
<!-- ... -->
<string moduleConfig="true" name="CodePushDeploymentKey">DeploymentKey</string>
<string moduleConfig="true" name="CodePushServerUrl">https://dota-sdk.delivr.live/</string>
</resources>
- Disable autolinking for
@d11/dotaby creatingreact-native.config.jsat the app root:
module.exports = {
dependencies: {
'@d11/dota': {
platforms: {
android: null,
},
},
},
};
iOS Setupβ
Once you've added the DOTA plugin, integrate it into your Xcode project.
- ObjectiveβC
- Swift
- Install CocoaPods dependencies:
cd ios && pod install && cd ..
- In
AppDelegate.m, import DOTA headers:
#import <CodePush/CodePush.h>
- Find the production JS source URL and replace it with DOTA:
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
β Replace with:
return [CodePush bundleURL];
- Use DOTA only for release builds:
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [CodePush bundleURL];
#endif
}
- Add deployment key (copied at step 3) and server URL to
Info.plist:
<key>CodePushServerURL</key>
<string>server-url</string>
<key>CodePushDeploymentKey</key>
<string>deployment-key</string>
- Install CocoaPods dependencies:
cd ios && pod install && cd ..
- In
AppDelegate.swift, import CodePush:
import CodePush
- Replace the production JS source URL with DOTA:
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
β Replace with:
return CodePush.bundleURL()
- Use DOTA only for release builds:
override func bundleURL() -> URL! {
#if DEBUG
return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
// Default behavior assumes "main.jsbundle"
return CodePush.bundleURL()
// If you embedded a differently named file:
// return CodePush.bundleURL(forResource: "mybundle")
// return CodePush.bundleURL(forResource: "mybundle", withExtension: "jsbundle")
#endif
}
- Add deployment key and server URL to
Info.plist:
<key>CodePushServerURL</key>
<string>https://dota-sdk.delivr.live/</string>
<key>CodePushDeploymentKey</key>
<string>deployment-key</string>
4.3 Integrate DOTA in Your App Codeβ
Open your root component (usually App.tsx or App.js):
import codePush from "@d11/dota";
import { Platform } from "react-native";
function App() {
// Your app code
return (
<View>
<Text>My App</Text>
</View>
);
}
// Wrap your app with codePush
export default codePush(App);
4.4 Build Your Appβ
DOTA updates don't work in Debug mode. Build in Release mode to test.
- Android
- iOS
yarn android --mode=Release
yarn ios --mode=Release
4.5 Release to App Storeβ
Build your app for production and release it to the App Store/Play Store with the DOTA SDK and deployment keys embedded.
β Your app is now ready to receive OTA updates!
π Detailed SDK Setup Guide β
Step 5: Generate Your JavaScript Bundleβ
Before you can send an update, you need to create a JavaScript bundle.
5.1 Generate Bundleβ
DOTA provides a way to copy the exact bundle created during build process to certain path for later use. Follow the platform specific setup and just create a Release build.
- Android
- iOS
Add to android/app/build.gradle:
apply from: "../../node_modules/@d11/dota/android/codepush.gradle"
In your Podfile:
# Import at the top
require_relative '../node_modules/@d11/dota/ios/scripts/dota_pod_helpers.rb'
# Include in the post_install block
post_install do |installer|
dota_post_install(installer, 'YourAppTarget', File.expand_path(__dir__))
end
Then run:
cd ios && pod install
This creates bundles in the .dota/ directory:
.dota/
βββ android/
β βββ index.android.bundle
β βββ assets/
βββ ios/
βββ main.jsbundle
βββ assets/
β Our Bundle and Assets is now ready to be released over-the-air.
π Detailed Bundle Generation Guide β
Step 6: Install and Configure DOTA CLIβ
The CLI allows you to deploy updates from your terminal or CI/CD pipeline.
6.1 Install CLIβ
- yarn
- npm
yarn add --dev @d11/delivr-cli
npm install --save-dev @d11/delivr-cli
6.2 Generate Access Tokenβ
- Go to your Web Panel at
http://localhost:5173 - Navigate to Profile Icon -> Token List
- Click on Create Token
- Enter a name:
CLI Access - Select access level: All
- Click "Create"
- Copy the token immediately (you won't see it again!)
π Detailed Guide on Managing Tokens
6.3 Authenticate CLIβ
yarn code-push-standalone login --accessKey YOUR_ACCESS_TOKEN <server-url>
Verify authentication:
yarn code-push-standalone whoami
β CLI is installed and authenticated!
π Detailed CLI Setup Guide β
Step 7: Deploy Your First OTA Update! πβ
Now comes the exciting part - deploying your first update!
Option A: Deploy via Web Panelβ
7.1 Make a Code Change
Edit your React Native code (change some text, colors, etc.)
7.2 Generate Bundle
Re-build the app in release mode. This will copy the bundle in .dota/<platform> directory.
- Android
- iOS
yarn android --mode=Release
yarn ios --mode=Release
7.3 Upload via Dashboard
- Open Web Panel at
http://localhost:5173 - Navigate to your app
- Click "Create Release" or "New Deployment"
- Upload Bundle: Drag and drop your bundle from
.dota/ios/or.dota/android/ - Configure:
- Target Binary Version:
1.0.0(match your app version) - Deployment: Staging
- Description: "My first OTA update!"
- Target Binary Version:
- Click "Deploy" or "Publish"
π Detailed Deployment Guide via Panel β
Option B: Deploy via CLI (Faster)β
7.1 Make a Code Change
Edit your React Native code
7.2 Generate Bundle and Deploy
Re-build the app in release mode.
- Android
- iOS
yarn android --mode=Release
yarn code-push-standalone release MyApp-Android ./.dota/android "1.0.0" \
--deploymentName Staging \
--description "My first OTA update!"
yarn ios --mode=Release
yarn code-push-standalone release MyApp-iOS ./.dota/ios "1.0.0" \
--deploymentName Staging \
--description "My first OTA update!"
Use "1.0.0" for exact version or "^1.0.0" for all 1.x.x versions
Step 8: Test Your OTA Updateβ
8.1 Restart Your App
Close and reopen your app (or restart it from your IDE). Make sure you rebuild your app with your changes reverted back to see new bundle impact.
8.2 Watch for the Update
- The app will check for updates on startup
- Download the update in the background
- Apply it on the next restart
8.3 Verify the Update
After the second restart, you should see your code changes!
Use codePush.sync to observe bundle status events (see API Reference β sync):
codePush.sync(
{},
(status) => {
switch (status) {
case codePush.SyncStatus.DOWNLOAD_REQUEST_SUCCESS:
// Downloaded successfully
break;
case codePush.SyncStatus.UPDATE_INSTALLED:
// Update installed; activation depends on installMode
break;
}
}
);
For the full list of statuses, see SyncStatus.
8.4 Monitor in Dashboard
Go to the Web Panel and check:
- Deployment status
- Download progress
- Installation metrics
β Congratulations! You've successfully deployed your first OTA update!
Checkout the Patch Bundle Guide to ship more lightweight OTA updates.
Step 9: Deploy to Production (When Ready)β
After testing in Staging, promote to Production:
Via CLI:β
yarn code-push-standalone promote MyApp-iOS Staging Production
Via Web Panel:β
- Go to your app's Staging deployment
- Find the tested release
- Click "Promote to Production"
Troubleshootingβ
App Not Receiving Updatesβ
Check:
- β App is in Release mode (not Debug)
- β Deployment key is correct
- β
Server is running at
http://localhost:3010 - β App version matches target version
- β Update is enabled (not disabled)
Server Connection Issuesβ
Verify:
# Check server is running
curl http://localhost:3010/health
# If Network Request failing try reversing port
adb reverse tcp:3010 tcp:3010
# Check from your mobile device/emulator can reach it
# For iOS simulator/Android emulator, use localhost
# For physical devices, use your computer's IP address
Bundle Generation Failsβ
Solutions:
- Ensure you're in your React Native project directory
- Check that
index.tsorindex.jsexists - Verify Node.js version is compatible
- Try clearing Metro cache:
npx react-native start --reset-cache
CLI Authentication Failsβ
Check:
- Access token is correct and not expired
- Server is running and accessible
- Token has the right permissions
What's Next?β
Now that you've sent your first OTA update, explore more capabilities:
π― Advanced Featuresβ
- Gradual Rollouts - Deploy to a percentage of users
- Mandatory Updates - Force critical updates
- Patch Bundles - Smaller differential updates
π Deep Diveβ
- SDK API Reference - Full API documentation
- Ship Your First Patch Bundle - End-to-end patch release
- Server Configuration - Advanced server setup
- CLI Advanced Usage - Master the command line
- Debugging Guide - Troubleshoot issues
Success Checklistβ
Before moving to production, ensure:
- Server is deployed and accessible from the internet
- Web Panel is configured with proper OAuth
- App is released to App Store/Play Store with SDK integrated
- Deployment keys are embedded in the app
- CLI is installed and working
- You've successfully tested OTA updates in staging
- You understand rollback procedures
- Monitoring and analytics are set up
Congratulations! π You're now ready to ship faster with DOTA! Deploy updates instantly, roll out features gradually, and rollback with confidence.