how to update docker images and restart it for ReactJS app - reactjs

I have a reactjs app, and now I dockerized it with the following Dockerfile
# get the base node image
FROM node:alpine as builder
# set the working dir for container
WORKDIR /frontend
# copy the json file first
COPY ./package.json /frontend
# install npm dependencies
RUN yarn install
ENV REACT_APP_API_ADDRESS=http://localhost:7001
# copy other project files
COPY . .
# build the folder
RUN yarn build
# Handle Nginx
FROM nginx
COPY --from=builder /frontend/build /usr/share/nginx/html
COPY ./docker/nginx/default.conf /etc/nginx/conf.d/default.conf
and my nginx conf is simple like below:
server {
listen 7001;
server_name _;
index index.html;
root /usr/share/nginx/html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
location / {
try_files $uri /index.html =404;
}
}
and then, I build it and push it to docker hub, I hope if I have publish a new image or you can said the latest one, the reactjs application should popup a window or a notification to let the user click it (I can make it so far).
and then, if user click the update notification button, the another server i call it hook_upgrade_server in anther container, which will get a signal and then it will execute docker pull reactjs and restart it by docker run -d -p7001:7001 reactjs docker container with latest images.
Which mean, I want to install two container on the user host:
reactjs do some business
hook_upgrade_server for wait user click signal and pull latest image and restart
So, How can i make it happen?

Related

Unexpected Token Error in React When Hosting on a Subpath Using Nginx + Traefik

I have a Docker container running a production React app alongside Nginx for hosting its static files.
Dockerfile
FROM node:16.5.0-alpine AS builder
WORKDIR /app
COPY . .
ENV PUBLIC_URL /trade-journal
RUN npm ci --production
RUN npm run build
FROM nginx:1.23.1-alpine AS production
ENV NODE_ENV production
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
nginx.conf
server {
listen 80;
location / {
# static file hosting location
root /usr/share/nginx/html/;
include /etc/nginx/mime.types;
try_files $uri $uri/ /index.html;
}
}
Above, you can see that I'm setting a PUBLIC_URL environment variable. This is because I'd like the app to be hosted on a subpath, like this: domain.com/trade-journal. I'm using Traefik to route to this subpath because in the future, I'd like to add more subpaths for other apps.
docker-compose.yml
reverse-proxy:
image: traefik:v2.8
command: --api.insecure=true --providers.docker
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
labels:
- traefik.enable=false
frontend:
build:
context: ./trade-journal/client
dockerfile: ./Dockerfile
image: "trade-journal-client"
labels:
- traefik.http.routers.frontend.rule=Host(`[MY-PUBLIC-IP-HERE]`) && PathPrefix(`/trade-journal`)
- traefik.http.services.frontend.loadbalancer.server.port=80
links:
- "backend:be"
I understand that React is designed to run on root by default, so I added:
<base href="%PUBLIC_URL%/"> in public/index.html, and
basename={process.env.PUBLIC_URL} to BrowserRouter
I've also alternatively tried setting the subpath with homepage in package.json, and writing the basename as just /trade-journal.
Either way, I get the same error in my browser on a blank page:
For whatever reason, it can't load http://domain/trade-journal/static/js/main.93967f03.js. Actually, I can't even view the code in that file, or any other JS or CSS files in that directory through the browser (even though I can when I bin/sh into the running container); I only ever get a blank index file.
I assume that the problem has to do with routing because when I remove any having to do with the subpath and host on /, the React app loads correctly.
I'm very new to hosting and deploying. How can I solve this problem?
It seems that I fixed it. I needed to use alias, and include the subpath in nginx as well. Now, I'm going to see if I can make this solution any more DRY (so I don't have to repeat the subpath so many times). If anyone has any suggestions, let me know.
location /trade-journal {
# static file hosting location
alias /usr/share/nginx/html/;
include /etc/nginx/mime.types;
try_files $uri $uri/ /trade-journal/index.html;
}

React PWA not working on production on nginx server

Getting following error when deploying React app with service worker on nginx server with docker, the error cause service worker to be status: redundant
Here is my docker config
ARG ENV
WORKDIR '/app'
COPY . .
RUN ls -la
RUN yarn install
RUN yarn build:$ENV
FROM nginx:alpine
RUN apk add --no-cache bash
RUN apk add --no-cache ca-certificates
EXPOSE 80
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/build /usr/share/nginx/html
and nginx default.conf
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /healthz {
access_log off;
return 200 "healthy\n";
}
error_page 404 /index.html;
location = /index.html {
root /usr/share/nginx/html;
internal;
}
}
App runs fine when running ./build version locally with servo but only one deployment it shows above error and service worker no longer works.

react docker nginx kubernetes 404

::: UPDATE :::
It seems to be a SSL issue. I changed the nginx.conf to port 80 and it works.
I am trying to solve the problem of the 404 errors in React when a user clicks refresh.
The application runs in Docker in Kubernetes on Azure.
I have tried changing the nginx.conf file and pulling it into the container.
Even though the Docker builds, it seems like the container is still running the default nginx.conf.
nginx.conf
server {
listen 443 ssl;
location / {
root /var/www;
index index.html index.htm;
try_files $uri $uri/ /index.html?$args;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www;
}
}
Docker file
FROM node:13.12.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm install
RUN npm install react-scripts#3.4.1 -g
COPY . ./
RUN npm run build
# production environment
FROM nginx:alpine
# copy the build folder from react to the root of nginx (www)
COPY --from=build /app/build /var/www
# --------- only for those using react router ----------
# if you are using react router
# you need to overwrite the default nginx configurations
# remove default nginx configuration file
RUN rm /etc/nginx/conf.d/default.conf
# replace with custom one
COPY /nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]
Project Structure

How to disable NGINX logging with file

I am very new to Nginx and noticed that whenever I hit my server locally it logs. I was wondering, what config files do I need to create (and where do I put them) and what do I have to put into them to disable that behavior (I am trying to prevent spew). I am running my application on aws and am getting a lot of log lines of the form '172.31.22.19 - - [23/Jun/2021:23:38:33 +0000] "GET / HTTP/1.1" 200 3022 "-" "ELB-HealthChecker/2.0" "-"' Is there a way to disable that? Or do I need to disable everything?
My docker file is:
# pull official base image
FROM node:16 AS builder
# set working directory
WORKDIR /app
# install app dependencies
#copies package.json and package-lock.json to Docker environment
COPY package.json ./
# Installs all node packages
RUN npm install
# Copies everything over to Docker environment
COPY . ./
RUN npm run build
#Stage 2
#######################################
#pull the official nginx:1.19.0 base image
FROM nginx:1.19.0
#copies React to the container directory
# Set working directory to nginx resources directory
WORKDIR /usr/share/nginx/html
# Remove default nginx static resources
RUN rm -rf ./*
# Copies static resources from builder stage
COPY --from=builder /app/build .
EXPOSE 80
# Containers run nginx with global directives and daemon off
ENTRYPOINT ["nginx", "-g", "daemon off;"]
I can successfully run the above with 'docker run -p 80:80 my-app'
if you are using a docker run command to run the container then add the flag --log-driver none to the run command
Looking at your dockerfile youre running node and nginx in a single container. I would advise against this and seperate them into seperate containers using docker-compose
if you do this then add the line driver: none to the service running the nginx container
I fixed the issue by adding a nginx.conf file (see below) and changing the value of access_log to 'off'. I describe the steps I took
get the nginx.conf file:
Per What is the 'default' nginx.conf that comes with docker Nginx image? do the following:
# Create a temporary container
docker run -d --rm --name mynginx nginx
# Copy the nginx configuration in the container
docker cp mynginx:/etc/nginx .
create nginx.conf file in root of project. Mine was:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log off;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
Modify Dockefile to (note the 'COPY nginx.conf /etc/nginx/nginx.conf'):
# pull official base image
FROM node:16 AS builder
# set working directory
WORKDIR /app
# install app dependencies
#copies package.json and package-lock.json to Docker environment
COPY package.json ./
# Installs all node packages
RUN npm install
# Copies everything over to Docker environment
COPY . ./
RUN npm run build
#Stage 2
#######################################
#pull the official nginx:1.19.0 base image
FROM nginx:1.19.0
COPY nginx.conf /etc/nginx/nginx.conf
#copies React to the container directory
# Set working directory to nginx resources directory
WORKDIR /usr/share/nginx/html
# Remove default nginx static resources
RUN rm -rf ./*
# Copies static resources from builder stage
COPY --from=builder /app/build .
EXPOSE 80
# Containers run nginx with global directives and daemon off
ENTRYPOINT ["nginx", "-g", "daemon off;"]

React app deployed with docker and nginx : /etc/nginx/conf.d/default.conf differs from the packages

hi I am having a problem to deploy my React app ( create react app) using docker and nginx
the image is created with success : using the following script :
docker build -t front --network=host .
howver when I try to run the container : docker run -p 3000:80 front
it is not working and I got the following message :
10-listen-on-ipv6-by-default.sh: /etc/nginx/conf.d/default.conf differs from the packages version, exiting
my docker file :
FROM node:12.19.0-alpine3.12 as build
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
#ARG REACT_APP_BACKENDURL
#ENV REACT_APP_BACKENDURL $REACT_APP_BACKENDURL
# install and cache app dependencies
COPY package.json ./
COPY package-lock.json ./
RUN npm ci
RUN npm install react-scripts#3.2.0 -g --silent
COPY . ./
RUN npm run build
# add app
#COPY . /app
# generate build
#RUN npm run build
############
### test ###
############
# base image
FROM nginx:1.19.0-alpine
# copy artifact build from the 'build environment'
COPY --from=build /app/build /usr/share/nginx/html
#nginx config with react router
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
# expose port 80
EXPOSE 80
#COPY .env /usr/share/nginx/html
# run nginx
CMD ["nginx", "-g", "daemon off;"]
my nginx.conf :
server {
listen 3000;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
any ideas what I did wrong,, also I am looking for best practices to deploy REACT APP with docker
You should separate dockefile above into 2 dockerfile,
One for front image , one for nginx.
Then create both images. And 2 containers are belong to those images.
Expose dockerfile nodejs : 3000
And add to nginx configuration file: proxy_pass ip_address_nodejs_container:3000

Resources