Skip to content

Commit

Permalink
fix(docker): Apply OWASP recommendations (#455)
Browse files Browse the repository at this point in the history
Reference: [Node.js Docker Cheatsheet 路 OWASP](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/NodeJS_Docker_Cheat_Sheet.md)

Changes:

* add sha256 to node docker image
cf https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/NodeJS_Docker_Cheat_Sheet.md

* ensure that we only install production dependencies in a deterministic way

* set NODE_ENV

* Don鈥檛 run containers as root

* troubleshooting: display openwhyd logs after tests fail

* try to allow "node" user to create files in workdir

* Properly handle events to safely terminate a Node.js Docker web application

* terminate gracefully on SIGINT and SIGTERM

* multi-stage build

* fix separation of parameters in CMD

* ignore more files

* fix `chown: changing ownership of '/usr/src/app': Operation not permitted`
cf https://github.com/openwhyd/openwhyd/runs/2589782153#step:3:655

* remove volume defs
  • Loading branch information
adrienjoly committed May 15, 2021
1 parent de6b808 commit 5507606
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 25 deletions.
7 changes: 6 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
.dockerignore
.gitignore
.git
.env
.port
.DS_Store
Dockerfile
npm-debug.log
/.nyc_output
/coverage
/node_modules
Expand All @@ -12,7 +16,8 @@
/*.out
/*.pid
/*.err
/env-vars-*.sh
/*.conf
/env-vars-*.*
/errorShots
/uAvatarImg
/uCoverImg
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,6 @@ jobs:
run: docker-compose exec -T web npm run test-unit
- name: Run API tests
run: docker-compose exec -T web npm run test-api
- name: Logs from docker-compose
if: ${{ always() }} # this step is useful to troubleshoot the execution of openwhyd when tests fail
run: docker-compose logs
35 changes: 25 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
FROM node:14.16.1-slim
# note: keep nodejs version above in sync with the one in .nvmrc
FROM node:14.16.1-slim@sha256:58dbfbdf664f703072bd8263b787301614579c8e345029cdc3d9acf682e853a9 AS build

# Install dependencies
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
g++ \
gcc \
libc6-dev \
make \
python \
graphicsmagick \
&& rm -rf /var/lib/apt/lists/*
python

# Install and build app dependencies
WORKDIR /usr/src/app
COPY ./package*.json /usr/src/app/
RUN npm install --no-audit --production
COPY --chown=node:node ./package*.json /usr/src/app/
RUN npm ci --only=production --no-audit

# Fix Error: Cannot find module '../build/Release/bson' on newer node / MongoDB versions
# RUN sed -i.backup 's/..\/build\/Release\/bson/bson/g' /usr/src/app/node_modules/bson/ext/index.js

FROM node:14.16.1-slim@sha256:58dbfbdf664f703072bd8263b787301614579c8e345029cdc3d9acf682e853a9
# note: keep nodejs version above in sync with the one in .nvmrc + don't forget to append the corresponding sha256 hash

# Install runtime dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
dumb-init \
graphicsmagick \
&& rm -rf /var/lib/apt/lists/*

ENV NODE_ENV production

# Bundle app source
COPY ./ /usr/src/app
WORKDIR /usr/src/app
COPY --chown=node:node --from=build /usr/src/app/node_modules /usr/src/app/node_modules
COPY --chown=node:node ./ /usr/src/app

# Allow openwhyd server (running as "node" user) to create files (e.g. playlog.json.log) in /usr/src/app
RUN chown node:node /usr/src/app
USER node

EXPOSE 8080

CMD [ "npm", "start" ]
# dumb-init is invoked with PID 1, then spawns node as another process whilst ensuring that all signals are proxied to it
CMD [ "dumb-init", "node", "app.js", "--fakeEmail", "--digestInterval", "-1" ]
16 changes: 15 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,23 @@ function start() {
},
};
require('./app/models/logging.js'); // init logging methods (IncomingMessage extensions)
new myHttp.Application(serverOptions).start();
const appServer = new myHttp.Application(serverOptions);
appServer.start(() => {
const url = params.urlPrefix || `http://127.0.0.1:${params.port}/`;
console.log(`[app] Server running at ${url}`);
});
require('./app/workers/notifEmails.js'); // start digest worker
require('./app/workers/hotSnapshot.js'); // start hot tracks snapshot worker

function closeGracefully(signal) {
console.warn(`[app] ${signal} signal received: closing server...`);
appServer.stop((err) => {
console.warn(`[app] server.close => ${err || 'OK'}`);
process.exit(err ? 1 : 0);
});
}
process.on('SIGTERM', closeGracefully);
process.on('SIGINT', closeGracefully);
}

// startup
Expand Down
13 changes: 6 additions & 7 deletions app/lib/my-http-wrapper/http/Application.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,17 @@ exports.Application = class Application {
return (this._expressApp = app);
}

start() {
start(callback) {
this._isRunning = true;
this.expressServer = this.getExpressApp().listen(this._port, () => {
const url = this._urlPrefix || `http://127.0.0.1:${this._port}/`;
console.log(`[Application] Server running at ${url}`);
});
this.expressServer = this.getExpressApp().listen(this._port, callback);
}

stop() {
stop(callback) {
if (this._isRunning) {
this.expressServer.close();
this.expressServer.close(callback);
this._isRunning = false;
} else if (callback) {
callback();
}
}
};
Expand Down
5 changes: 2 additions & 3 deletions app/models/analytics.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@
**/

var fs = require('fs');
//var mongodb = require("./mongodb.js");
var snip = require('../snip.js');

var playlogStream = fs.createWriteStream('./playlog.json.log', {
flags: 'a',
flags: 'a', // append
encoding: 'utf8',
autoClose: true,
});

var visitStream = fs.createWriteStream('./visits.json.log', {
flags: 'a',
flags: 'a', // append
encoding: 'utf8',
autoClose: true,
});
Expand Down
3 changes: 0 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ services:
web:
restart: 'always'
build: .
volumes:
- ./:/usr/src/app
- /usr/src/app/node_modules
ports:
- '8080:8080'
depends_on:
Expand Down

0 comments on commit 5507606

Please sign in to comment.