Failed to deploy React app (build) folder to App Service Azure - reactjs

I'm following this link below on how to deploy React app to App Service Azure.
How to deploy React app to App service Azure
However, I couldn't see my application page but the Azure App service default page. "Hey, Node developers!"
Here, I have attached screenshots about the deployment condition and logs. [App service 1
Please advise.

Update:
Another method:
The premise of this method is you have Node.js env and have installed npm tools.
1.add a file name index.js under the site/wwwroot.
index.js:
var express = require('express');
var server = express();
var options = {
index: 'index.html' //Fill path here.
};
server.use('/', express.static('/home/site/wwwroot', options));
server.listen(process.env.PORT);
2.install express:
run this command under the wwwroot directory,
npm install -save express
3.restart your app service and wait for minutes.
Original Answer:
First of all, you can follow this link to know how to deploy your react app to azure.
https://medium.com/microsoftazure/deploying-create-react-app-as-a-static-site-on-azure-dd1330b215a5
All of the files will be upload to D:/site/wwwroot, the physical folder.
Default page setting of the web app based on Linux os is very similar.
For example, I have a file named index.php under public_html folder and I want to set it as the default page of my web app.
You need to create a file named .htaccess under the wwwroot.
This is the content of the .htaccess file:
DirectoryIndex public_html/index.php
Then, Success set the default page:

Related

React App doesn't make proxy calls after deployed to azure

Simple setup:
React App created with create-react-app
ASP.NET Core web API - a couple of controllers (currently no security until I make it work)
Both the API and Application are deployed to Azure.
When I run the app locally with configured proxy (I contact the deployed API on Azure) it works correctly makes the calls.
If I try the API directly from my machine it works too (PostMan for example)
When I open the deployed React APP - The application loads correctly but the call to the API doesn't get proxy(ed). What I mean it's not returning 404, 403 - it returns status 200, but makes the call to the app itself instead of proxy the request to the API.
I've tried both using "proxy" configuration in package.json as well as using "http-proxy-middleware". Both cases work with locally running app, but not deployed. Here is the configuration of the proxy:
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'https://XXXXXX.azurewebsites.net',
changeOrigin: true,
})
);
};
I suppose it's something related to the configuration of the node server used when I deploy to azure, but I don't have a clue what.
I've used the following tutorial for deployment: https://websitebeaver.com/deploy-create-react-app-to-azure-app-services
But as seen from content there is no proxy part in it.
After long troubleshooting I realize the issue was due to wrong understanding of the proxy configuration.
So I was not realizing the proxy configuration is respected only in debug mode and totally ignored into prod build. And of course while debugging the issue I was not realizing the Azure Deployment pipe was doing production build. So the resolution was to detect the production/dev on application layer and inject correct URL.
Here I hit another issue - process.env.NODE_ENV, which I was using to distinguish between development and production was undefined into my index.tsx - it was available in App.tsx and all its children, but not in index.tsx where my dependency container was initialized.
What resolved my issue is package called dotenv. Then I've just imported it into index.tsx and the process.env was available.
import * as dotenv from 'dotenv';

How to deploy Next.js app without Node.js server?

I was hoping to deploy a Next.js app with Laravel API. I had developed React apps with CRA and in those I used the API server to serve the index.html of the CRA as the entry point of the app.
But in Next.js, after development I get to know that it needs a Node.js server to serve (which is my bad, didn't notice that). There is an option next export that builds a static representation of the Next.js app and it has an index.html. I am serving the index.html as the entry of the app by my Laravel API. It is serving the page, but just some of the static contents.
What I was hoping to know is it possible to host the aPI and the Next app from a single PHP shared hosting without any node server? If so, how? If not so, what could be the alternatives?
Actually the acepted answer is completly wrong, when you do yarn build and in your package.json is set like "build": "next build && next export", you will get an out folder which all the items in there are used to build without node.js server
Now since you are using laravel, and you use the out folder you will only load half of the page because the routes are not set properly. for that to work you need to edit your next.config.js edit it to
module.exports = {
distDir: '/resources/views',
assetPrefix: '/resources/views',
}
These will set the root directory to the root one in Laravel. now this will work for SPA (single page application) only for the dynamic routes you need to match with a view file for each one that you have in your out folder
For each route that you have you need to create a new "get" route in laravel
Route::get('/', function () {
return require resource_path('views/index.html');
});
Route::get('/contacts', function () {
return require resource_path('views/contacts.html');
});
Route::get('/post/{slug}', function () {
return require resource_path('views/post/[slug].html');
});
Notice that you can pass a wildcard for dynamic routes and they are all gonna work. once you do that and you deploy route out folder inside /resources/views in Laravel it's going to work
Apparently there is no alternative to nodejs server, which is not an option for me currently, so I unfortunately had to abandon next.js and create a CRA app and used as much from the next.js as I could.

React SPA dynamic environment configuration

I'm building React SPA application from ground up using create-react-app and setting up uri address for API server of my SPA. According to official documentation suggested way is to create environment .env files for such kind of needs. I'm using a continuous delivery as part of development workflow. After deployment React SPA application goes in one Docker container and API goes to another. Those containers are deployed in separate servers and I do not know exactly what uri for API will be, so there is no way to create separate .env file for each deployment. Is there any "right way" to provide dynamic configuration for my SPA application so I can easily change environment parameters
API URI examples in SPA
// api.config.js
export const uriToApi1 = process.env.REACT_APP_API1_URI;
export const uriToApi2 = process.env.REACT_APP_API2_URI;
// in App.js
import { uriToApi1, uriToApi2 } from '../components/config/api.config.js';
/* More code */
<DataForm apiDataUri={`${uriToApi1}/BasicService/GetData`} />
/* More code */
<DataForm apiDataUri={`${uriToApi2}/ComplexService/UpdateData`} />
Let's imagine that you build your frontend code in some dist folder that will be packed by Docker in the image. You need to create config folder in your project that also will be added in dist folder (and obvious, will be packed in Docker image). In this folder, you will store some config files with some server-specific data. And you need to load these files when your react application starts.
The flow will be like that:
User opens your app.
Your App shows some loader and fetches config file (e.g. ./config/api-config.json)
Then your app reads this config and continues its work.
You need to setup Docker Volumes in your Docker config file and connect config folder in Docker container with some config folder on your server. Then you will be able to substitute config files in a docker container by files on your server. This will help you to override config on each server.

Cannot GET index.html Azure Linux Web App

We created a Linux Web App in Microsoft Azure. The application is static written with React (html and Javascript).
We copied the code into the wwwroot folder, but the application only showing only hostingstart.html and when we try to get page index.html we have this error:
Cannot GET /index.html
We tried with a sample of Azure in GitHub (https://github.com/Azure-Samples/html-docs-hello-world) but the error is the same.
The url is this: https://consoleadmin.azurewebsites.net/index.html
Last week the application was running correctly.
We forget to do something?
MAY 2020 - You don't have to add any javascript files or config files anywhere. Let me explain.
I was facing this exact same issue and wasted 6 hours trying everything including the most popular answer to this question. While the accepted answer is a nice workaround (but requires more work than just adding the index.js file), there's something a simpler than that.
You see, when you just deploy an Azure Web App (or App Service as it is also called), two things happen:
The web app by default points to opt/startup/hostingstart.html
It also puts a hostingstart.html in home/site/wwwroot
When you deploy your code, it replaces hostingstart.html in home/site/wwwroot but the app is still pointing to opt/startup/hostingstart.html. If you want to verify this, try deleting opt/startup/hostingstart.html file and your web app will throw a "CANNOT GET/" error.
So how to change the default pointer? It's simpler than it looks:
Go to Configuration tab on your web app and add the following code to startup script:
pm2 serve /home/site/wwwroot --no-daemon
If this web app is a client-side single-page-app and you're having issues with routing, then add --spa to the above command as follows:
pm2 serve /home/site/wwwroot --no-daemon --spa
This will tell the web app to serve wwwroot folder. And that's it.
Image for reference:
Screenshot explaination
PS: If you only set the startup script without deploying your code, it will still show the hostingstart.html because by default that file lies in the wwwroot folder.
Ok you are gonna love this. This happened to me today also. Same exact thing.
I am pretty sure the azure team flipped a switch somewhere and we fell through a crack.
I found this obscure answer with no votes and it did the trick (with a little extra finagling)
BONUS! this also fixed my router issues I was having only on the deployed site (not local):
Credit: #stormwild: Default documents not serving on node web app hosted on Azure
From #stormwild's post see here:
https://blogs.msdn.microsoft.com/waws/2017/09/08/things-you-should-know-web-apps-and-linux/#NodeHome
Steps:
Go to your azure portal, select your app service and launch ssh
In ssh terminal, navigate via command line to /home/site/wwwroot
create index.js there with the following code:
var express = require('express');
var server = express();
var options = {
index: 'index.html'
};
server.use('/', express.static('/home/site/wwwroot', options));
server.listen(process.env.PORT);
NOTE: Be sure to run npm install --save express also in this folder else your app service will crash on startup
Be sure to restart your app service if it doesn't do so automagically
A workaround, I changed the webapp stack to PHP 7
Another solution would be to add a file called ecoysystem.config.js right next to your index.html file.
module.exports = {
apps: [
{
script: "npx serve -s"
}
]
};
This will tell pm2 to associate all requests to index.html as your app service starts up.
Very helpful information here: https://burkeholland.github.io/posts/static-site-azure/

After deploying React/Express app to Heroku unable to start passport.js flow (page reloads instead) [duplicate]

I'm building a node + express server, with create-react-app to the frontend.
I used passportjs for auth routes handling, and all the stuff totally working on localhost ( backend on port 5000 and frontend on port 3000, with a proxy ).
When I deploy to Heroku, seems like the server can't recognize my auth routes and so heroku serve up static index.html.
If I test my APIs with Postman all seems to work ( I can see the html page for google oauth ), but with an anchor tag in my react app or manually writing the endpoint in the url, I can see only the same page reloading.
My server index.js:
const express = require('express')
const passport = require('passport')
const mongoose = require('mongoose')
const path = require('path')
// KEYS
const keys = require('./config/keys')
// MONGOOSE MODELS
require('./models/User')
mongoose.connect(keys.mongoURI)
// PASSPORT SETUP
require('./config/passport')
// CREATE THE SERVER
const app = express()
// EXTERNAL MIDDLEWARES
require('./middlewares/external')(app)
// ROUTE HANDLERS
require('./routes/authRoutes')(app)
// PRODUCTION SETUP
if (process.env.NODE_ENV === 'production') {
// express serve up production assets ( main.js, main.css )
app.use(express.static('client/build'))
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'))
})
}
// START THE SERVER
const PORT = process.env.PORT || 5000
app.listen(PORT)
Flow:
LOCALHOST:
react app starts -> I click 'Google Login' -> GET request to "/auth/google" -> google oauth flow -> redirect to "/" and my react app reappears, the user is logged in.
HEROKU:
react app on my-app.herokuapp.com/ -> click on "Google Login" -> the page reloads, nothing happens. the user is not logged in.
Please guys, help me.
Thanks
This is a result of the service worker being installed by default to make your app a Progressive Web App
To determine if this is an issue for you, test your heroku production mode app in incognito mode. The request for /auth/google should now reach the server and behave as it does in development.
Once you determine it is an issue, you can remove the
import registerServiceWorker from "./registerServiceWorker";
from your /client/src/index.js file.
You browser cache may already contain an installed service worker so you may have to
clear browser cache on a user browsers
uninstall the server worker programmatically
import { unregister } from './registerServiceWorker';
....
unregister();
I had the same issues with same symptoms exactly.
For me the cause was a typo in the keys: in server/config/prod.js I had a line reading cookieKey: process.env.COOKIE_KEY but in Heroku Config Variables that variable was named cookieKey. Renaming it to COOKIE_KEY inside Heroku solved the issue.
If you've followed the Stephen Grider tutorial one thing I'm wondering: Is your passport.js file in config or services? I see you've written in index.js: require('./config/passport')
whereas mine in index.js is require('./services/passport')
may not be your solution to the google oauth flow hanging in production but may help.

Resources