With Microsoft sunsetting App Center and CodePush, many in the React Native community are seeking alternatives for over-the-air (OTA) updates.
In order to let developers keep using CodePush functionality after App Center is fully retired, Microsoft created a standalone version of CodePush Server that can be deployed and used independently from App Center itself.
This guide will show you how to deploy and configure your own CodePush Server in a self-hosted environment and CodePush Command Line Interface.
This guide assumes you have a React Native app that is currently using CodePush from App Center and that you are comfortable using the command line interface (CLI) to release OTA updates, should have basic understanding of Azure App Service, Azure Blob Storage and Azure Resource Manager.
To deploy CodePush to Azure, an active Azure account and subscription are needed. During the deployment process script will create Azure services needed to run CodePush Server including:
For user authentication and to register your React Native application on self-managed server, a GitHub or Microsoft OAuth application is needed (we will use GitHub OAuth application in this example. Please follow official documentation to create one).
$
az --version
azure-cli 2.67.0
core 2.67.0
telemetry 1.1.0
Dependencies:
msal 1.31.0
azure-mgmt-resource 23.1.1
Python location '/opt/homebrew/Cellar/azure-cli/2.67.0_1/libexec/bin/python'
Extensions directory '/Users/username/.azure/cliextensions'
Python (Darwin) 3.12.8 (main, Dec 3 2024, 18:42:41) [Clang 16.0.0
(clang-1600.0.26.4)]
Legal docs and information: aka.ms/AzureCliLegal
Your CLI is up-to-date.
$
az login
$
az account set --subscription <subscription-id>
$
az group create --name <resource-group-name> --location <az-location eg. eastus>
$
az account list-locations --output table
{
"id": "/subscriptions/2979d791-c9cc-4cb4-9c25-7ccf2473e983/resourceGroups/codepushselfhosted",
"location": "eastus",
"managedBy": null,
"name": "codepushselfhosted",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}
$
git clone https://github.com/microsoft/code-push-server.git
$
az deployment group create --resource-group <resource-group-name> --template-file ./codepush-infrastructure.bicep --parameters project_suffix=<project-suffix> az_location=<az-location eg. eastus> github_client_id=<github-client-id> github_client_secret=<github-client-secret> microsoft_client_id=<microsoft-client-id> microsoft_client_secret=<microsoft-client-secret>
Resource and property changes are indicated with these symbols:
+ Create
* Ignore
The deployment will update the following scope:
Scope: /subscriptions/2979d791-c9cc-4cb4-9c25-7ccf2473e983/resourceGroups/ccp_group_name
+ Microsoft.Storage/storageAccounts/codepushstoragetst [2022-09-01]
apiVersion: "2022-09-01"
id: "/subscriptions/2979d791-c9cc-4cb4-9c25-7ccf2473e983/resourceGroups/ccp_group_name/providers/Microsoft.Storage/storageAccounts/codepushstoragetst"
kind: "StorageV2"
location: "westeurope"
name: "codepushstoragetst"
properties.allowBlobPublicAccess: true
properties.minimumTlsVersion: "TLS1_2"
properties.publicNetworkAccess: "Enabled"
sku.name: "Standard_LRS"
type: "Microsoft.Storage/storageAccounts"
+ Microsoft.Web/serverfarms/codepush-asp-tst [2022-03-01]
apiVersion: "2022-03-01"
id: "/subscriptions/2979d791-c9cc-4cb4-9c25-7ccf2473e983/resourceGroups/ccp_group_name/providers/Microsoft.Web/serverfarms/codepush-asp-tst"
location: "westeurope"
name: "codepush-asp-tst"
properties.reserved: true
sku.name: "S1"
type: "Microsoft.Web/serverfarms"
+ Microsoft.Web/sites/codepush-tst [2022-03-01]
apiVersion: "2022-03-01"
id: "/subscriptions/2979d791-c9cc-4cb4-9c25-7ccf2473e983/resourceGroups/ccp_group_name/providers/Microsoft.Web/sites/codepush-tst"
location: "westeurope"
name: "codepush-tst"
properties.httpsOnly: true
properties.serverFarmId: "/subscriptions/2979d791-c9cc-4cb4-9c25-7ccf2473e983/resourceGroups/ccp_group_name/providers/Microsoft.Web/serverfarms/codepush-asp-tst"
properties.siteConfig: "*******"
type: "Microsoft.Web/sites"
+ Microsoft.Web/sites/codepush-tst/basicPublishingCredentialsPolicies/scm [2022-03-01]
apiVersion: "2022-03-01"
id: "/subscriptions/2979d791-c9cc-4cb4-9c25-7ccf2473e983/resourceGroups/ccp_group_name/providers/Microsoft.Web/sites/codepush-tst/basicPublishingCredentialsPolicies/scm"
name: "scm"
properties.allow: true
type: "Microsoft.Web/sites/basicPublishingCredentialsPolicies"
$
az webapp up --sku <sku-name> --name <app-name>
Creating AppServicePlan 'codepush-asp-ccp' or Updating if already exists
Readonly attribute name will be ignored in class
Creating zip with contents of dir /Users/username/code-push-server/api ...
Getting scm site credentials for zip deployment
Starting zip deployment. This operation can take a while to complete ...
Deployment endpoint responded with status code 202
Polling the status of async deployment. Start Time: 2024-12-18 10:29:03.070207+00:00 UTC
Status: Building the app... Time: 0(s)
Status: Building the app... Time: 17(s)
Status: Building the app... Time: 33(s)
Status: Building the app... Time: 49(s)
Status: Building the app... Time: 66(s)
Status: Building the app... Time: 82(s)
Status: Building the app... Time: 98(s)
Status: Building the app... Time: 115(s)
Status: Building the app... Time: 132(s)
Status: Building the app... Time: 148(s)
Status: Building the app... Time: 164(s)
Status: Building the app... Time: 180(s)
Status: Building the app... Time: 197(s)
Status: Building the app... Time: 214(s)
Status: Building the app... Time: 230(s)
Status: Building the app... Time: 246(s)
Status: Building the app... Time: 262(s)
Status: Building the app... Time: 279(s)
Status: Building the app... Time: 296(s)
Status: Building the app... Time: 312(s)
Status: Building the app... Time: 328(s)
Status: Building the app... Time: 344(s)
Status: Building the app... Time: 363(s)
Status: Build successful. Time: 380(s)
Status: Site started successfully. Time: 395(s)
You can launch the app at http://<app name from previous step>.azurewebsites.net
Welcome to the CodePush REST API!
Revopush provides consulting services to install and configure a standalone CodePush Server in your cloud environment. This includes infrastructure provisioning, server setup, and integration with existing systems.
Self-hosting a CodePush Server requires expertise in infrastructure, security, and maintenance. Revopush also offers a SaaS solution for over-the-air (OTA) CodePush updates with the following features:
To run command of CodePush management CLI you need to have Node.js and npm installed on your
machine. At the moment
of writing this guide, we used Node.js v18.20.4 and npm
v10.9.1 to build and install CodePush management CLI.
For more information on installing Node.js and npm, please visit the official
website.
$
git clone https://github.com/microsoft/code-push-server.git
$
npm install
$
npm run build
$
npm install -g code-push-standalone
$
code-push-standalone -h
_____ __ ___ __
/ ___/__ ___/ /__ / _ \__ _____ / /
/ /__/ _ \/ _ / -_) ___/ // (_-</ _ \
\___/\___/\_,_/\__/_/ \_,_/___/_//_/ CLI v0.0.1
======================================
CodePush is a service that enables you to deploy mobile app updates directly to your users' devices.
Usage: code-push-standalone <command>
Commands:
code-push-standalone access-key View and manage the access keys associated with your account
code-push-standalone app View and manage your CodePush apps
code-push-standalone collaborator View and manage app collaborators
code-push-standalone debug View the CodePush debug logs for a running app
code-push-standalone deployment View and manage your app deployments
code-push-standalone link Link an additional authentication provider (e.g. GitHub) to an existing CodePush account
code-push-standalone login Authenticate with the CodePush server in order to begin managing your apps
code-push-standalone logout Log out of the current session
code-push-standalone patch Update the metadata for an existing release
code-push-standalone promote Promote the latest release from one app deployment to another
code-push-standalone register Register a new CodePush account
code-push-standalone release Release an update to an app deployment
code-push-standalone release-react Release a React Native update to an app deployment
code-push-standalone rollback Rollback the latest release for an app deployment
code-push-standalone session View and manage the current login sessions associated with your account
code-push-standalone whoami Display the account info for the current login session
Options:
--help Show help [boolean]
-v, --version Show version number [boolean]
$
code-push-standalone register <your CodePush server hostname>
A browser is being launched to authenticate your account. Follow the instructions it displays to complete your login.
Enter your access key: yQKR17duPW0h9zzfQI_sSI896t4LVJMn2aoEZl
$
code-push-standalone app add <appName>
code-push-standalone app add MyApp-Android
code-push-standalone app add MyApp-iOS
Successfully added the "MyApp-Android" app, along with the following default deployments:
┌────────────┬────────────────────────────────────────┐
│ Name │ Deployment Key │
├────────────┼────────────────────────────────────────┤
│ Production │ iTPp_VDEFilxBSRQElJz5Jnv7IhgVJMn2aoEZl │
├────────────┼────────────────────────────────────────┤
│ Staging │ ol3aTQxSTRaLjI3MZszdw_B20i_8VJMn2aoEZl │
└────────────┴────────────────────────────────────────┘
Successfully added the "MyApp-iOS" app, along with the following default deployments:
┌────────────┬────────────────────────────────────────┐
│ Name │ Deployment Key │
├────────────┼────────────────────────────────────────┤
│ Production │ OECdNPjYzjs_1el1QlvClu3nRVfdVJMn2aoEZl │
├────────────┼────────────────────────────────────────┤
│ Staging │ nUtMITaUV-ne_GJWcnngnO6htnpzVJMn2aoEZl │
└────────────┴────────────────────────────────────────┘
You need to update your React Native app to query for updates against your new CodePush Server. Due to React Native nature this change will require you to release new version of the app for AppStore and PlayStore.
<key>CodePushDeploymentKey</key>
<string>deployment-key</string>
<key>CodePushServerURL</key>
<string>server-url</string>
<string moduleConfig="true" name="CodePushDeploymentKey">deployment-key</string>
<string moduleConfig="true" name="CodePushServerUrl">server-url</string>
Once your app has been configured to query for updates against the CodePush server, you can begin releasing updates to it.
$
code-push-standalone release-react MyApp-iOS ios --outputDir ./CodePush --targetBinaryVersion 0.0.1
Running "react-native bundle" command:
node node_modules/react-native/cli.js bundle --assets-dest ./CodePush --bundle-output CodePush/main.jsbundle --dev false --entry-file index.js --platform ios
Welcome to Metro v0.81.0
Fast - Scalable - Integrated
info Writing bundle output to: CodePush/main.jsbundle
info Done writing bundle output
info Copying 1 asset files
info Done copying assets
private key was not provided
Releasing update contents to CodePush:
Upload progress:[==================================================] 100% 0.0s
Successfully released an update containing the "./CodePush" directory to the "Staging" deployment of the "MyApp-iOS" app.
$
code-push-standalone release-react --help
$
code-push-standalone deployment history MyApp-iOS Staging
┌───────┬────────────────┬─────────────┬───────────┬─────────────────┬──────────────────────┐
│ Label │ Release Time │ App Version │ Mandatory │ Description │ Install Metrics │
├───────┼────────────────┼─────────────┼───────────┼─────────────────┼──────────────────────┤
│ v1 │ 27 minutes ago │ 0.0.1 │ No │ │ No installs recorded │
├───────┼────────────────┼─────────────┼───────────┼─────────────────┼──────────────────────┤
│ v2 │ 4 minutes ago │ 0.0.1 │ No │ fix misspelling │ No installs recorded │
└───────┴────────────────┴─────────────┴───────────┴─────────────────┴──────────────────────┘
When deciding between a Standalone CodePush Server and a Software as a Service (SaaS) solution, it's important to consider various factors such as overall cost, scalability, and maintenance. Based on what we have observed at Revopush, for production-grade applications, you will need at least:
Alternatively, you can try Revopush for free and enjoy all the benefits without the hassle.