I am trying to setup docker with a nodejs/react env for local dev purposes, this is Dockerfile for client:
# Pull Docker Hub base image
FROM node:14.16.0-alpine3.10
# Set working directory
WORKDIR /usr/app
# Install app dependencies
COPY package*.json ./
RUN npm install -qy
# Copy app to container
COPY . .
# Run the "dev" script in package.json
CMD ["npm", "start"]
this is Dockerfile for server:
# Pull Docker Hub base image
FROM node:14.16.0-alpine3.10
# Set working directory
WORKDIR /usr/app
# Install app dependencies
COPY package*.json ./
RUN npm install -qyg [email protected]
RUN npm install -qy
# Copy app to container
COPY . .
# Run the "dev" script in package.json
CMD ["npm", "start"]
and this is docker-compose.yml:
version: "3"
services:
client:
build:
context: ./client
dockerfile: Dockerfile
ports:
- "3000:3000"
networks:
- picstack-network
volumes:
- ./client/src:/usr/app/src
- ./client/public:/usr/app/public
depends_on:
- server
environment:
- REACT_APP_SERVER=http://localhost:5000
- CHOKIDAR_USEPOLLING=true
command: npm start
stdin_open: true
tty: true
server:
build:
context: ./server
dockerfile: Dockerfile
ports:
- "5000:5000"
networks:
- picstack-network
volumes:
- ./server/src:/usr/app/src
depends_on:
- db
environment:
- MONGO_URL=mongodb://db:27017
- CLIENT=http://localhost:3000
command: nodemon -L app.js
db:
image: mongo:3.6.19-xenial
ports:
- "27017:27017"
networks:
- picstack-network
volumes:
- mongo-data:/data/db
networks:
picstack-network:
driver: bridge
volumes:
mongo-data:
driver: local
and here's my entry point app.js:
var createError = require('http-errors');
var express = require('express');
const bodyParser = require("body-parser");
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
const app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
if I run docker-compose up, I can see the react index at http://localhost:3000, but I can't see the express index that is supposed to be at http://localhost:5000. docker ps shows all 3 containers are running and the log is free from errors.
however, if I stop docker and I run npm start locally, I can actually see the express index at http://localhost:5000.
So I suspect that when I run docker, http://localhost:5000 is only accessible from the client container, but I don't know how to verify it, and anyway I would like to be able to see the api from the outside when docker is running, so I can use Postman or similar. What should I change to achieve this?
I am really a newby with docker and express so any other suggestion to improve this configuration is welcome.
CodePudding user response:
As per discussion, you are not calling listen, in app.js. Therefore, your server will not start if you set the command in the compose file to command: nodemon -L app.js
I suggest to call app.listen in the app.js file.
app.listen(port, '0.0.0.0')
Then you can use nodemon again, as command.
nodemon -L app.js
By default nodemon monitors the current working directory.