Docker webpack doesn't create bundle in right place - node.js

I am using Docker to run my React universal application using docker-compose as an control tool. Unfortunately, after webpack successfully creates the bundles my pm2 inside docker can't find the script and my container exits with error.
What is the best way to debug this or solve the problem?
Dockerfile
FROM node:erbium
WORKDIR /app
RUN npm install pm2 -g
RUN npm install bower -g
COPY package*.json /app/
RUN npm install
COPY . /app/
RUN bower install
RUN npm run build
EXPOSE 8080
CMD ["pm2-runtime", "start", "ecosystem.config.js", "--env", "production"]
docker-compoe service
client:
container_name: client_folder
image: client_image
build: ./finstead-client
volumes:
- ./client_folder:/app
- /app/node_modules
restart: "always"
ports:
- "4000:8080"
the application is inside folder client_folder and I use volumes to attach my files to the docker container. But In my opinion it doesn't attach volumes after buildtime and on runtime it can't find the files.
I would appreciate a lot if you could give me advice or help me find out the root of the problem.

Related

How to write Dockerfile to serve Angular app and Node server

My Angular app runs fine locally but I haven't figured out how to do the same with a Docker image. Outside of Docker, the UI runs on port 4200 with ng serve and the API serves data from 8080 with node server.js.
My Dockerfile is set up so it can get the Node server running and available on 8080, but the Angular UI won't run. I've tried several options but right now I have:
FROM node:14.17.3
COPY package*.json ./
EXPOSE 4200 8080
RUN npm install -g #angular/cli
RUN npm install --only=production
COPY . ./
RUN ng serve
CMD ["node", "server.js"]
It fails on ng serve with the error: The serve command requires to be run in an Angular project, but a project definition could not be found. I do have an angular.json file in the root. I'm not sure what I am missing. I read that ng serve shouldn't be used in this situation but the alternatives I've seen haven't made a difference.
Workspace:
EDIT 8/10/21: Based on the answers here and a bunch of research, this will display the UI with nginx:
FROM node:12.16.1-alpine as build
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
# RUN npm install -g #angular/cli
# RUN npm run build --prod
FROM nginx:1.15.8-alpine
COPY --from=build /usr/src/app/dist /usr/share/nginx/html
# CMD ["node", "server.js"]
However, the npm run build step fails because ng is not found despite installing #angular/cli. I have to run this manually to build the dist folder. And I can't run node server.js alongside this. It seems I can only get the front end or back end, not both.
Use below command at the end to run ng serve with host 0.0.0.0 which means it listens to all interfaces.
CMD ["ng","serve","--host", "0.0.0.0"]
But I would suggest using ngInx.
Steps to follow:
Create a docker file under the root of your project, and add the below code. It takes care of: downloading dependencies, building angular project, and deploy it to ngInx server.
#Download Node Alpine image
FROM node:12.16.1-alpine As build
#Setup the working directory
WORKDIR /usr/src/ng-app
#Copy package.json
COPY package.json package-lock.json ./
#Install dependencies
RUN npm install
#Copy other files and folder to working directory
COPY . .
#Build Angular application in PROD mode
RUN npm run build
#Download NGINX Image
FROM nginx:1.15.8-alpine
#Copy built angular files to NGINX HTML folder
COPY --from=build /usr/src/ng-app/dist/pokemon-app/ /usr/share/nginx/html
Build docker image:
docker build -t my-ng-app .
Spinning the docker container with below command expose your app at port 80
docker run -dp 3000:80 my-ng-app
Check out my article on this - https://askudhay.com/how-to-dockerize-an-angular-application, and please let me know if you still have any questions.
I figured out a solution that will run the full application. Most answers here focus on running the front end (the nginx suggestion was helpful). It seemed a Docker container could enable the UI or server but not both. I came across Docker Compose, which will run the front and back ends in separate images. My solution:
Dockerfile.ui
# Define node version
FROM node:12.16.1-alpine as build
# Define container directory
WORKDIR /usr/src/app
# Copy package*.json for npm install
COPY package*.json ./
# Run npm clean install, including dev dependencies for #angular-devkit
RUN npm ci
# Run npm install #angular/cli
RUN npm install -g #angular/cli
# Copy all files
COPY . .
# Run ng build through npm to create dist folder
RUN npm run build --prod
# Define nginx for front-end server
FROM nginx:1.15.8-alpine
# Copy dist from ng build to nginx html folder
COPY --from=build /usr/src/app/dist /usr/share/nginx/html
Dockerfile.server
# Define node version
FROM node:12.16.1-alpine
# Define container directory
WORKDIR /usr/src/app
# Copy package*.json for npm install
COPY package*.json ./
# Run npm clean install, prod dependencies only
RUN npm ci --only=production
# Copy all files
COPY . .
# Expose port 8080 for server
EXPOSE 8080
# Run "node server/run.js"
CMD ["node", "server/run.js"]
docker-compose.yml
version: '3'
services:
server:
build:
context: ./
dockerfile: Dockerfile.server
container_name: server
ports:
- 8080:8080
ui:
build:
context: ./
dockerfile: Dockerfile.ui
container_name: ui
ports:
- 4200:80
links:
- server
docker-compose up will build out an image for server and UI and deploy concurrently. I also resolved the ng not found errors by installing dev dependencies, particularly #angular-devkit/build-angular.
This tutorial helped me figure out Docker Compose: https://wkrzywiec.medium.com/how-to-run-database-backend-and-frontend-in-a-single-click-with-docker-compose-4bcda66f6de
I think updating this line
COPY . ./
with
COPY . ./app
should solve that error. It appears that the node "volume" is in that folder.
Otherwise setting the workdir also seems like a solution:
FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
...
Source: https://nodejs.org/en/docs/guides/nodejs-docker-webapp/

npm install hangs when using Docker to install libraries

Here's the deal. I'm trying to setup my environment to develop a react native application using expo. Since I'm working on a Windows OS, I'd like to setup using Docker and docker-compose.
First I build my image, installing expo-cli from a node image. Then I use docker-compose to specify a volume and ports to expose.
Since at this point I have to project initialized, what I do is, use docker-compose run to initialize my project and then the same to install specific project libraries. But when I do, at some random point, the installation hangs.
Now it seems like it's docker related, but I'm not sure what I'm doing wrong.
Dockerfile
FROM node:12.18.3
ENV PATH /app/node_modules/.bin:$PATH
RUN npm install --no-save -g expo-cli
RUN mkdir /app
WORKDIR /app
RUN adduser user
USER user
docker-compose.yml
version: "3"
services:
app:
build:
context: .
expose:
- "19000"
- "19001"
- "19002"
- "19003"
ports:
- "19000:19000"
- "19000:19001"
- "19000:19002"
- "19000:19003"
volumes:
- ./app:/app
command: sh -c "cd myapp && npm start"
Assuming my app is called myapp
Here are the commands I use to install additional npm packages and initialize project:
docker-compose run --rm app sh -c "npx expo-cli init myapp"
docker-compose run --rm app sh -c "cd /app/myapp && npm install react-navigation --verbose"
I see that several things happen, but it always hangs somewhere and never at the same place everytime I start from skratch.
Please help!

docker-compose for a node project getting cannot find package.json on windows

I'm trying to get docker-compose working on my Windows 8 box. I have the following docker-compose file
version: '3'
services:
testweb:
build: .
command: npm run install
volumes:
- .:/usr/app/
working_dir: /app
ports:
- "3000:3000"
However when I run this using docker-compose I get an error saying cannot find package.json. I know this is something to do with how the paths are mapped. So I moved my folder to c:\users and tried with the same issue. I then moved to c:\users\ and tried, ended up with the same issue. The mapping on my virtual box is as follows
Does anyone know how to fix this?
Attached is my Dockerfile
FROM node:7.7.2-alpine
WORKDIR /usr/app
RUN apk update && apk add postgresql
COPY package.json .
RUN npm install --quiet
COPY . .
It may be because you set the working directory to /app in your docker-compose file, but your package.json is in /usr/app. So the container runs npm run install from the wrong directory.
For a docker container to stay up you need to have a running process. In this case its the command npm start which will keep running as long as the container is up. So you need to have a cmd or Entrypoint that will start a running process. Please try something like this. Let me know if you have any questions
FROM node:7.7.2-alpine
WORKDIR /usr/app
RUN apk update && apk add postgresql
COPY package.json .
RUN npm install --quiet
COPY . .
EXPOSE 8080
CMD [ "npm", "start" ]
Put file docker-compose.yml in project/app directory.
Then run docker compose up in project/app directory.
reference: https://forums.docker.com/t/use-docker-compose-in-get-started-tutorial-solved/129415

Access node modules in typescript while using docker & docker compose

I'm trying to create a docker image that is hosting a NodeJS project during develop. It simply executes the NodeJS application with nodemon so it restarts every time when I make changes.
I also use TypeScript to develop the application. TypeScript must have access to a installed #types module. However the mounted volume that should show the node_modules folder is empty. So TypeScript cannot find the modules and cannot compile. My IDE is also complaining (obviously)
Is there a way to make the node_modules visible for TypeScript?
This is my Dockerfile:
FROM node:alpine
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
COPY package.json .
RUN npm install
# Bundle app source
COPY . .
# Run app
CMD [ "npm", "start" ]
This is my docker-compose.yml:
version: "3"
services:
server:
build: .
environment:
- NODE_ENV=development
command: npm run debug
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
ports:
- "8080:8080"
- "9229:9229"
You should use a separate folder for your node_modules and then set that folder in NODE_PATH environment
FROM node:alpine
# Create app directory
ENV NODE_PATH /usr/node_modules
WORKDIR /usr/node_modules
# Install app dependencies
COPY package.json .
RUN npm install
WORKDIR /usr/src/app
# Bundle app source
COPY . .
# Run app
CMD [ "npm", "start" ]
This way your code would be separate and the node_modules will there in image itself. Anytime you add a new module you will rebuild the image, else development can go fine withe mounted volume

Docker Compose gulp is not found in $PATH

I have just started learning docker-compose and I am using a nodejs image. I want to install gulp to create some tasks and have one of them working on the background.
When I run: docker-compose run --rm -d server gulp watch-less
I get this error: ERROR: oci runtime error: container_linux.go:247: starting container process caused "exec: \"gulp\": executable file not found in $PATH"
Here are my file:
# Dockerfile
FROM node:6.10.2
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app
RUN npm install --quiet
COPY . /usr/src/app
CMD ["npm", "start"]
# docker-compose.yml
version: "2"
services:
server:
build: .
ports:
- "5000:5000"
volumes:
- ./:/usr/src/app
I also have a .dockerignore to ignore the node_modules folder and the npm-debug.log
EDIT:
When I run docker-compose run --rm server npm install package-name I don't have any problem and the package is installed.
Try adding gulp install in Dockerfile:
# Dockerfile
FROM node:6.10.2
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
RUN npm install -g gulp
COPY package.json /usr/src/app
RUN npm install --quiet
COPY . /usr/src/app
CMD ["npm", "start"]
I have found a solution that works but maybe is not the best solution. I have created an script that runs a gulp task on the package.json and if I run:
docker-compose run --rm server npm run gulp_task it works and does what it has to do.
I find that just referencing gulp via
./node_modules/.bin/gulp
instead of directly works fine. ./node_modules/.bin isn't in the path by default. Another option would be to add that dir to the PATH.

Resources