I've wrote a simple NodeJs (ExpressJs) server that uses Puppeteer to generate PDF files on JSON data being passed to it. While locally everything is working like charm, I'm struggling to run this server on Azure App Services.
I've created a Resource group, within it I've created an App Servces instance (running on Linux) that is connected to my repo at Azure DevOps (via the Deployment Center).
My server has two endpoints:
/ - returns a JSON - { status: "ok" }. I'm using this to validate the running server instance.
/generate-pdf - uses the Puppeteer to generate and return a PDF file.
After successfully starting the App Service instance I'm able to access the "/" route and get a valid response but upon accessing the "/generate-pdf" route the result is "502 - Bad Gateway".
Does my instance require some additional configuration that I haven't done?
Does App Services can not run Puppeteer? Perhaps there is a different service on Azure that I need to use?
Is there a way to automate the process via the Azure DevOps pipeline or release?
Any questions/thoughts/FAQs are more than welcomed. Thanks =)
I'm answering my own question: as was mentioned here https://stackoverflow.com... the Azure App Services does not allow the use of GDI (which is required by Chrome) regardless if you're using Linux or Windows based system. The solution was to put the NodeJs application into a Docker container and manually install Chrome. Once you have a container - just upload it to the Azure App Services and viola!
By default App Servies exposes 80 and 443 ports, so if your application listens on a different port be sure to specify it via the WEBSITES_PORT environment variable.
In my case, I had to upload the Docker image to the Docker hub but you can also set up a pipeline to automate the process.
I've built the Docker image on my M1 Pro and it led to some arch issues when the container was uploaded to Azure. Be sure to add the --platform linux/amd64 in the image-building step if you're building for Linux.
Related
I am using web for container in azure
- platform linux
My application was written in Node.js with socketio.
I use docker for create container.
I've already tested in local machince websocket is work fine but when I deploy to azure web for container.
When I try to connect websocket, I always got error code 503 Service Temporarily Unavailable.
I'm trying to use jsreports.net (following this answer) to generate a pdf in an aspnet core application. Locally it runs fine but when I push it to an azure web app the app fails on start up. Does anyone know if this scenario is possible?
I reproduce your problem and it seems that jsreport uses headless chrome to print pdf. Unfortunately Azure Web Apps running on windows are very restrictive and doesn't allow running headless chrome process. In the other words jsreport.Local won't be able to print pdf in Azure Web Apps running on windows.
Fortunately, Azure Web Apps running in docker with Linux host are using different sandboxing strategy and headless chrome works there. If this is an option for you, enable Linux docker support in your Azure Web App and add to your Dockerfile lines from the docker chapter. Additionally you need to explicitly specify jsreport internal port, because of collision in the environment variables.
For more details, you could refer to this article.
I have create cordapp in azure VM. now i want to deploy that cordapp into Azure cloud server so that client from anywhere can hit cordapp. but i confused whether i have to use webapps or inbuilt Blockchain module in marketplace. if so, how to do deploy?
You can deploy a node to a cloud server by following the instructions here: https://docs.corda.net/deploying-a-node.html.
You can then interact with your node remotely, using either:
An RPC client (e.g. https://github.com/corda/cordapp-template-java/blob/release-V3/clients/src/main/java/com/template/Client.java)
A server (e.g. https://github.com/corda/cordapp-template-java/tree/release-V3/clients/src/main/java/com/template/webserver)
The node shell over SSH (Corda V3 onwards - see https://docs.corda.net/head/shell.html#the-shell-via-ssh)
App 1: I have a React app (based on create-react-app) which I've added as a Web App in Azure - that was pretty straight-forward to setup. This is using the JS SignalR client to communicate with the server, mentioned next.
App 2: This app is the ASP.NET Core SignalR Server application created with dotnet new console. This app exposes a SignalR endpoint and is "self hosted".
App 3: A 2nd ASP.NET Core console app is setup as a SignalR client. This is responsible to fetching some data, and sends those data to the SignalR server. This takes the SignalR endpoint (url) as a commandline argument.
Running all this locally is pretty straightforward:
App 1: npm start / serve -s build
App 2: dotnet run -commandline args (runs on localhost taking a hubpath and port from the args supplied. The port is so that multiple instances SignalR servers can run on localhost - not sure if this is the way to do it in Azure or if they're differentiated with separate urls and hosted seperately there)
App 3: dotnet run "http://localhost:5000/somenotificationhubname"
I've added a bat file in each of the console apps, so I can open multiple instances of those, with different args.
So locally it runs as easily as clicking 3 bat files.
But I'm kinda lost on how to host all this in Azure. The web app seemed pretty straightforward. I just created a web app in Azure, connected to it through an FTP client and copied over the contents of the build folder from the React app.
But what to do with the ASP.NET Core console applications so that the SignalR console app will be hosted in Azure and has its endpoint exposed for the other 2 apps to consume?
I tried adding both both App 2 and 3 as webjobs under App 1, but that didn't seem to work.
I've also heard that SignalR should not be running on IIS, so would it make sense to make it self-contained (exe) and run it inside a docker container? Any help is much appreciated.
I will suggest to change your app to use AppSettings file for configuration values instead of the commandline args.
You can easily change the value of appsettings without redeploying or changing anything.
You can have multiple appsettings file based on environments.
Allows you to easily duplicate the app with same code but different appsettings for your multiple signalr server.
This will make it easier to deploy using the standard publishing wizard in Visual Studio or via command line.
You could try the publish Profile in Azure App Service with the help of Visual Studio,
Reference 1
Reference 2
Once you successfully publish your webApp. You can double check the deployment using kudu service (or) App service editor
Advanced Tool-KUDU
AppService editor
Consider a docker image containing a React UI and a Spring REST app. I'd like to deploy this to Azure web app for containers, where the URL for the instance hits the UI which is being statically served on port 5000 while the Spring app is listening on 8080. The UI communicates with the Spring app via HTTP, hence the requests made by the UI to the Spring app are evaluated on the user's machine (i.e. can't access the Spring app via localhost:8080). However, port 8080 is not mapped in the default run command. Another issue is that there is only one URL for the web app.
The default run command is: (from logging in via FTP and examining docker logs)
docker run -d -p <WEB_APP_PORT>:<UI_PORT> --name ... -e ... <IMG>
Can I run a custom docker run command to expose the UI_PORT and the SPRING_PORT and also set up one web app with two URLs?
If not, are there alternative solutions?
For context:
The final image is built by extending an image which contains only the Spring app (i.e. FROM openjdk:8-jdk-alpine) and installing node and the UI.
An entrypoint.sh script start both the UI and the SPRING APP
The ports exposed in the image are 8080 and 5000.
A diagram of what I'm trying to achieve:
No, you can't do what you want with "Azure web app for containers", that platform lets you run a single container image that is mapped to ONLY one URL, and you can ONLY export web ports (80, 443) to the world, and SSH (2222) to their internal "kudzu" service.
Being "purist", you are describing a "microservice stack", so you have to go with a full container orchestration, like "Azure Container Service" (AKS, using Kubernetes), or "Azure Service Fabric" (which looks it will be awesome when they reach their goals).
However, you could get it done by internally running a "mapping service", like an Nginx proxy which would send "/" to the localhost:8080 UI and /api to localhost:5000 Spring API, or any of the techniques traditionally used for Single-page-Application "routing".
It's a decision between putting all your services inside a single container behind a single URL (microservice in a container) or putting every process in a container on a container orchestration platform (the former is cheaper in time and cost of running it, the later is more "elegant" and flexible but requires more time to build the management and is more expensive to run).