is there any way that I can serve my ".next" folder without using next.js? - reactjs

I know how to reduce the size, I should remove dev time dependencies, another option is easy to find on the internet. But the real question comes while serving the next.js app. I deploy the website on production through pm2 using next start. What is really happening is that next start won't work without dev dependencies and which affects the size of the docker image. Is there any way that I can serve my .next folder without using next.js? This will reduce the massive size of the docker image.

You can use yarn install --production=true to ignore devDependencies and only install regular dependencies.
Using this, you can install production dependencies first in a temporary folder, then copy the dependencies to the app folder and remove the temp folder.
Here's an example Dockerfile:
# Install production dependencies
WORKDIR /tmp/app
COPY ./package.json ./package.json
COPY ./yarn.lock ./yarn.lock
RUN yarn install --production=true
RUN mkdir -p /home/node/web && cp -a ./node_modules /home/node/web/
# Build project
COPY . .
RUN yarn install --production=false
RUN yarn run build
RUN cp -a ./dist /home/node/web/
# Clean up
RUN rm -rf /tmp/app
# Run next app
WORKDIR /home/node/web
CMD NODE_ENV=production ./node_modules/.bin/next

Related

React App on Fargate is ignoring env variable

I deployed my React app and backend using Fargate with load balancers, I noticed my React app is using the wrong endpoint to access my API, it seems to be using the it's load balancer's DNS name as it's endpoint even though this endpoint is configured by using environment variables (On a React App, so this would be REACT_APP_API_URL).
On my local machine, this container works fine and is able to connect to my backend. Here it shows the correct endpoint.
If I were to run this same exact image in Fargate, the wrong endpoint is shown, this is actually the URL to visit my web app.
And I configured the correct endpoint in my task definition like so, it matches the correct endpoint shown in figure 1. I also made sure the service is using the latest task definition with this endpoint.
If needed this is my docker file.
# The first image is for compiling the client files, the second is for serving.
# BUILD IMAGE
FROM node:14-alpine as build-stage
WORKDIR /app
# Install dependencies
COPY package*.json ./
RUN npm install
RUN npm install cross-env -g
RUN npm install npm install #craco/craco -g
# Build
COPY . .
RUN npm run build
# -----------------------------------------------------------------------------
# SERVING IMAGE
FROM fitiavana07/nginx-react
# Copy built files
COPY --from=build-stage /app/build /usr/share/nginx/html
# 80 for HTTP
EXPOSE 80
# Run nginx
CMD nginx -g 'daemon off;'
Turns out I'm an idiot lol, you need a .env file at the root of your project, this means you can't pass environment variables to be docker image. I managed to overcome this by creating .env on my docker file like so.
# The first image is for compiling the client files, the second is for serving.
# BUILD IMAGE
FROM node:14-alpine as build-stage
WORKDIR /app
# Install dependencies
COPY package*.json ./
RUN npm install
RUN npm install cross-env -g
RUN npm install npm install #craco/craco -g
# Build
COPY . .
# Create a .env for react app
# Define a required build arg
ARG api_url
# Create a .env file
RUN touch .env
# Write the api url into the env file
RUN echo REACT_APP_API_URL=${api_url} > .env
RUN cat .env
RUN npm run build
# -----------------------------------------------------------------------------
# SERVING IMAGE
FROM fitiavana07/nginx-react
# Copy built files
COPY --from=build-stage /app/build /usr/share/nginx/html
# 80 for HTTP
EXPOSE 80
# Run nginx
CMD nginx -g 'daemon off;'
On my GitHub Actions, I use this action to dynamically set this build argument

Next js app (running inside a docker container) fails to load static file images located in public dir

I am trying to run a next js app locally inside a docker file. When I run the container, everything works as expected with the exception of my image files failing to render on the page. Inspection via the developer tools indicates a failed network request for those images (no 4XX code is indicated). The failed request looks as follows:
When I build npm run build and run the app locally npm run start, I see this same request successfully run. Same success story when I run in development mode npm run dev.
Here is the section of code utilizing the next Image module. import Image from "next/image";
<Image
src="/images/computerStation.png"
alt=""
height={300}
width={600}
/>
And my public directory tree:
root
│
└───public
│
└───images
│
└───computerStation.png
Given my local build/dev-env success, my thought is that I am doing something wrong with my docker file. I pretty much just ripped this off from the Next js docs and tweaked it to run with npm instead of yarn. See Dockerfile below:
# Install dependencies only when needed
FROM node:alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install --frozen-lockfile
# Rebuild the source code only when needed
FROM node:alpine AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN npm run build
# Production image, copy all the files and run next
FROM node:alpine AS runner
WORKDIR /app
ENV NODE_ENV production
# You only need to copy next.config.js if you are NOT using the default configuration
# COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
RUN chown -R nextjs:nodejs /app/.next
USER nextjs
EXPOSE 3000
# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry.
RUN npx next telemetry disable
CMD ["node_modules/.bin/next", "start"]
Any help on this would be greatly appreciated. Thanks!
You need to check your docker Node version, which should be
FROM node:14-alpine AS deps
FROM node:14-alpine AS builder
FROM node:14-alpine AS runner
Next.js has some problems, in Node 16 (node:alpine).

npm run tests in docker with travis CI

I am deploying a react app to Heroku via TravisCI. The fact that I'm using Heroku doesn't really affect what I'm about to ask, I'm pretty sure, it's just there for context. Travis successfully deploys the app until I add a testing step (the script section) in .travis.yml:
language: generic
sudo: required
services:
- docker
before_install:
- docker build -t myapp:prod -f Dockerfile.prod .
script:
- docker run -e CI=true myapp:prod npm run test
after_success:
- docker build -t myapp:prod -f Dockerfile.prod .
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_ID" --password-stdin
- docker push myapp:prod
deploy:
provider: heroku
app: myapp
skip_cleanup: true
api_key:
secure: <my_key>
However, my Dockerfile.prod is a multi-stage node + nginx where the nginx stage doesn't keep any node or npm stuff:
# build environment
FROM node:13.12.0-alpine as builder
# set working directory
WORKDIR /app
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# install app dependencies
COPY package.json ./
COPY package-lock.json ./
# some CI stuff I guess
RUN npm ci
RUN npm install react-scripts#3.4.1 -g --silent
COPY . ./
RUN npm run build
# production environment
FROM nginx:stable-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
# If using React Router
COPY --from=builder /app/build /usr/share/nginx/html
# For Heroku
CMD sed -i -e 's/$PORT/'"$PORT"'/g' /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'
Therefore, it is my understanding that .travis.yml tries to run that npm run test command inside my nginx container and can't execute npm commands (no node installed, right?). So guided by SO answers such as this one I started adding commands into that nginx stage such as
COPY package.json ./
COPY package-lock.json ./
RUN apk add --update npm
but I realized I might be approaching this the wrong way. Should I perhaps be adding npm through Travis? That is, should I include in .travis.yml in the scripts section something like docker run -e CI=true myapp:prod apk add --update npm and whatever else is necessary? This would result in a smaller nginx image no? However, would I run into problems with package.json from the node stage in Dockerfile.prod or anything like that?
In summary, to use TravisCI to test a dockerized react app served with nginx, at what point should I install npm into my image? Does it happen as part of script in .travis.yml or does it happen in Dockerfile.prod? If it is recommened to npm run tests inside Dockerfile.prod, would I do that in the first stage (node) or the second (nginx)?
Thanks
EDIT: Not sure if this can be considered solved, but a user on Reddit recommended to simply RUN npm run test right before the RUN npm run build.

how to run bower install inside subfolder in Docker

--myproject
---app
----bower.json
----index.html
---package.json
My project folder structure is like that. What I want is I want to run bower install command in docker file before npm install. Following is my Dockerfile. Got stuck how to go sub folder and run bower install. Thanks.
### STAGE 1: Build ###
FROM node:latest as builder
LABEL auther="PPShein"
COPY package.json package.json
RUN npm install
COPY . .
RUN gulp default
Use
RUN cd app && bower install
Or
WORKDIR app
bower install
this changes the pwd for all following commands, which you may not want.
PS. Careful with COPY . ., it may overwrite what you just built.

Docker Multi-stage build - Copy failing

I'm having some issues with a multi-stage Dockerfile for an ejected create-react-app. The Dockerfile is listed below:
FROM node:9.6.1 as builder
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY package.json /usr/src/app/package.json
RUN npm install --silent
COPY . /usr/src/app
RUN npm run build
FROM nginx:1.13.9-alpine
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
EXPOSE 80
The Dockerfile runs successfully until it gets to step 10 (COPY) where it throws the following error:
COPY failed: stat /var/lib/docker/overlay2/2fc8af4cb8db9777246cae48721d8a93917c73e415a02680f1e3a73c8780b903/merged/usr/src/app/build: no such file or directory
I've googled away but can't find a clear answer. Has anyone experienced anything similar?
When you build the application it's building in another cointainer/layer. You i'll need to build the application before and copy the build folder to /usr/src/app.
So, this is fine:
FROM node:9.6.1 as builder
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY package.json .
COPY public public
COPY src src
RUN npm install --silent
RUN npm run build
COPY build .
RUN rm -rf src
RUN rm -rf build
FROM nginx:1.13.9-alpine
COPY --from=builder /usr/src/app /usr/share/nginx/html
EXPOSE 80
I'm removing the src and build folders since that's not necessary and can expose an critical part of your application.
Hence, no doubt about the security of dockerizing an application.
It's hard to tell from that, but my best guess would be that "RUN npm install --silent" is failing, possibly because it can't download one of your packages due to either a network issue or some other reason, therefore your build is then failing and not producing the build folder.
I had the same error using volumes Just because project (and Also dockerfile obviously) was outside Users/[currentuser] folder.. It Easy in "program files". Moving project from program files folder ti Users/[currentuser] It worked. I don't know if it's the same case. Try It and let me know
Possibly because COPY . /usr/src/app should be done inside top level directory so that build is created inside /usr/src/app. Do one thing. Put this command 'COPY . /usr/src/app' at the top(before WORKDIR /usr/src/app) and post the output here so I can help you better.
A cleaner way to do this would be like the following:
FROM node:9.6.1 as builder
WORKDIR /build
ENV PATH /build/node_modules/.bin:$PATH
COPY package.json /usr/src/app/package.json
RUN npm install --silent
COPY . /build/app
RUN npm run build
FROM nginx:1.13.9-alpine
COPY --from=builder /build /usr/share/nginx/html
EXPOSE 80

Resources