Search code examples
javascriptnode.jsdockergulpdocker-compose

Gulp build task failing inside docker


I have a simple Hapi.js Node API. Since I have used TypeScript to write the API, I wrote Gulp task for transpiling the code. My API works fine if I run it directly in my main machine but I get the following error when I try to run it inside Docker:

Error: enter image description here

Docker compose command:

docker-compose -f docker-compose.dev.yml up -d --build

Here is my code: ./gulpfile:

'use strict';

const gulp = require('gulp');
const rimraf = require('gulp-rimraf');
const tslint = require('gulp-tslint');
const mocha = require('gulp-mocha');
const shell = require('gulp-shell');
const env = require('gulp-env');

/**
 * Remove build directory.
 */
gulp.task('clean', function () {
  return gulp.src(outDir, { read: false })
    .pipe(rimraf());
});

/**
 * Lint all custom TypeScript files.
 */
gulp.task('tslint', () => {
  return gulp.src('src/**/*.ts')
    .pipe(tslint({
      formatter: 'prose'
    }))
    .pipe(tslint.report());
});

/**
 * Compile TypeScript.
 */

function compileTS(args, cb) {
  return exec(tscCmd + args, (err, stdout, stderr) => {
    console.log(stdout);

    if (stderr) {
      console.log(stderr);
    }
    cb(err);
  });
}

gulp.task('compile', shell.task([
  'npm run tsc',
]))

/**
 * Watch for changes in TypeScript
 */
gulp.task('watch', shell.task([
  'npm run tsc-watch',
]))
/**
 * Copy config files
 */
gulp.task('configs', (cb) => {
  return gulp.src("src/configurations/*.json")
    .pipe(gulp.dest('./build/src/configurations'));
});

/**
 * Build the project.
 */
gulp.task('build', ['tslint', 'compile', 'configs'], () => {
  console.log('Building the project ...');
});

/**
 * Run tests.
 */
gulp.task('test', ['build'], (cb) => {
  const envs = env.set({
    NODE_ENV: 'test'
  });

  gulp.src(['build/test/**/*.js'])
    .pipe(envs)
    .pipe(mocha({ exit: true }))
    .once('error', (error) => {
      console.log(error);
      process.exit(1);
    });
});

gulp.task('default', ['build']);

./.docker/dev.dockerfile:

FROM node:latest

LABEL author="Saurabh Palatkar"

# create a specific user to run this container
# RUN adduser -S -D user-app

# add files to container
ADD . /app

# specify the working directory
WORKDIR app
RUN chmod -R 777 .
RUN npm i gulp --g
# build process
RUN npm install
# RUN ln -s /usr/bin/nodejs /usr/bin/node
RUN npm run build
# RUN npm prune --production
EXPOSE 8080
# run application
CMD ["npm", "start"]

./docker-compose.dev.yml:

version: "3.4"

services:
  api:
    image: node-api
    build:
      context: .
      dockerfile: .docker/dev.dockerfile
    environment:
      PORT: 8080
      MONGO_URL: mongodb:27017
      NODE_ENV: development
    ports:
      - "8080:8080"
    links:
      - database

  database:
    image: mongo:latest
    ports:
      - "27017:27017"

What I am missing here?


Solution

  • Edit: The problem wasn't what I initially thought. The order of the operations in the Dockerfile was simply wrong: you have to install the dependencies first, then copy all the files into the container (so the installed dependencies will also be copied), only then you can use the application and its dependencies. I made a pull request on your repo with those fixes :)