How to install standalone CodePush Server

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.

Objectives

  • Deploy and configure your own Code Push Server as Azure App Service
  • Configure CodePush Server management command line interface (CLI) to interact with your new server
  • Reconfigure your React Native app to use your new Code Push Server

Prerequisites

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.

Deploy CodePush Server to Azure

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:

  • Service plan
  • App Service
  • Storage account

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).

Steps

  • Install Azure CLI for your platform or upgrade to the latest version. As result, you should be able to run the command below to see the version number.

    $ 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.

  • Login to Azure account

    $ az login

    and follow the instructions in the browser.
  • Select subscription for deployment:

    $ az account set --subscription <subscription-id>

  • Create a resource group for CodePush Server resources:

    $ az group create --name <resource-group-name> --location <az-location eg. eastus>

    Help tip: you can find the list of available locations by running

    $ az account list-locations --output table

    We recommend you to select the location that is the closest to your target audience to provide the best performance and throughput to your users.
    Upon successful creation, you will see output similar to the following:
    
    {
        "id": "/subscriptions/2979d791-c9cc-4cb4-9c25-7ccf2473e983/resourceGroups/codepushselfhosted",
        "location": "eastus",
        "managedBy": null,
        "name": "codepushselfhosted",
        "properties": {
            "provisioningState": "Succeeded"
        },
        "tags": null,
        "type": "Microsoft.Resources/resourceGroups"
    }
        
  • Azure Resource Manager has a domain specific language called Bicep that uses declarative syntax to define Azure resources. We will use a Bicep script to deploy the infrastructure needed to run CodePush Server.
    To be able to do that checkout the CodePush Server repository:

    $ git clone https://github.com/microsoft/code-push-server.git

    and navigate to the api directory.
  • Deploy infrastructure with the next command:

    $ 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>

    OAuth parameters (both GitHub and Microsoft) are optional. It is possible to specify them after the deployment in environment settings of Azure WebApp.
    Upon successful deployment, you will see output similar to the following:
    
    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"
    
        
  • Deploy CodePush to the Azure WebApp created during infrastructure deployment. Follow the Azure WebApp official documentation "Deployment and configuration" section for detailed instructions.
    From api directory run the following command:

    $ az webapp up --sku <sku-name> --name <app-name>

    Be patient, it may take a few minutes to build and deploy the app. In the backgroud Azure will crete AppServicePlan, update App settings, Creating zip with contents of directory, build the app and deploy it to the Azure WebApp.
    Upon successful deployment, you will see output similar to the following:
    
    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
        
    Congratulations! You have successfully deployed CodePush Server to Azure and you may open https://<your app name>.azurewebsites.net that will show you welcome message

    Welcome to the CodePush REST API!

Revopush approach

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:

  • Pricing: Includes hosting, maintenance, and upgrades.
  • Analytics: Tracks app update performance, user adoption, and errors.
  • Interface: Offers a straightforward UI for release promotion, rollbacks, and environment/application management.
  • Additional Capabilities: Seamless CI/CD integrations, code signing, integrity verification, and differential updates to reduce download sizes.

Build and install CodePush management CLI

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.

Steps

  • Check out the CodePush Server repository:

    $ git clone https://github.com/microsoft/code-push-server.git

    and navigate to the cli directory.
  • Install required dependencies by running:

    $ npm install

  • Build the CodePush Server management CLI by running:

    $ npm run build

  • Install the CodePush Server management CLI globally by running:

    $ npm install -g code-push-standalone

  • Verify that you are able to run code-push-standalone commands in your terminal:

    $ code-push-standalone -h

    Upon successful deployment, you will see output similar to the following:
    
      _____        __    ___           __
     / ___/__  ___/ /__ / _ \__ _____ / /
    / /__/ _ \/ _  / -_) ___/ // (_-</ _ \
    \___/\___/\_,_/\__/_/   \_,_/___/_//_/    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]
        

Register your account and app on CodePush Server

  • In terminal run the following command and follow the instructions to create a new account on your CodePush Server.

    $ code-push-standalone register <your CodePush server hostname>

    and navigate to the cli directory.
  • Upon successful registration, you will need to put received access key to cli:
    
    A browser is being launched to authenticate your account. Follow the instructions it displays to complete your login.
    
    Enter your access key:  yQKR17duPW0h9zzfQI_sSI896t4LVJMn2aoEZl
                                               
    This key will be persisted in the .code-push.config file in user's home folder. To terminate current session run code-push-standalone logout command.
  • Create a new app on your CodePush Server by running:

    $ code-push-standalone app add <appName>

    We suggest you to create separate application for each platform (iOS, Android) with CodePush server. This way, you can manage and release updates to them separately. Example
    
    code-push-standalone app add MyApp-Android
    code-push-standalone app add MyApp-iOS
                                               
    Upon successful creation, you will see output similar to the following:
    
    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 │
    └────────────┴────────────────────────────────────────┘
    
                                               
    At this point, you have successfully registered your account and created an app on your CodePush Server.

Configure app to use your new CodePush Server

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.

iOS

  • Open Info.plist file in your Xcode project and add the following lines, replacing server-url with your CodePush server location and deployment-key with the deployment key of the deployment you want to target.
    
    <key>CodePushDeploymentKey</key>
    <string>deployment-key</string>
    <key>CodePushServerURL</key>
    <string>server-url</string>
                                               
  • Rebuild your app and submit it to the App Store.

Android

  • Open strings.xml file in your Android project and add the following line, replacing server-url with your CodePush server location and deployment-key with the deployment key of the deployment you want to target.
    
    <string moduleConfig="true" name="CodePushDeploymentKey">deployment-key</string>
    <string moduleConfig="true" name="CodePushServerUrl">server-url</string>
                                               
  • Rebuild your app and submit it to the Play Store.

Releasing updates to your app

Once your app has been configured to query for updates against the CodePush server, you can begin releasing updates to it.

  • Navigate to the root of your React Native project and run the following command to release an update to your iOS app:

    $ code-push-standalone release-react MyApp-iOS ios --outputDir ./CodePush --targetBinaryVersion 0.0.1

    This command will create a new release for the MyApp-iOS app, targeting the ios platform, and output the generated bundle to the ./CodePush directory. Upon successful release, you will see output similar to the following:
    
    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.
    
                                               
    Under the hood, the code-push-standalone release-react command will bundle your app's JavaScript code and assets, upload them to the CodePush server, and create a new release for the specified deployment.
    The full list of options for fine-grained tuning of the release process can be found by running:

    $ code-push-standalone release-react --help

  • Check deployment history for given application and deployment running:

    $ code-push-standalone deployment history MyApp-iOS Staging

    Upon successful execution, you will see output similar to the following:
    
    ┌───────┬────────────────┬─────────────┬───────────┬─────────────────┬──────────────────────┐
    │ 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 │
    └───────┴────────────────┴─────────────┴───────────┴─────────────────┴──────────────────────┘
                                               

Summary

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.

Join Revopush!

Avoid last-minute headaches!