How to change permission to files in Dockerfile when running in OpenShift - docker

As I have discovered, OpenShift runs all containers as non-root, so if I have to write to a file inside a container, I get an Error: EACCES: permission denied, open 'database.db~'. This is my Dockerfile:
FROM node:9-alpine
WORKDIR /app
COPY package.json .
COPY package-lock.json .
COPY database.db .
RUN chmod 666 database.db <-- This doesn't work
RUN npm install
COPY index.js .
EXPOSE 8080
CMD npm start
But chmod doesn't seem to work. I don't know why.

Related

Docker + Sveltekit, cant access localhost:3000

After building I start the image and see in the terminal:
*Executing task: docker run --rm -it -p 3000:3000/tcp bamdock:latest
Listening on 0.0.0.0:3000*
However when trying to reach http://localhost:3000/ in browser I see:
*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.*
This is my Dockerfile:
FROM node:19 as builder
RUN npm install -g pnpm
WORKDIR /usr/src/app
COPY package*.json ./
RUN pnpm install
COPY prisma ./prisma/
COPY .env ./
RUN npx prisma generate
COPY . .
RUN pnpm run build
FROM node:19-alpine3.16
WORKDIR /app
COPY --from=builder /usr/src/app/build .
COPY --from=builder /usr/src/app/package.json .
COPY --from=builder /usr/src/app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "index.js"]
Any ideas what I'm missing?
My first time trying to get Docker working ...

Understanding Dockerfile syntax?

I am learning Docker and looking at this Dockerfile example for React application
FROM node:alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i
CMD ["npm", "run", "start"]
To me it's saying
Grab image node:alpine from docker library
create WORKDIR called /app
copy the package.json file to the /app dir
copy the lock file also to /app dir
I don't understand what COPY ./ ./ is doing?
command npm install
then CMD npm run start
Am I interpreting this language correctly? Can anyone give me insight of what is actually going on?
Docker is an open-source containerization platform. Here we run our application in the container(which is managed by Docker Engine). Dockerfile contains all the commands. Also, you can say in Dockerfile that we write all the procedures to make a container runnable.
Coming back to your point...
Here COPY ./ ./ meaning is, COPY <source_path> <destination_path> and <source_path> is the path in your host machine and <destination_path> is path in your container machine
I will try to simplify the other contents in your Dockerfile...
FROM node:alpine : Pull image node:alpine from Docker Hub. Here node is the package name and alpine is the Linux distribution with very minimal and required packages.
WORKDIR /app: (Work Directory) In container you're setting up your WORKDIR as /app folder.
COPY package.json ./: COPY the package.json(host machine) file to ./(current directory) in your container
And other COPY will also work in the same way.
RUN npm i: RUN command npm i in container
CMD ["npm", "run", "start"]: CMD command will executed(npm run start) when Docker Container will start.
For more detail please see Dockerfile Documentation.

Docker EACCES permission denied mkdir

My friend gave me a project with a dockerfile which seems to work just fine for him but I get a permission error.
FROM node:alpine
RUN mkdir -p /usr/src/node-app && chown -R node:node /usr/src/node-app
WORKDIR /usr/src/node-app
COPY package.json yarn.lock ./
COPY ./api/package.json ./api/
COPY ./iso/package.json ./iso/
USER node
RUN yarn install --pure-lockfile
COPY --chown=node:node . .
EXPOSE 3000
error An unexpected error occurred: "EACCES: permission denied, mkdir '/usr/src/node-app/node_modules/<project_name>/api/node_modules'".
Could it be a docker version error?
COPY normally copies things into the image owned by root, and it will create directories inside the image if they don't exist. In particular, when you COPY ./api/package.json ./api/, it creates the api subdirectory owned by root, and when you later try to run yarn install, it can't create the node_modules subdirectory because you've switched users.
I'd recommend copying files into the container and running the build process as root. Don't chown anything; leave all of these files owned by root. Switch to an alternate USER only at the very end of the Dockerfile, where you declare the CMD. This means that the non-root user running the container won't be able to modify the code or libraries in the container, intentionally or otherwise, which is a generally good security practice.
FROM node:alpine
# Don't RUN mkdir; WORKDIR creates the directory if it doesn't exist
WORKDIR /usr/src/node-app
# All of these files and directories are owned by root
COPY package.json yarn.lock ./
COPY ./api/package.json ./api/
COPY ./iso/package.json ./iso/
# Run this installation command still as root
RUN yarn install --pure-lockfile
# Copy in the rest of the application, still as root
COPY . .
# RUN yarn build
# Declare how to run the container -- _now_ switch to a non-root user
EXPOSE 3000
USER node
CMD yarn start

Dockerfile copy from build failing for create-react-app

I have a react app I'm trying to dockerize for production. It was based off create-react-app. To run the app locally, I am in the app's root folder and I run npm start. This works. I built the app with npm run build. Then I try to create the docker image with docker build . -t app-name. This is failing for not being able to find the folder I'm trying to copy the built app from (I think).
Here's what's in my Dockerfile:
FROM node:13.12.0-alpine as build
WORKDIR /src
ENV PATH /node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm install --silent
COPY . ./
RUN npm run build
FROM nginx:alpine
COPY --from=build build /usr/share/nginx/html
EXPOSE 80
CMD ["npm", "start"]
I'm pretty sure I've got something wrong on the COPY --from line.
The app structure is like this, if it matters
-app-name (folder)
-src (folder)
-build (folder)
-dockerfile
-other stuff, but I think I listed what matters
The error I get is failed to compute cache key: "/build" not found: not found
I'm running my commands in windows powershell.
What do I need to change?
You were almost correct,
Just that the path where the build folder is generated is at /src/build and not at /build.
and hence the error you see,
and why the /src coming?
it's due to the WORKDIR /src.
and hence this should work: COPY --from=build /src/build /usr/share/nginx/html
besides, since you are using nginx server to serve the build static files,
you don't need to or you cant run npm start with CMD.
instead, just leave it, and you can access the application at port 80.
so the possible working Dockerfile would be:
FROM node:13.12.0-alpine as build
WORKDIR /src
ENV PATH /node_modules/.bin:$PATH
COPY package*.json ./
RUN npm install --silent
COPY . ./
RUN npm run build
FROM nginx:alpine
COPY --from=build /src/build /usr/share/nginx/html
EXPOSE 80
This is in accordance with the Dockerfile in the above question,
in some specific cases, advanced configuration might be required.

How to avoid node_modules folder being deleted

I'm trying to create a Docker container to act as a test environment for my application. I am using the following Dockerfile:
FROM node:14.4.0-alpine
WORKDIR /test
COPY package*.json ./
RUN npm install .
CMD [ "npm", "test" ]
As you can see, it's pretty simple. I only want to install all dependencies but NOT copy the code, because I will run that container with the following command:
docker run -v `pwd`:/test -t <image-name>
But the problem is that node_modules directory is deleted when I mount the volume with -v. Any workaround to fix this?
When you bind mount test directory with $PWD, you container test directory will be overridden/mounted with $PWD. So you will not get your node_modules in test directory anymore.
To fix this issue you can use two options.
You can run npm install in separate directory like /node and mount your code in test directory and export node_path env like export NODE_PATH=/node/node_modules
then Dockerfile will be like:
FROM node:14.4.0-alpine
WORKDIR /node
COPY package*.json ./
RUN npm install .
WORKDIR /test
CMD [ "npm", "test" ]
Or you can write a entrypoint.sh script that will copy the node_modules folder to the test directory at the container runtime.
FROM node:14.4.0-alpine
WORKDIR /node
COPY package*.json ./
RUN npm install .
WORKDIR /test
COPY Entrypoint.sh ./
ENTRYPOINT ["Entrypoint.sh"]
and Entrypoint.sh is something like
#!/bin/bash
cp -r /node/node_modules /test/.
npm test
Approach 1
A workaround is you can do
CMD npm install && npm run dev
Approach 2
Have docker install node_modules on docker-compose build and run the app on docker-compose up.
Folder Structure
docker-compose.yml
version: '3.5'
services:
api:
container_name: /$CONTAINER_FOLDER
build: ./$LOCAL_FOLDER
hostname: api
volumes:
# map local to remote folder, exclude node_modules
- ./$LOCAL_FOLDER:/$CONTAINER_FOLDER
- /$CONTAINER_FOLDER/node_modules
expose:
- 88
Dockerfile
FROM node:14.4.0-alpine
WORKDIR /test
COPY ./package.json .
RUN npm install
# run command
CMD npm run dev

Resources