From 2160061ed03649802cfa8a514124ad5e9514009d Mon Sep 17 00:00:00 2001 From: Edward Kim Date: Thu, 7 Mar 2019 14:21:35 -1000 Subject: [PATCH] Updated to handle production enviroments --- .env.example | 17 +++-- Dockerfile | 37 +++++++--- docker-compose.override.yml | 5 +- docker-compose.prod.yml | 38 ++++++++++ docker-compose.yml | 3 +- server/{db => database}/bookshelf.js | 1 - server/database/knex.js | 2 + .../migrations/20181224104403_users.js | 0 .../user.js => database/models/User.js} | 0 server/database/seeds/users.js | 13 ++++ server/db/knex.js | 3 - server/knexfile.js | 74 ++++--------------- server/server.js | 14 +++- 13 files changed, 118 insertions(+), 89 deletions(-) create mode 100644 docker-compose.prod.yml rename server/{db => database}/bookshelf.js (99%) create mode 100644 server/database/knex.js rename server/{db => database}/migrations/20181224104403_users.js (100%) rename server/{db/models/user.js => database/models/User.js} (100%) create mode 100644 server/database/seeds/users.js delete mode 100644 server/db/knex.js diff --git a/.env.example b/.env.example index b5ebae9..050c31c 100644 --- a/.env.example +++ b/.env.example @@ -1,16 +1,21 @@ -DOCKERHUB_NAME=your_docker_username -IMAGE_NAME=image_name -IMAGE_VERSION=0.0.0 +# Container version +DOCKERHUB_NAME=name +IMAGE_NAME=docker-deploy-demo +IMAGE_VERSION=0.0.1 -EXPRESS_CONTAINER_PORT=8080 +# Container runtime +PORT=8080 EXPRESS_HOST_PORT=8080 +EXPRESS_CONTAINER_PORT=8080 POSTGRES_HOST_PORT=5432 POSTGRES_CONTAINER_PORT=5432 POSTGRES_HOSTNAME=postgres-primary-db -POSTGRES_USER=postgres_user +POSTGRES_USER=username POSTGRES_PASSWORD=password -POSTGRES_DB=project_db +POSTGRES_DB=database_name +REDIS_HOSTNAME=redis://redis-server:6379 REDIS_HOST_PORT=6379 REDIS_CONTAINER_PORT=6379 +SESSION_SECRET=secret diff --git a/Dockerfile b/Dockerfile index dd508c7..dc909d7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,36 @@ -# Built from Node latest Alpine -FROM node:10.0 +FROM node:10.15.1-alpine -# Specify an optional argument with a default value -ARG app_directory=/src/app -ARG NODE_ENV=development +# Update latest security patches +RUN apk update && apk upgrade -# Set the app directory as the context for all commands and entry to the container -WORKDIR ${app_directory} +# RUN adduser webuser - +RUN adduser -D -g '' webuser -# ONLY copy over the package.json to install NPM packages +# SET default APP_DIR path +ARG APP_DIR=/src/app + +# Create APP_DIR path and set permissions + +RUN mkdir -p $APP_DIR +RUN chown -R webuser:webuser $APP_DIR + +# Switch user to non-privileged user +USER webuser + +# Change working directory to application directory +WORKDIR $APP_DIR + +# Copy package.json to /app directory COPY package.json . -# Install node module dependencies +# Install node modules/dependencies RUN npm install -# Add the rest of the project files(most builds will start from here based on cache) +# Copy application code COPY . . -# Start the node application as you normally would +# Expose this port on DOCKER NETWORK (NOT HOST MAPPING) +EXPOSE 8080 + +# Start the Express server CMD ["node", "./server/server.js"] diff --git a/docker-compose.override.yml b/docker-compose.override.yml index d414553..9229266 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -7,11 +7,8 @@ services: command: ["npm", "run", "dev"] container_name: ${IMAGE_NAME} volumes: - - ".:/src/app/:rw" + - ".:/src/app" env_file: .env - environment: - ENVIRONMENT: production - NODE_ENV: production ports: - "${EXPRESS_HOST_PORT}:${EXPRESS_CONTAINER_PORT}" networks: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..735f610 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,38 @@ +version: "3" +services: + express-server: + image: ${DOCKERHUB_NAME}/${IMAGE_NAME}:${IMAGE_VERSION} + depends_on: + - postgres-primary-db + container_name: ${IMAGE_NAME} + env_file: .env + environment: + ENVIRONMENT: production + NODE_ENV: production + ports: + - "${EXPRESS_HOST_PORT}:${EXPRESS_CONTAINER_PORT}" + networks: + - my-app-network + postgres-primary-db: + image: postgres:10.0-alpine + env_file: .env + volumes: + - pg-data-volume:/var/lib/postgresql/data + ports: + - '${POSTGRES_HOST_PORT}:${POSTGRES_CONTAINER_PORT}' + networks: + - my-app-network + redis-server: + image: redis:4.0-alpine + env_file: .env + volumes: + - redis-data-volume:/data + ports: + - '${REDIS_HOST_PORT}:${REDIS_CONTAINER_PORT}' + networks: + - my-app-network +volumes: + pg-data-volume: + redis-data-volume: +networks: + my-app-network: diff --git a/docker-compose.yml b/docker-compose.yml index 7bb644c..c6d0643 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,5 +2,4 @@ version: "3" services: express-server: build: . - image: ${DOCKERHUB_NAME}/${IMAGE_NAME}/${IMAGE_VERSION} - env_file: .env + image: ${DOCKERHUB_NAME}/${IMAGE_NAME}:${IMAGE_VERSION} diff --git a/server/db/bookshelf.js b/server/database/bookshelf.js similarity index 99% rename from server/db/bookshelf.js rename to server/database/bookshelf.js index 1a82acd..09459b0 100644 --- a/server/db/bookshelf.js +++ b/server/database/bookshelf.js @@ -1,5 +1,4 @@ const knex = require('./knex'); const bookshelf = require('bookshelf')(knex); bookshelf.plugin('registry'); - module.exports = bookshelf; diff --git a/server/database/knex.js b/server/database/knex.js new file mode 100644 index 0000000..f6dc426 --- /dev/null +++ b/server/database/knex.js @@ -0,0 +1,2 @@ +const config = require('../knexfile.js'); +module.exports = require('knex')(config); diff --git a/server/db/migrations/20181224104403_users.js b/server/database/migrations/20181224104403_users.js similarity index 100% rename from server/db/migrations/20181224104403_users.js rename to server/database/migrations/20181224104403_users.js diff --git a/server/db/models/user.js b/server/database/models/User.js similarity index 100% rename from server/db/models/user.js rename to server/database/models/User.js diff --git a/server/database/seeds/users.js b/server/database/seeds/users.js new file mode 100644 index 0000000..c506029 --- /dev/null +++ b/server/database/seeds/users.js @@ -0,0 +1,13 @@ +exports.seed = function(knex, Promise) { + // Deletes ALL existing entries + return knex('users').del() + .then(function () { + // Inserts seed entries + return knex('users').insert([ + { username: 'ed' }, + { username: 'raymond' }, + { username: 'jason' } + ]); + }); +}; + diff --git a/server/db/knex.js b/server/db/knex.js deleted file mode 100644 index f4da672..0000000 --- a/server/db/knex.js +++ /dev/null @@ -1,3 +0,0 @@ -const environment = process.env.ENVIRONMENT || 'development'; -const config = require('../knexfile.js')[environment]; -module.exports = require('knex')(config); diff --git a/server/knexfile.js b/server/knexfile.js index 6cceb8d..0fe4aeb 100644 --- a/server/knexfile.js +++ b/server/knexfile.js @@ -2,65 +2,23 @@ require('dotenv').config({path: '../.env'}) module.exports = { - - development: { - client: 'pg', - connection: { - host: 'localhost', - database: process.env.POSTGRES_DB, - port: process.env.POSTGRES_CONTAINER_PORT, - user: process.env.POSTGRES_USER, - password: process.env.POSTGRES_PASSWORD - }, - pool: { - min: 2, - max: 10 - }, - migrations: { - tableName: 'knex_migrations', - directory: __dirname + '/db/migrations' - }, - seeds: { - directory: __dirname + '/db/seeds' - } + client: 'pg', + connection: { + host: process.env.POSTGRES_HOSTNAME, + database: process.env.POSTGRES_DB, + port: process.env.POSTGRES_CONTAINER_PORT, + user: process.env.POSTGRES_USER, + password: process.env.POSTGRES_PASSWORD }, - - staging: { - client: 'postgresql', - connection: { - database: 'my_db', - user: 'username', - password: 'password' - }, - pool: { - min: 2, - max: 10 - }, - migrations: { - tableName: 'knex_migrations' - } + pool: { + min: 2, + max: 10 }, - - production: { - client: 'pg', - connection: { - host: process.env.POSTGRES_HOSTNAME, - database: process.env.POSTGRES_DB, - port: process.env.POSTGRES_CONTAINER_PORT, - user: process.env.POSTGRES_USER, - password: process.env.POSTGRES_PASSWORD - }, - pool: { - min: 2, - max: 10 - }, - migrations: { - tableName: 'knex_migrations', - directory: __dirname + '/db/migrations' - }, - seeds: { - directory: __dirname + '/db/seeds' - } + migrations: { + tableName: 'knex_migrations', + directory: './database/migrations' + }, + seeds: { + directory: './database/seeds' } - }; diff --git a/server/server.js b/server/server.js index e8b9f13..2b54b81 100644 --- a/server/server.js +++ b/server/server.js @@ -1,14 +1,20 @@ const express = require('express'); const bodyParser = require('body-parser'); -const app = express(); +const User = require('./database/models/User'); // data vars -const PORT = process.env.EXPRESS_CONTAINER_PORT; -const User = require('./db/models/user'); +const PORT = process.env.PORT; +const SESSION_SECRET = process.env.SESSION_SECRET; +const REDIS_HOSTNAME = process.env.REDIS_HOSTNAME; + +if (!PORT) { console.log('No Port Found'); } +if (!SESSION_SECRET) { console.log('No Session Secret Found'); } +if (!REDIS_HOSTNAME) { console.log('No Redis Hostname Found'); } +if (!PORT || !SESSION_SECRET || !REDIS_HOSTNAME) { return process.exit(1); } // setup server middleware +const app = express(); app.use(bodyParser.json({ extended: true })); -app.use(express.static('server/public')); // routes app.get('/api/smoke', (req, res) => {