docker buildx not copying files when in production - docker

I am having an issue where the docker buildx tool doesn't properly copy files to the production container. For example:
FROM --platform=$BUILDPLATFORM node:16.14.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY yarn.lock ./
RUN apk update && apk add python3 g++ make && rm -rf /var/cache/apk/*
RUN yarn install
COPY . ./
RUN yarn run build
# production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html/
COPY ./nginx/nginx.conf /etc/nginx/conf.d/default.conf
# Default port exposure
EXPOSE 80
# Copy .env file and shell script to container
COPY ./env.sh /usr/share/nginx/html/env.sh
# Start Nginx server
CMD ["/bin/sh", "-c", "/usr/share/nginx/html/env.sh && nginx -g \"daemon off;\""]
All of the files from build will copy properly. However, the nginx.conf and env.sh will report as not found. Any ideas?
P.S: This seems to be an issue with nginx:alpine. No clue

Related

Docker build is using cache for COPY command even if my files have changed

I have a Dockerfile that is as follow:
FROM node:14-alpine as frontend-builder
WORKDIR /app/frontend
COPY ./frontend .
ENV PATH ./node_modules/.bin/:$PATH
RUN set -ex; \
yarn install --frozen-lockfile --production; \
yarn cache clean; \
yarn run build
CMD ["tail", "-f", "/dev/null"]
I have changed one file in frontend folder and re-run the build and docker is using the cache...I know i can force to build with --no-cache but how can i tweak docker so it detects changes in my files instead of no-cache option ?

How to create a Dockerfile for Nextjs and graphql?

I tried to deploy my Nextjs project to Heroku via Docker, so i follow docs on internet,then i get a Dockerfile like this
# 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 yarn.lock ./
COPY package.json package-lock.json ./
# RUN yarn install --frozen-lockfile
RUN npm ci
# Rebuild the source code only when needed
FROM node:alpine AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
# RUN yarn build && yarn install --production --ignore-scripts --prefer-offline
RUN npm run build && npm install --production --ignore-scripts --prefer-offline
# Production image, copy all the files and run next
FROM node:alpine AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# 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 --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
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.
ENV NEXT_TELEMETRY_DISABLED 1
# CMD ["yarn", "start"]
CMD ["npm", "run", "start"]
and .dockerignore
node_modules
.next
But i get this error when building
ERROR [runner 5/8] COPY --from=builder /app/public ./public
I think this error right because i don't see public folder in my project, maybe my project missing it
Then i go to learn basic about docker, i dont know so much , but i can create a simple Dockerfile like this
FROM node
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY . .
# RUN npm run build
# ENV NODE_ENV=production
EXPOSE 3000
USER node
CMD [ "npm","run","dev"]
with .dockerignore above,I test it with dev enviroment, if it can run I'll edit to production, I run my project by command
docker run -it -p 3000:3000 --name run-my-client my-client
But i get this error
[Error: EACCES: permission denied, unlink '/usr/src/app/.next/build-manifest.json'] {
errno: -13,
code: 'EACCES',
syscall: 'unlink',
path: '/usr/src/app/.next/build-manifest.json'
}
I still see build-manifest.json file in .next folder, but i don't know why this error is appear.Am i missing something and How can i fix it?

Dockerizing Nextjs

I need to publish my Next js project on a server. For that, by request of admin, I need to dockerize it (because SWC compiler is not available on the server).
I set up Docker Desktop, created Dockerfile (content below) and docker-compose.yml (content below)
Then I successfully ran "docker-compose build"
and then "docker-compose up" - after that website is successfully work on my localhost:3000
What is my next steps? What should I provide to admin? I can push those 2 files on Github, but I guess, it's not enough. I can see in my docker app, that it created image of 723.88 Mb. Maybe I need to sent this one? But how and where it located?
I'm a noob in Docker, any advice is highly welcomed.
My Dockerfile:
# 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 ./
RUN yarn 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 yarn build && yarn install --production --ignore-scripts --prefer-offline
# Production image, copy all the files and run next
FROM node:alpine AS runner
WORKDIR /app
RUN npm install --global pm2
ENV NODE_ENV production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# 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 --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
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.
ENV NEXT_TELEMETRY_DISABLED 1
# Run npm start script with PM2 when container starts
CMD [ "pm2-runtime", "npm", "--", "start" ]
My docker-compose.yml file:
version: '3'
services:
next:
build: ./frontend
image: dockerhubid/project-webui:latest
ports:
- '3000:3000'

Next JS DockerFile for Cloud Build in GCP

This is the recommended Dockerfile from the official documentation
# 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 yarn.lock ./
RUN yarn 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 yarn build && yarn install --production --ignore-scripts --prefer-offline
# Production image, copy all the files and run next
FROM node:alpine AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# 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 --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
USER nextjs
EXPOSE 3000
ENV PORT 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.
# ENV NEXT_TELEMETRY_DISABLED 1
CMD ["node_modules/.bin/next", "start"]
It takes about 8min to build right now, it was 6 plus something at the beginning.
I'm deploying it into GCP using a Cloud Build pipeline which trigger is a push to a given branch and just wondering the reason to add three different runs of node:alpine.
At the end it will be triggered anytime some push happen in the given branch so it will need to re-create everything.
Shouldn't something like this work better for those building it outside Vercel or similar?
FROM node:14.17-alpine AS deps
RUN apk update
RUN apk add --no-cache libc6-compat
WORKDIR /app
ENV NODE_ENV production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
COPY package.json ./
RUN yarn build && yarn install --production
COPY /app/next.config.js ./
COPY /app/public ./public
COPY --chown=nextjs:nodejs /app/.next ./.next
COPY /app/node_modules ./node_modules
COPY /app/package.json ./package.json
RUN npx next telemetry disable
USER nextjs
EXPOSE 3000
CMD ["yarn", "start"]
It's not working and I'm trying to make it work like that to see results but in the meantime I would like to get help on figuring out if there's any issue in my mental workaround about that, I'm not an expert on that so I may be missing something.
The reason it's faster is because at the point where you do your yarn build, the only file you've copied into the image is package.json. The original Dockerfile has copied everything, so it can actually build your app.
As for the multi-stage nature of the first Dockerfile, I think its main advantage is that the final image only contains the output of the build. With a single-stage build like the latter file, the image will contain both the source files and the built files.

How can I debug dist/ is not generating on Docker Cloud Build?

I’m trying to automate build on dockercloud to build a docker container for my front-end.
I have
web.dockerfile
### STAGE 1: Build ###
FROM node:9.3.0-alpine as builder
COPY package.json ./
RUN npm set progress=false && npm config set depth 0 && npm cache clean --force
## Storing node modules on a separate layer will prevent unnecessary npm installs at each build
RUN npm i
RUN mkdir /web
RUN cp -R ./node_modules ./web
WORKDIR /web
COPY . .
## Build the angular app in production mode and store the artifacts in dist folder
RUN $(npm bin)/ng build --prod --build-optimizer
### STAGE 2: Setup ###
FROM nginx:1.13.8-alpine
COPY nginx.conf /etc/nginx/nginx.conf
COPY site.conf /etc/nginx/conf.d/default.conf
RUN rm -rf /usr/share/nginx/html/*
COPY dist /usr/share/nginx/html/
RUN touch /var/run/nginx.pid && \
chown -R nginx:nginx /var/run/nginx.pid && \
chown -R nginx:nginx /var/cache/nginx && \
chown -R nginx:nginx /usr/share/nginx/html
USER nginx
as you see I already did this line :
RUN $(npm bin)/ng build --prod --build-optimizer
Which it should generate the dist/ folder for me.
I got
This long logs in my docker-cloud
What I don't understand is, it is working fine, when I used that Dockerfile locally.
Should I look into my webpack settings or my Dockerfile syntax ?
Use the --from argument to COPY to set the source location to a previous build stage.
COPY --from=builder /web/dist /usr/share/nginx/html/
For your local build you probably have a dist/ folder for your local development which is then included in the build context sent to Docker. The local copy is what ends up in the image.

Resources