How can I work with NodeJS and Docker Compose with volumes? - node.js

I'm trying to make it work nodejs with docker-compose and volumes, I want to edit my code, that's why I should use volumes.
when I do not put volumes in the docker-compose.yml file, it work!. But with volumes no work.
Any idea?
This is my docker-compose.yml:
version: "3.2"
services:
node:
container_name: node_app
build:
context: ./
dockerfile: dockerfiles/Dockerfile
user: "node"
environment:
- NODE_ENV=production
volumes:
- .:/home/app
ports:
- "3000:3000"
This is my Dockerfile:
FROM node:carbon-stretch
WORKDIR /home/app
COPY package*.json ./
RUN npm i express -S
COPY . .
EXPOSE 3000
CMD [ "npm", "start" ]
This is my package.json:
{
"name": "docker_web_app",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "First Last <test#gmail.com>",
"main": "server.js",
"scripts": {
"start": "node server.js"
}
}
This is my server.js:
'use strict'
const express = require('express')
// Constants
const PORT = 3000
const HOST = '0.0.0.0'
// App
const app = express()
app.get('/', (req, res) => {
res.send('Hello world\n')
});
app.listen(PORT, HOST)
console.log(`Running on http://${HOST}:${PORT}`)
Thanks!

The problem is that when you mount the folder . onto /home/app, all the content in /home/app gets overshadowed by the content of . on the host. This effectively removes the things introduced by RUN npm i express -S
To solve this you need to isolate the code that you want to edit into a separate folder (if that is already not the case)
volumes:
- ./code:/home/app/code

Try to parse your docker-compose file to the valid yaml format, you can try again:
version: "3.2"
services:
node:
container_name: node_app
build:
context: ./
dockerfile: dockerfiles/Dockerfile
user: "node"
environment:
- NODE_ENV=production
volumes:
- .:/home/app
ports:
- "3000:3000"

Related

Dockerizing React-Express- MongoDB Atlas App with Docker-Compose and Proxy

I have a react-express app that connects to MongoDB Atlas and is deployed to Google App Engine. Currently, the client folder is stored inside the backend folder. I manually build the React client app with npm run build, then use gcloud app deploy to push the entire backend app and the built React files to GAE, where it is connected to a custom domain. I am looking to dockerize the app, but am running into problems with getting my backend up and running. Before Docker, I was using express static middleware to serve the React files, and had a setupProxy.js file in the client directory that I used to redirect api requests.
My express app middleware:
if (process.env.NODE_ENV === 'production') {
app.use(express.static(path.join(__dirname, '/../../client/build')));
}
if (process.env.NODE_ENV === 'production') {
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, '/../../client/build/index.html'));
});
}
My client Dockerfile:
FROM node:14-slim
WORKDIR /usr/src/app
COPY ./package.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD [ "npm", "start"]
My backend Dockerfile:
FROM node:14-slim
WORKDIR /usr/src/app
COPY ./package.json ./
RUN npm install
COPY . .
EXPOSE 5000
CMD [ "npm", "start"]
docker-compose.yml
version: '3.4'
services:
backend:
image: backend
build:
context: backend
dockerfile: ./Dockerfile
environment:
NODE_ENV: production
ports:
- 5000:5000
networks:
- mern-app
client:
image: client
build:
context: client
dockerfile: ./Dockerfile
stdin_open: true
environment:
NODE_ENV: production
ports:
- 3000:3000
networks:
- mern-app
depends_on:
- backend
networks:
mern-app:
driver: bridge
I'm hoping that someone can provide some insight/assistance regarding how to effectively connect my React and Express apps inside a container using Docker Compose so that I can make calls to my API server. Thanks in advance!

docker-compose for attaching node.js debugger from VS Code to a node process in WSL docker

I'm really doing the best as I can but I don't know what am I doing wrong.
I have this existing project that can be started and debugged both on Win10 and Linux containers. But I want to be able to attach the debugger in WSL container on Win10 and I'm really loosing my patience now.
So, I have VS Code on Win10 and WSL2 installed. I have Remote-WSL extension (also Remote-Containers, but can't get that to work either, so let's skip that for the time being). And I would prefer to keep Dockerfile as-is, if possible.
When I try to attach to node debugger by running "Docker: Attach to Node" configuration, I get the following error:
Error processing attach: Error: Could not connect to debug target at http://localhost:9229: Promise was canceled
at e (/home/ozren_admin/.vscode-server/bin/3dd905126b34dcd4de81fa624eb3a8cbe7485f13/extensions/ms-vscode.js-debug/src/extension.js:1:92915)
Here are my files...
/docker-compose.yml
version: '3'
services:
web:
build:
context: .
dockerfile: ./Dockerfile
env_file: ./myapp.env
depends_on:
- db
volumes:
- "./app:/src/app"
ports:
- "5000:4000"
- "9229:9229"
expose:
- 9229
links:
- db:myapp_mobile_apis_db
db:
image: mysql:5.7
container_name: myapp_mobile_apis_db
restart: always
environment:
# see: https://hub.docker.com/_/mysql
MYSQL_DATABASE: 'myapp'
MYSQL_USER: 'myapp_user'
MYSQL_PASSWORD: 'myapp_user_pwd'
MYSQL_ROOT_PASSWORD: '****************'
ports:
- '3306:3306'
expose:
- '3306'
volumes:
- my-db:/mnt/c/Projects/MyApp/Local/data/
volumes:
my-db:
/Dockerfile
FROM node:alpine
RUN mkdir /src
WORKDIR /src
COPY app/ /src/app/
COPY gulpfile.js /src/
COPY .sequelizerc /src/
ADD app/package.json /src/package.json
RUN npm install --global gulp-cli
RUN npm install
COPY myapp.env /src/.env
EXPOSE 80
CMD gulp prod
/.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Docker: Attach to Node",
"port": 9229,
"address": "localhost",
"localRoot": "${workspaceRoot}/app",
"remoteRoot": "/src/app",
"protocol": "inspector"
}
]
}
When I add the following to docker.compose.yml
command: sh -c "npm run start:debug:docker"
I get this on docker-compose up
web_1 | npm ERR! missing script: start:debug:docker
I tried googling for additional info and the idea is probably to run node in the debugging mode, but I obviously can't get it to work.
Any help appreciated!
There was this:
/gulpfile.js
'use strict';
let gulp = require('gulp');
let nodemon = require('gulp-nodemon');
let started = !1;
let paths = {
js: [
'**/*.js',
'!node_modules'
]
};
gulp.task('prod', (e) => {
nodemon({
script: './app/app.js',
ext: 'js',
watch: paths.js,
ignore: ['./app/node_modules/**']
}).on('start', () => {
started || (started = !0, e());
});
});
And when I added this line to nodemon options to enable debug over inspect:
nodeArgs: ['--inspect=0.0.0.0:9229'],
...all of a sudden the debugger started working.
DISCLAIMER: I started my journey to Node.js ecosystem from .Net world, where stuff like remote debugging and other basics usually aren't hidden behind... packages, but eh. Live and learn.

Nodejs and React inside docker containers

I am trying to run Node/React project inside Docker containers. I have a NodeJS server for the API's and the client app. I also have concurrently installed and everything works fine when running npm run dev.
This issue is when I run the server and app via a docker-compose.yml file I get the following error from the client:
client | [HPM] Error occurred while trying to proxy request /api/current_user from localhost:3000 to http://localhost:5000 (ECONNREFUSED) (https://nodejs.org/api/errors.html#errors_common_system_errors)
Here is the docker-compose.yml
version: "3"
services:
frontend:
container_name: client
build:
context: ./client
dockerfile: Dockerfile
image: client
ports:
- "3000:3000"
volumes:
- ./client:/usr/src/app
networks:
- local
backend:
container_name: server
build:
context: ./
dockerfile: Dockerfile
image: server
ports:
- "5000:5000"
depends_on:
- frontend
volumes:
- ./:/usr/src/app
networks:
- local
networks:
local:
driver: bridge
Server Dockerfile
FROM node:lts-slim
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
EXPOSE 5000
# You can change this
CMD [ "npm", "run", "dev" ]
Client Dockerfile
FROM node:lts-slim
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
EXPOSE 3000
CMD [ "npm", "start" ]
I am using "http-proxy-middleware": "^0.21.0" so my setupProxy.js is
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(proxy('/auth/google', { target: 'http://localhost:5000' }));
app.use(proxy('/api/**', { target: 'http://localhost:5000' }));
};
You should use container_name instead of localhost
app.use(proxy('/auth/google', { target: 'http://localhost:5000' }));
app.use(proxy('/api/**', { target: 'http://localhost:5000' }));
You can also check these details by inspecting your network using following command:-
docker inspect <network_name>
It will show all the connected containers to the network, also the host names created for those containers.
NOTE : Host names are created based on container_names otherwise based
on service names.

WebStorm 2018.1: I am not able to hit breakpoints running remote debugging typescript from docker container

I am using the docker integration tool to run docker-compose to start two containers, one for node and one for mongodb.
Here is the docker-compose.yml file:
version: '2.1'
services:
mongo:
container_name: "app_mongo"
hostname: "mongo"
tty: true
image: mongo:latest
environment:
- MONGO_DATA_DIR=/data/db
- MONGO_LOG_DIR=/dev/null
- MONGO_INITDB_DATABASE=***********
- MONGO_INITDB_ROOT_USERNAME=************
- MONGO_INITDB_ROOT_PASSWORD=********************
volumes:
- /data/db:/data/db
ports:
- 27017:27017
command: "mongod --smallfiles --auth"
networks:
- my-app-network
group:
container_name: "app_api1"
hostname: "api1"
build:
context: .
dockerfile: api1.dev.yml
entrypoint: ["npm", "run", "debug"]
volumes:
- ".:/home/app"
ports:
- 3000:3000
- 56745:56745
depends_on:
- "mongo"
networks:
- my-app-network
networks:
my-app-network:
driver: bridge
Here is the api1.dev.yml file:
FROM node:latest
ADD package.json /tmp/package.json
RUN cd /tmp && npm install --production && npm install -g nodemon
RUN mkdir -p /home/app && cp -a /tmp/node_modules /home/app/ && mkdir -p /home/app/dist
ADD package.json /home/app/package.json
ADD .env /home/app/.env
WORKDIR /home/app
Here is the script entry in package.json:
"scripts": {
"debug": "nodemon --inspect=56745 --require ts-node/register app/app.ts"
// "debug": "nodemon -L --inspect=56745 dist/myapp/app.js"
}
I also added a new "Attach to Node.js/Chrome" item to attach to the debugging port for node.
I run the docker-compose file followed by debugging the "Attach to Node.js/Chrome" item after node is up and listening.
When I try to hit a breakpoint in a .ts file, nothing is happening. I am seeing the endpoint is called.
What are the steps involved in debugging a typescript app from docker and what am I doing wrong?
Where can I find a good tutorial that walks through how to debug typecript for a node.js app hosted inside of a docker container?
An answer was finally provided to me. Ultimately, I had to change the debug script from "debug": "nodemon -L --inspect=56745 dist/myapp/app.js" to "nodemon -L --inspect=0.0.0.0:56745 dist/myapp/app.js".

Why is my docker node container exiting

I'm trying to run a node container with docker-compose -
services:
node:
build:
context: nodejs/
ports:
- "3000:3000"
volumes:
- ../nodejs:/usr/src/app
working_dir: '/usr/src/app'
My docker file
FROM node:6.10
EXPOSE 3000
The problem is it exits immediately -
$ docker-compose up
Starting docker_node_1
Attaching to docker_node_1
docker_node_1 exited with code 0
And there's nothing in the logs - docker logs docker_node_1 returns nothing.
There's a package.json referencing the main script -
{
...
"main": "server.js",
...
}
And my main script is just a simple express server -
const express = require('express');
const app = express();
const port = 3000;
app.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err);
}
console.log(`server is listening on ${port}`);
});
I guess I'm missing something obvious but I can't see what it is...
It's missing specifying the docker command. That is the key concept that represents the container: sort of isolated process (process = the command, your program)
You can do it in Dockerfile:
CMD npm start
Or in docker-compose.yml:
services:
node:
command: npm start
build:
context: nodejs/
ports:
- "3000:3000"
volumes:
- ../nodejs:/usr/src/app
working_dir: '/usr/src/app'
Both approaches are equivalent. But edit it as your needs (npm run, npm run build, etc)

Resources