Deploying Angular Universal 9 to Google App Engine - node.js

I am not sure the situation has been changed but it seems I got stuck with the versions I am using.
Previously, in Angular 7, we were able to generate server files for Angular Universal at the root level so we could have node main.js in app yaml and Google App Engine just found the way to run our web application. It seems this is not possible anymore for Angular 9.
We are using Angular SSR for our production web site. It compiles all the server files in /dist-server folder. There is a docker file to deploy it on Google App Engine:
FROM node:12-alpine as buildContainer
WORKDIR /app
COPY ./package.json ./package-lock.json /app/
RUN npm install
COPY . /app
RUN npm run build:ssr // This will create dist/ and dist-server/ folders in the docker
FROM node:12-alpine
WORKDIR /app
COPY --from=buildContainer /app/package.json /app
COPY --from=buildContainer /app/dist /app/dist
COPY --from=buildContainer /app/dist-server /app/dist-server
EXPOSE 4000
CMD ["npm", "run", "serve:ssr"]
In package.json we have :
"serve:ssr": "node dist-server/main.js",
In order to start the deployment, we type gcloud app deploy in the terminal and everything works fine for this process. The main problem is this takes almost 25 mins to finish. The main bottleneck for the time consuming part is the compiling.
I thought we could have compiled the repo on our local dev machine, and copy only dist/ and dist-server folder to the docker and add node dist-server/main.js to run our web application in the docker file. Whenever I tried to copy only dist and dist-server folder. I got below error message:
COPY failed: stat /var/lib/docker/tmp/docker-builder{random numbers}/dist: no such file or directory
I also tried to compile the main.js which is the main server file for angular universal at the same level as app.yaml. I assumed this is required according to Google App Engine Node JS deployment rule since there is an example repo from Google. I cannot compile our main.js file into the root folder, it gives below error message:
An unhandled exception occurred: Output path MUST not be project root directory!
So I am looking for a solution to which does not require Google App Engine to rebuild our repo (since we can do this in our dev machine and upload the compiled files for the sake of time saving) to make the deployment process faster.
Thanks for your help

I have found that the .dockerignore file had dist and dist-server folder in it. I have removed those entries. I am able to compile and deploy the docker file on google app engine now.

Related

What is the command needed for an API backend Dockerfile?

I am new to creating Dockerfiles and cannot figure out what command to use to start up the API backend application. I know that backend applications don't use Angular and that the command to start it is not "CMD ng serve --host 0.0.0.0".
I am attaching the code of the backend Dockerfile and also providing the errors that I am getting when trying to run the container in Docker Desktop below.
I have looked at Docker documentation and Node commands but cannot figure out what command to use to make the API backend run. What am I doing wrong?
Code:
# using Node v10
FROM node:10
# Create app directory
WORKDIR /usr/src/lafs
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm#5+)
COPY package*.json ./
RUN npm install
# If you are building your code for production
# RUN npm ci --only=production
# Bundle app source
COPY . .
# Expose port 3000 outside container
EXPOSE 3000
# Command used to start application
CMD ng serve --host 0.0.0.0
Errors that I am receiving in Docker Desktop:
/bin/sh: 1: ng: not found
From your original screenshot, it looks like you've got a server directory. Assuming that's where your Express app lives, try something like this
FROM node:16 # 12 and older are EOL, 14 is in maintenance
WORKDIR /usr/src/lafs
EXPOSE 3000 # assuming this is your server port
COPY server/package*.json . # copy package.json and package-lock.json
RUN npm ci --only=production # install dependencies
COPY server . # copy source code
CMD ["npm", "start"] # start the Express server

Docker Nginx with nuxt.js and hot reload setup

Problem
Currently I can only create simple Dockerfiles but I have no experience with docker-compose. I have taken over a project where a static page was
built with Nuxt.js. I want to build a development environment where I can work
with hot reload or just a copy which immediately transfers the change to the nginx service.
Currently, only when I building a container, the dist folder is copied into the nginx/html folder. So I can then call the page.
Question:
What can I do so that the nginx/html folder is overwritten (hot reload)
when saving the Vue file?
I found an interesting approach on SO (option 4). https://stackoverflow.com/a/64010631/8466673
But I don't know how to configure a docker-compose from my one docker file.
My dockerfile
# build project
FROM node:14 AS build
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
RUN npm run build
# create nginx server
FROM nginx:1.19.0-alpine AS prod-stage
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD [ "nginx", "-g", "daemon off;" ]

Problem deploying MERN app with Docker to GCP App Engine - should deploy take multiple hours?

I am inexperienced with Dev Ops, which drew me to using Google App Engine to deploy my MERN application. Currently, I have the following Dockerfile and entrypoint.sh:
# Dockerfile
FROM node:13.12.0-alpine
WORKDIR /app
COPY . ./
RUN npm install --silent
WORKDIR /app/client
RUN npm install --silent
WORKDIR /app
RUN chmod +x /app/entrypoint.sh
ENTRYPOINT [ "/app/entrypoint.sh" ]
# Entrypoint.sh
#!/bin/sh
node /app/index.js &
cd /app/client
npm start
The React front end is in a client folder, which is located in the base directory of the Node application. I am attempting to deploy these together, and would generally prefer to deploy together rather than separate. Running docker-compose up --build successfully redeploys my application on localhost.
I have created a very simple app.yaml file which is needed for Google App Engine:
# app.yaml
runtime: custom
env: standard
I read in the docs here to use runtime: custom when using a Dockerfile to configure the runtime environment. I initially selected a standard environment over a flexible environment, and so I've added env: standard as the other line in the app.yaml.
After installing and running gcloud app deploy, things kicked off, however for the last several hours this is what I've seen in my terminal window:
Hours seems like a higher magnitude of time than what seems right for deploying an application, and I've begun to think that I've done something wrong.
You are probably uploading more files than you need.
Use .gcloudignore file to describe the files/folders that you do not want to upload. LINK
You may need to change the file structure of your current project.
Additionally, it might be worth researching further the use of the Standard nodejs10 runtime. It uploads and starts much faster than the Flexible alternative (custom env is part of App Engine Flex). Then you can deploy each part to a different service.

running react and node in a single docker file without docker-compose.yml file

i have a sample project using reactjs and nodejs below is the folder structure.
movielisting
Dockerfile
client
package.json
package.lock.json
... other create-react-app folders like src..
server
index.js
I start this project by npm run start - client folder and nodemon index.js - server folder. All my api's are written in server folder. My client is running in port 3000 and server is running in port 4000, i have added proxy in package.json of client like below
"proxy": "http://localhost:4000"
So what i am trying to achieve in Dockerfile is i want to start application by running this Dockerfile
1) i need to create the build of client by running npm run build
2) copy to the workdir inside the container
3) copy all server folder
4) npm install for the server folder
5) proxy the application
how can i do this one ? should i need to write some code in nodejs to serve the build index.html file
also how can i run the Dockerfile command to run the application.
Any help appreciated !!!
In order to build both frontend and backend into single image. you need to do the following:
For the frontend application it needs to be built in order to serve it as a static file
For the backend application it needs to be running inside the container and exposed publically so the frontend can reach it from the browser as using localhost:4000 will end up calling the user's localhost not the container's localhost
Finally you need to use something like supervisor as a service manager in order to run multiple service in single container. You might need to check the following
As an example you might check the following:
FROM node:10.15.1-alpine
COPY . /home/movielisting
#Prepare the client
WORKDIR /home/movielisting/client
RUN npm install --no-cache && npm run build && npm install -g serve
#Prepare the server
WORKDIR /home/movielisting/server
RUN npm install --no-cache
EXPOSE 4000
CMD [ "npm", "start", "index.js" ]
You might need to check the following links:
ReactApp Static Server
Deployment

Workdir of Node.JS

I have a dockerfile from nodejs. I'm copying the right folders (which are in my repo after a npm install) and I start the node.js server.
It seems to work fine but what I don't understand is /usr/src/www.
I saw it often on the internet. But is it important in which directory you're running your server.js?
FROM node
# Create app directory
RUN mkdir -p /usr/src/www
WORKDIR /usr/src/www
# copy
COPY node_modules /usr/src/www/node_modules
COPY gulpfile.js /usr/src/www/gulpfile.js
COPY gulp.config.js /usr/src/www/gulp.config.js
COPY server.js /usr/src/www/server.js
EXPOSE 8080
CMD [ "node", "server.js" ]
In node.js all the references are relative to the file which you reference from. So usually the working dir is less relevent

Resources