This method allows you to setup Code Push Server in a Windows Web App
TOC
- Introduction
- Setup
- Debugging
- References
1. Introduction
CodePush Server is a self-hosted backend for Microsoft CodePush, allowing you to manage and deploy over-the-air updates for React Native and Cordova apps. It provides update versioning, deployment history, and authentication controls.
It is typically designed to run on Linux-based Node environments. If you want to deploy it on Azure Windows Web App, you can follow this tutorial to apply the necessary modifications.
2. Setup
1. Create a Windows Node.js Web App. In this example, we use Node.js 20 LTS.
2. After the Web App is created, go to the Overview tab and copy its FQDN. You'll need this in later steps.
3. Create a standard Storage Account.
4. Once created, go to Access keys and copy the Storage Account’s name and key for later use.
5. Return to the Web App's Environment Variables and add the following configuration values.
Variable Name |
Variable Value |
AZURE_STORAGE_ACCOUNT |
<Storage Account name you've copied from step 4> |
AZURE_STORAGE_ACCESS_KEY |
<Storage Account key you've copied from step 4> |
SERVER_URL |
<https:// + Web app FQDN you've copied from step 2> e.g., https://az-7135-app.azurewebsites.net |
CORS_ORIGIN |
<https:// + Web app FQDN you've copied from step 2> e.g., https://az-7135-app.azurewebsites.net |
LOGGING |
false |
6. On your local machine, open a terminal and clone the CodePush Server source code. Then create your own project folder—for example, az-7135-app.
# Change to you working dir and your project name (e.g, az-7135-app)
git clone https://github.com/microsoft/code-push-server.git
mkdir az-7135-app
cp -R code-push-server/api/* az-7135-app
cp az-7135-app/.env.example az-7135-app/.env
7. Open the project folder in VSCode, create server.js and web.config, and modify the relevant files as described.
File name |
Change |
Reason |
.env |
Please setup AZURE_STORAGE_ACCOUNT, AZURE_STORAGE_ACCESS_KEY, and SERVER_URL follow step 4 |
From Official Tutorial Bicep Template |
web.config |
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <handlers> <add name="iisnode" path="server.js" verb="*" modules="iisnode" /> </handlers> <rewrite> <rules> <rule name="NodeJsApp" stopProcessing="true"> <match url=".*" /> <action type="Rewrite" url="server.js" /> </rule> </rules> </rewrite> <iisnode loggingEnabled="false" debuggingEnabled="true" devErrorsEnabled="true" /> </system.webServer> </configuration> |
When using a Windows App, the HTTP server is IIS. As a reverse proxy, IIS needs to forward incoming requests to another web server running on the same machine—in this case, node.exe. Due to several path limitations in web.config (such as not supporting nested directories for the entry point), the server.js file must reside in the same directory as web.config. Since the original project uses bin/script/server.js as the entry point, which cannot be directly referenced here, you need to create a new server.js file in the root directory as a wrapper to forward execution. The iisnode section in web.config is useful for debugging purposes. However, it requires the debugging settings described below to work correctly. Once debugging is complete, this section can be safely removed. |
server.js |
// Wrapper to launch actual entry point require("./bin/script/server.js"); |
Same as above |
script/server.ts |
//const port: number = Number(process.env.API_PORT) || Number(process.env.PORT) || defaultPort; const port: number = process.env.API_PORT || process.env.PORT || defaultPort; |
All traffic in Windows Web Apps is routed through IIS to node.exe, so the actual listening port is not a traditional number but a system-generated internal pipe (e.g., \\.\pipe\dff22378-aeb3-4ede-8d1e-7c1e1bdc0c46). Therefore, adjustments are needed to align with this architecture. |
package.json |
Before: "main": "./script/server.js", After: "main": "server.js",
Before: "start": "node ./bin/script/server.js", After: "start": "node server.js",
Before: "start:env": "node -r dotenv/config server.js dotenv_config_path=.env dotenv_config_silent=true", After: "start:env": "node -r dotenv/config server.js dotenv_config_path=.env dotenv_config_silent=true",
Before: "build": "tsc && shx cp -r ./script/views ./bin/script", After: "build": "npm install typescript --save-dev && tsc && shx cp -r ./script/views ./bin/script", |
Like web.config, we change most entry points to use a root-level server.js instead of a path with nested folders. Additionally, note that the Oryx build process differs between Windows and Linux Web Apps. On Windows, the build step only runs npm install and npm run start, but not npm run build. Also, the underlying OS doesn’t come with TypeScript pre-installed. This causes npm run build to fail unless adjusted. To resolve this, modify the build script to include TypeScript installation. After deployment, you must also manually run npm run build once using the Kudu interface. |
8. Use VSCode to publish the project. Then, in the Azure Portal's Web App Deployment Center, wait for the deployment to complete. This may take around 10 minutes, and this step alone doesn't mean the app is ready to run.
9. Open the Kudu interface. Here, you need to perform the task mentioned in step 7: manually run npm run build once. This will generate the bin folder containing the compiled runtime code. This process takes about 5 minutes.
10. With the build complete, the deployment process is finished. You can now visit the Web App's homepage. The first load may take up to 30 seconds due to cold start; subsequent requests will be faster.
3. Debugging
If you need to debug, enable App Service Logs and ensure that your web.config in step 7 has the appropriate debug settings.
Once enabled, go to the Kudu interface, navigate to the LogFiles/Application folder, and review the stdout and stderr logs generated by node.exe.