Unable to run a react app inside docker container using nginx - reactjs

I'm trying to run a react app inside a docker container using DOCKER-multistage.
The server is written on deno and I tried to add nginx server to dispatch the requests from the frontend to the server.
Dockerfile:
FROM ubuntu:20.04
# install curl
RUN apt-get update && apt-get install -y curl unzip sudo nginx
# install node.js v16.x
RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash -
RUN apt-get install -y nodejs
# install postgresql
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
curl vim wget \
build-essential \
libpq-dev &&\
apt-get update && apt-get install -y tzdata nodejs yarn postgresql postgresql-contrib
# install deno v1.21.3
RUN curl -fsSL https://deno.land/install.sh | sh -s v1.21.3
ENV DENO_INSTALL="/root/.deno"
ENV PATH="${DENO_INSTALL}/bin:${PATH}"
# Install denon
RUN deno install -qAf --unstable https://raw.githubusercontent.com/nnmrts/denon/patch-4/denon.ts
# The working directory of the project
WORKDIR /app
# Copy the app package and package-lock.json file
COPY frontend/build/ /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
# Copy the backend directory
RUN mkdir backend
COPY backend/deps.ts ./backend/deps.ts
RUN cd ./backend && deno cache --unstable deps.ts
ADD backend ./backend
EXPOSE 3000
COPY ./script.sh script.sh
CMD ./script.sh
script.sh:
#!/bin/bash
# create the database in postgres
service postgresql start && su - postgres -c "psql -U postgres -d postgres -c \"alter user postgres with password 'postgres';\"" \
&& su - postgres -c "psql postgres -c \"create database db;\""
# start nginx
sudo service nginx start
# Populate database tables
cd backend && deno run --unstable --allow-env --allow-net database/seeds.ts && denon start &
# Wait for any process to exit
wait -n
# Exit with status of process that exited first
exit $?
nginx.conf:
server {
listen 3000;
root /usr/share/nginx/html;
location / {
try_files $uri $uri/ /index.html;
proxy_pass http://localhost:5000/;
}
}
I build the image :
docker build . -t server-app
And I create a new container:
docker run -p 3000:3000 server-app
Everything is working and the deno server is listening on the 5000 port but when I run the app on localhost:3000/ I got this error:
The connection was reset
The connection to the server was reset while the page was loading.
The site could be temporarily unavailable or too busy. Try again in a few moments.
If you are unable to load any pages, check your computer’s network connection.
If your computer or network is protected by a firewall or proxy, make sure that Firefox is permitted to access the Web.
What's wrong with the config I have done?

I fixed the issue by updating the nginx.conf:
server {
listen 3000;
server_name localhost;
root /usr/share/nginx/html;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
location /api {
rewrite ^/api/?(.*) /$1 break;
proxy_pass http://localhost:5000;
}
}

Related

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.

how to fix 404 not found error nginx on docker?

I'm trying to make docker file run in to react app.react app all ready successfully deploy but page reload get an error 404 nginx error.
this is my docker file
FROM nginx:1.19.4-alpine
RUN rm -rf /usr/share/nginx/html/*
COPY build-qa /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Could be React Router DOM issue with nginx. Might check if you have the nginx.conf (local)
# nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
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 /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
#include /etc/nginx/conf.d/*.conf;
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
}
Then try build the image and run. Sample Dockerfile content:
FROM nginx
# FROM node:8 as react-build
WORKDIR /usr/share/react
RUN curl -fsSL https://deb.nodesource.com/setup_17.x | bash -
RUN apt-get install -y nodejs
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
RUN rm -r /usr/share/nginx/html/*
RUN cp -a build/. /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
# Build Image
# docker build . -t <your-app-tag>:latest
# Run Container
# docker run -it --rm -d -p 8080:80/tcp --name <your-app-name> <your-app-tag>

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

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

How to make a single React Docker build/image to run through all environments?

i'm trying to deploy a React application in a single Docker container able to run through dev, preprod and prod on an OpenShift platform on which i can only push tagged docker images. In order to do this i have:
a React application generated with create-react-app hosted on Github
a Dockerfile at project root containing the docker build/run process
a .gitlab-ci.yml file containing the continuous integration checks and deploy methods
an accessible OpenShift platform
What i can do:
I can easily generate a production build '/build' that will be added in the docker image build phase and will run with a production context or i can build at run start (but just writing it feels bad).
The problem:
This generated image isn't able to run through all environment, and i don't want to have a specific build for each environment.
What i want:
I want to be able to generate a single docker image that will run through all environments without having to install dependencies or build when only RUN is needed.
here is my Dockerfile:
FROM nginx:1.15.5-alpine
RUN addgroup --system app \
&& adduser --uid 1001 --system --ingroup app app \
&& rm -rf /etc/nginx/conf.d/default.conf \
&& apk add --update nodejs nodejs-npm \
&& mkdir /apptmp
COPY . /apptmp
RUN chmod 777 /apptmp
COPY config/default.conf /etc/nginx/conf.d/
COPY config/buildWithEnv.sh .
RUN touch /var/run/nginx.pid && \
chown -R app:app /var/run/nginx.pid && \
chown -R app:app /var/cache/nginx && \
chown -R app:app /usr/share/nginx/html
EXPOSE 8080
USER 1001
CMD sh buildWithEnv.sh
And here is the script buildWithEnv.sh
#!/bin/bash
echo "===> Changin directory: /apptmp ..."
cd /apptmp
echo "===> Installing dependencies: npm install ..."
npm install
echo "===> Building application: npm run build ..."
npm run build
echo "===> Copying to exposed html folder ... "
rm -rf /usr/share/nginx/html/*
cp -r build/* /usr/share/nginx/html/
echo "===> Launching http server ... "
nginx -g 'daemon off;'
A possible approach is described on this blog-post
Basically: You use placeholders for all environment specific parts in your static resources. Then you configure nginx' sub_filter to replace those at runtime with the environment specific values.
I finally found a way.
Build application
The first step is to make a static build of your application, environment agnostic. (Actually for my situation this is done by the CI so i directly retrieve the static build in Docker build part)
Create Nginx conf
In your project, create a file holding the default configuration for nginx, plus the reverse proxy configuration your need, and fill the proxy_pass with values easily and uniquely replacable.
server {
gzip on;
gzip_types text/plain application/xml application/json;
gzip_vary on;
listen 8080;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_set_header x-clientapikey REACT_APP_BAMBOO_API_KEY;
proxy_pass REACT_APP_SERVICE_BACK_URL;
}
location /auth {
proxy_set_header Authorization "Basic REACT_APP_AUTHENTIFICATION_AUTHORIZATION";
proxy_pass REACT_APP_SERVICE_AUTH_URL;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Openshift configuration
In your OC application, go to the "environment" tab, and add all the environnement variables you will use in your nginx conf.
Dockerfile build
In the dockerfile build part, move your build to its correct position into nginx html folder, and handle your configuration files, including nginx.
FROM nginx:1.15.5-alpine
RUN addgroup --system app \
&& adduser --uid 1001 --system --ingroup app app \
&& rm -rf /etc/nginx/conf.d/default.conf \
&& apk --update add sed
COPY ./build /usr/share/nginx/html/
COPY config/default.conf /etc/nginx/conf.d/
RUN chmod 777 -R /etc/nginx/conf.d/
COPY config/nginxSetup.sh .
RUN touch /var/run/nginx.pid && \
chown -R app:app /var/run/nginx.pid && \
chown -R app:app /var/cache/nginx && \
chown -R app:app /usr/share/nginx/html
EXPOSE 8080
USER 1001
CMD sh nginxSetup.sh
Dockerfile run
In the dockerfile run part (CMD), just use the command line tool sed in order to replace paths in your nginx reverse proxy configuration.
#!/usr/bin/env bash
sed -i "s|REACT_APP_SERVICE_BACK_URL|${REACT_APP_SERVICE_BACK_URL}|g" /etc/nginx/conf.d/default.conf
sed -i "s|REACT_APP_SERVICE_AUTH_URL|${REACT_APP_SERVICE_AUTH_URL}|g" /etc/nginx/conf.d/default.conf
sed -i "s|REACT_APP_BAMBOO_API_KEY|${REACT_APP_BAMBOO_API_KEY}|g" /etc/nginx/conf.d/default.conf
sed -i "s|REACT_APP_AUTHENTIFICATION_AUTHORIZATION|${REACT_APP_AUTHENTIFICATION_AUTHORIZATION}|g" /etc/nginx/conf.d/default.conf
echo "===> Launching http server ... "
nginx -g 'daemon off;'
And here you are.

Resources