code-8
code-8

Reputation: 58790

NodeJS Express Docker Instance exited with code 0

Goal

I have 3 instances in my dockercompose.yml , I can only start 2 of my instances, and have a hard time starting my third one which my node express.


Project directory

.
├── Icon\r
├── angular
│   ├── Dockerfile
│   ├── README.md
│   ├── dist
│   │   ├── css
│   │   │   └── style.css
│   │   ├── img
│   │   │   ├── external.png
│   │   │   ├── favicon.png
│   │   │   ├── footer_logo.png
│   │   │   └── logo.png
│   │   ├── index.html
│   │   └── js
│   │       ├── bundle.js
│   │       └── vendor.js
│   ├── docs
│   │   ├── app
│   │   │   ├── api.js
│   │   │   ├── app.config.js
│   │   │   ├── app.module.js
│   │   │   └── guide.js
│   │   ├── build
│   │   │   ├── index.html
│   │   │   ├── partials
│   │   │   │   ├── api
│   │   │   │   │   ├── common
│   │   │   │   │   │   ├── directive
│   │   │   │   │   │   │   └── app.html
│   │   │   │   │   │   ├── directive.html
│   │   │   │   │   │   ├── type
│   │   │   │   │   │   │   ├── AppController.html
│   │   │   │   │   │   │   └── AppSidebarController.html
│   │   │   │   │   │   └── type.html
│   │   │   │   │   ├── common.html
│   │   │   │   │   ├── components.auth
│   │   │   │   │   │   ├── service
│   │   │   │   │   │   │   └── AuthService.html
│   │   │   │   │   │   └── service.html
│   │   │   │   │   ├── components.auth.html
│   │   │   │   │   ├── components.contact
│   │   │   │   │   │   ├── directive
│   │   │   │   │   │   │   └── lengthCheck.html
│   │   │   │   │   │   ├── directive.html
│   │   │   │   │   │   ├── service
│   │   │   │   │   │   │   └── ContactService.html
│   │   │   │   │   │   ├── service.html
│   │   │   │   │   │   ├── type
│   │   │   │   │   │   │   └── ContactEditController.html
│   │   │   │   │   │   └── type.html
│   │   │   │   │   ├── components.contact.html
│   │   │   │   │   └── components.html
│   │   │   │   ├── api.html
│   │   │   │   ├── guide
│   │   │   │   │   └── howTo.html
│   │   │   │   └── guide.html
│   │   │   └── src
│   │   │       ├── api-data.js
│   │   │       ├── api.js
│   │   │       ├── app.config.js
│   │   │       ├── app.module.js
│   │   │       ├── guide-data.js
│   │   │       └── guide.js
│   │   ├── config
│   │   │   ├── index.js
│   │   │   ├── processors
│   │   │   │   ├── api-data.js
│   │   │   │   ├── guide-data.js
│   │   │   │   └── index-page.js
│   │   │   └── templates
│   │   │       ├── constant-data.template.js
│   │   │       ├── content.template.html
│   │   │       ├── indexPage.template.html
│   │   │       └── module.template.html
│   │   └── content
│   │       ├── api
│   │       │   └── index.md
│   │       └── guide
│   │           ├── howTo.md
│   │           └── index.md
│   ├── files
│   │   ├── default.conf
│   │   └── nginx.conf
│   ├── gulpfile.babel.js
│   ├── karma.conf.js
│   ├── mocks
│   │   └── firebase.mock.js
│   ├── npm-shrinkwrap.json
│   ├── package.json
│   ├── src
│   │   ├── app
│   │   │   ├── common
│   │   │   │   ├── app-footer.component.js
│   │   │   │   ├── app-footer.html
│   │   │   │   ├── app-header.component.js
│   │   │   │   ├── app-header.html
│   │   │   │   ├── app-pagination.html
│   │   │   │   ├── app-pagination.js
│   │   │   │   ├── app-sidebar.component.js
│   │   │   │   ├── app-sidebar.html
│   │   │   │   ├── app.component.js
│   │   │   │   ├── app.html
│   │   │   │   ├── app.module.js
│   │   │   │   ├── app.spec.js
│   │   │   ├── components
│   │   │   │   ├── auth
│   │   │   │   │   ├── auth-form
│   │   │   │   │   │   ├── auth-form.component.js
│   │   │   │   │   │   ├── auth-form.controller.js
│   │   │   │   │   │   ├── auth-form.html
│   │   │   │   │   │   └── auth-form.spec.js
│   │   │   │   │   ├── auth.module.js
│   │   │   │   │   ├── auth.spec.js
│   │   │   │   │   └── login
│   │   │   │   │       ├── login.component.js
│   │   │   │   │       ├── login.controller.js
│   │   │   │   │       ├── login.html
│   │   │   │   │       └── login.spec.js
│   │   │   │   ├── components.module.js
│   │   │   │   └── dashboard
│   │   │   │       ├── access-point-map
│   │   │   │       │   ├── access-point-map.component.js
│   │   │   │       │   └── access-point-map.html
│   │   │   │       ├── account-stats
│   │   │   │       │   ├── account-stats.component.js
│   │   │   │       │   └── account-stats.html
│   │   │   │       ├── dashboard.component.js
│   │   │   │       └── dashboard.html
│   │   │   ├── root.component.js
│   │   │   ├── root.html
│   │   │   └── services
│   │   │       ├── account.service.js
│   │   │       ├── auth.service.js
│   │   │       └── services.module.js
│   │   ├── img
│   │   │   ├── external.png
│   │   │   ├── favicon.png
│   │   │   ├── footer_logo.png
│   │   │   └── logo.png
│   │   ├── index.html
│   │   └── sass
│   │       ├── base
│   │       │   ├── _buttons.scss
│   │       │   ├── _forms.scss
│   │       │   ├── _headings.scss
│   │       │   ├── _list-group.scss
│   │       │   ├── _main.scss
│   │       │   ├── _media.scss
│   │       │   ├── _mixins.scss
│   │       │   ├── _page-header.scss
│   │       │   ├── _scaffolding.scss
│   │       │   ├── _sections.scss
│   │       │   ├── _table.scss
│   │       │   └── _tabset.scss
│   │       ├── components
│   │       │   ├── _auth.scss
│   │       │   ├── _footer.scss
│   │       │   ├── _header.scss
│   │       │   ├── _panels.scss
│   │       │   ├── _root.scss
│   │       │   ├── _sidebar.scss
│   │       │   └── _tablet.scss
│   │       ├── layout
│   │       │   ├── _loading.scss
│   │       │   └── _smb.scss
│   │       ├── style.scss
│   │       ├── utils
│   │       │   ├── _colors.scss
│   │       │   └── _typography.scss
│   │       └── vendors
│   │           ├── _bootstrap.scss
│   │           ├── _colorpicker.scss
│   │           ├── _fontawesome.scss
│   │           └── _rzslider.scss
│   └── templates.js
├── docker-compose.yml
└── express
    ├── Dockerfile
    ├── LICENSE
    ├── README.md
    ├── bin
    │   └── index.js
    ├── npm-debug.log
    ├── npm-shrinkwrap.json
    ├── package.json
    └── server
        ├── app.js
        ├── config
        │   └── config.json
        ├── controllers
        │   ├── accounts.js
        │   ├── auth.js
        │   ├── index.js
        │   ├── todoitems.js
        │   └── todos.js
        ├── migrations
        │   ├── 20160717103305-create-todo.js
        │   └── 20160717104733-create-todo-item.js
        ├── models
        │   ├── index.js
        │   ├── todo.js
        │   └── todoitem.js
        ├── routes
        │   └── index.js
        └── services
            ├── account.js
            ├── cpe.js
            ├── device.js
            └── index.js

59 directories, 166 files

Back-end

Dockerfile

# Create image based on the official Node 6 image from the dockerhub
FROM node:6

RUN useradd --user-group --create-home --shell /bin/false nodejs

# Create a directory where our app will be placed
RUN mkdir -p /usr/src/app

# Change directory so that our commands run inside this new directory
WORKDIR /usr/src/app

# Copy dependency definitions
COPY package.json /usr/src/app

# Install dependecies
RUN npm install

# Get all the code needed to run the app
COPY . /usr/src/app

# Expose the port the app runs in
EXPOSE 3000

# Serve the app
CMD ["node", "server/app.js"]

Do I have any bug in this file above according to my file structure ?


Front-end

Dockerfile

FROM alpine:3.6

RUN apk add --update nginx && rm -rf /var/cache/apk/*
RUN mkdir -p /tmp/nginx/client-body

COPY files/nginx.conf /etc/nginx/nginx.conf
COPY files/default.conf /etc/nginx/conf.d/default.conf
COPY dist /usr/share/nginx/html

CMD ["nginx", "-g", "daemon off;"]

dockercompose.yml

version: '2.1'

    # Define the services/containers to be run
    services:
      angular:
        build: angular # specify the directory of the Dockerfile
        network_mode: bridge
        ports:
        - 8080:80/tcp
        volumes:
        - /Users/bheng/Sites/BASE/angular/dist:/usr/share/nginx/html:rw
    
      express: #name of the second service
        build: express # specify the directory of the Dockerfile
        ports:
          - "3000:3000" #specify ports forewarding
        mem_limit: 300m
        memswap_limit: 1g
        volumes:
          - .:/home/nodejs/app
          - /home/nodejs/app/node_modules
    
        links:
          - database
    
      database: # name of the third service
        image: postgres
        environment:
          POSTGRES_PASSWORD: ih4cku
        ports:
          - "5432:5432" # specify port forewarding

Result

I couldn't get my third instances to start.

I kept getting

docker-compose up
Starting base_angular_1 ... 
Starting base_database_1 ... 
Starting base_database_1
Starting base_database_1 ... done
Starting base_express_1 ... 
Starting base_express_1 ... done
Attaching to base_angular_1, base_database_1, base_express_1
database_1  | LOG:  database system was shut down at 2017-08-30 00:54:24 UTC
database_1  | LOG:  MultiXact member wraparound protections are now enabled
database_1  | LOG:  database system is ready to accept connections
database_1  | LOG:  autovacuum launcher started

base_express_1 exited with code 0

How would one go about and debug this further?

Upvotes: 1

Views: 6009

Answers (1)

Juan
Juan

Reputation: 6383

ok, after you posted your app.js, I think I can help you.

When you run node app.js, that app.js is being executed and exiting successfully because it is just a module but no server is starting.

You need a file like this:

create a bin folder and inside create a file, name this file www Names are just suggestions, you can name it whatever.

#!/usr/bin/env node

/**
 * Load any undefined ENV variables
 */
require('dotenv').config();

/**
 * Module dependencies.
 */

var app = require('../app');
var debug = require('debug')('app:server');
var http = require('http');

/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}

Then make sure you install these packages:

npm install debug --save
npm install dotenv --save

These can be removed from the www file, if you want. I just included them here so my shared www file runs.

Then, in your Dockerfile for the express app, use:

node ./bin/www

This command starts a server, keeps the process alive and serves your app.js express module. Make sure that where you require the app.js file in the www, matches the location of your file. I put there ../app in the require.

How to include it in DockerFile?

I recommend this: create a start entry in your package.json:

"start": "node ./bin/www"

in the scripts section.

Then, update your Dockerfile:

CMD npm start or CMD ["npm", "start"]

Upvotes: 1

Related Questions