From 47de0a4785f98188ab1f4f4edbb436674c8a6d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 13 Aug 2018 20:12:39 +0200 Subject: [PATCH] Complete rewrite of configuration - no bash scripts * error prone * platform dependent) --- .env.example | 18 ++++++++++++++++++ .env.template | 18 ++++++++++++++++++ .env.tmp | 35 ----------------------------------- .gitignore | 1 - .travis.yml | 3 +-- README.md | 8 +++++++- entrypoint.sh | 12 ------------ middleware/authenticated.js | 4 ++-- middleware/maintenance.js | 4 ++-- nuxt.config.js | 17 ++++++++++++++--- package.json | 22 ++++++++++------------ plugins/api.js | 10 +++++----- plugins/env.js | 3 +-- plugins/i18n.js | 4 ++-- plugins/raven-client.js | 12 ++++++------ plugins/raven-server.js | 15 +++++---------- scripts/on-build.sh | 14 -------------- scripts/on-dev.sh | 4 ---- scripts/on-start.sh | 24 ------------------------ scripts/run-local.sh | 5 ----- server/.env-secrets.tmp | 2 -- server/index.js | 24 +++++++++--------------- store/env.js | 25 ------------------------- yarn.lock | 2 +- 24 files changed, 101 insertions(+), 185 deletions(-) create mode 100644 .env.example create mode 100644 .env.template delete mode 100644 .env.tmp delete mode 100644 entrypoint.sh delete mode 100644 scripts/on-build.sh delete mode 100644 scripts/on-dev.sh delete mode 100644 scripts/on-start.sh delete mode 100644 scripts/run-local.sh delete mode 100644 server/.env-secrets.tmp delete mode 100644 store/env.js diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..0a3085cb --- /dev/null +++ b/.env.example @@ -0,0 +1,18 @@ +# WEBAPP +WEBAPP_HOST = localhost +WEBAPP_PORT = 3000 +WEBAPP_BASE_URL = http://localhost:3000 + +# API +API_HOST = localhost +API_PORT = 3030 + +# METAAPI +EMBED_API_URL = http://localhost:3050 + +# 3rd party integrations +SENTRY_DNS_PUBLIC = +MAPBOX_TOKEN = pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ + +# MAINTENANCE +MAINTENANCE = diff --git a/.env.template b/.env.template new file mode 100644 index 00000000..25d99134 --- /dev/null +++ b/.env.template @@ -0,0 +1,18 @@ +# WEBAPP +WEBAPP_HOST = ${WEBAPP_HOST} +WEBAPP_PORT = ${WEBAPP_PORT} +WEBAPP_BASE_URL = ${WEBAPP_BASE_URL} + +# API +API_HOST = ${API_HOST} +API_PORT = ${API_PORT} + +# METAAPI +EMBED_API_URL = ${EMBED_API_URL} + +# 3rd party integrations +SENTRY_DNS_PUBLIC = ${SENTRY_DNS_PUBLIC} +MAPBOX_TOKEN = ${MAPBOX_TOKEN} + +# MAINTENANCE +MAINTENANCE = ${MAINTENANCE} diff --git a/.env.tmp b/.env.tmp deleted file mode 100644 index 391cc5e7..00000000 --- a/.env.tmp +++ /dev/null @@ -1,35 +0,0 @@ -# DO NOT INPUT SECRETS OR PRIVAT TOKENS! -# for secrets please use server/.env-secrets -# -# this file here is read on server and client - -#################################### -# at build time -#################################### -BUILD_DATE = ${BUILD_DATE} -BUILD_ID = ${TRAVIS_BUILD_NUMBER} -BUILD_COMMIT = ${TRAVIS_PULL_REQUEST_SHA} - -#################################### -# at deploy time -#################################### -DEPLOY_DATE = ${DEPLOY_DATE} - -# WEBAPP -WEBAPP_HOST = ${WEBAPP_HOST} -WEBAPP_PORT = ${WEBAPP_PORT} -WEBAPP_BASE_URL = ${WEBAPP_BASE_URL} - -# API -API_HOST = ${API_HOST} -API_PORT = ${API_PORT} - -# METAAPI -EMBED_API_URL = ${EMBED_API_URL} - -# 3rd party integrations -SENTRY_DNS_PUBLIC = ${SENTRY_DNS_PUBLIC} -MAPBOX_TOKEN = ${MAPBOX_TOKEN} - -# MAINTENANCE -MAINTENANCE = ${MAINTENANCE} diff --git a/.gitignore b/.gitignore index 43ab0ac6..86bb3684 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,6 @@ npm-debug.log /nbproject/private/ /nbproject/ -# .env and .env-secrets .env .env-secrets diff --git a/.travis.yml b/.travis.yml index 5ac3e772..9d6a66bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,8 +16,7 @@ jobs: - stage: Test and Build script: - yarn install --frozen-lockfile --non-interactive - - yarn test:env - - yarn test + - yarn run ci - script: - docker build -t humanconnection/frontend-nuxt . diff --git a/README.md b/README.md index 32217340..af05c333 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ This is the nuxt + express version of our WebApp as nuxt.js seams to be more stable and we have better options for keeping it updated. -## Build Setup +## Local installation > we recommend to install the project locally for the best development ease and performance @@ -34,6 +34,12 @@ $ yarn dev $ yarn start ``` +Create your individual set of environment variables: +```sh +$ cp .env.example .env +# now open .env and change it according to your setup +``` + For detailed explanation on how things work, checkout the [Nuxt.js docs](https://github.com/nuxt/nuxt.js). ## Env Vars diff --git a/entrypoint.sh b/entrypoint.sh deleted file mode 100644 index d073171f..00000000 --- a/entrypoint.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env ash - -# this script is triggered always when the image is started -# it writes the environment variables to the config files -# this is needed as nuxtjs replaces all mentions of process.env -# with static vars at build time but we need them fresh at deploy time - -# setting deploy time environment vars and writing them to .env -./scripts/on-start.sh - -# starting the application with the correct settings -yarn start -p $WEBAPP_PORT -H $WEBAPP_HOST diff --git a/middleware/authenticated.js b/middleware/authenticated.js index b74c0363..a0e723eb 100644 --- a/middleware/authenticated.js +++ b/middleware/authenticated.js @@ -1,7 +1,7 @@ import { isEmpty } from 'lodash' -export default async ({ store, route, redirect }) => { - let publicPages = process.env.publicPages +export default async ({ store, env, route, redirect }) => { + let publicPages = env.publicPages publicPages.push('auth-logout') // only affect non public pages if (publicPages.indexOf(route.name) >= 0) { diff --git a/middleware/maintenance.js b/middleware/maintenance.js index c1b4c073..da242d2f 100644 --- a/middleware/maintenance.js +++ b/middleware/maintenance.js @@ -1,7 +1,7 @@ -export default async function ({ app, error, store, redirect, route }) { +export default async function ({ app, env, error, store, redirect, route }) { let isMaintenanceEnabled = false - if (Boolean(app.$env.MAINTENANCE) === true) { + if (Boolean(env.MAINTENANCE) === true) { error({ statusCode: 503, message: 'Maintenance Mode' }) return } diff --git a/nuxt.config.js b/nuxt.config.js index 6e88623d..e01ca888 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -1,4 +1,3 @@ -require('dotenv').config() const path = require('path') module.exports = { @@ -112,8 +111,20 @@ module.exports = { {src: '~/plugins/open-page-in-modal.js', ssr: false} ], modules: [ - 'cookie-universal-nuxt', - '@nuxtjs/dotenv' + ['@nuxtjs/dotenv', { + only: [ + 'WEBAPP_HOST', + 'WEBAPP_PORT', + 'WEBAPP_BASE_URL', + 'API_HOST', + 'API_PORT', + 'EMBED_API_URL', + 'SENTRY_DNS_PUBLIC', + 'MAPBOX_TOKEN', + 'MAINTENANCE' + ] + }], + 'cookie-universal-nuxt' // '@nuxtjs/pwa' ], router: { diff --git a/package.json b/package.json index 617c428d..3e6ac1b6 100644 --- a/package.json +++ b/package.json @@ -27,22 +27,20 @@ "yarn": ">= 1.3.0" }, "scripts": { - "dev": "yarn dev:env && backpack dev", - "dev:local": "sh scripts/run-local.sh", - "dev:debug": "yarn dev:env && backpack dev --inspect-brk=9229", - "dev:env": "sh scripts/on-dev.sh", - "build": "yarn build:env && nuxt build && backpack build", - "build:env": "sh scripts/on-build.sh", - "start": "yarn start:env && node build/main.js", - "start:pm2": "yarn start:env && pm2 start node build/main.js -n frontend -i 2 --attach", - "start:env": "sh scripts/on-start.sh", - "refresh": "rm -rf node_modules && yarn install && npm run dev", + "ci": "yarn run eslint && yarn run test", + "clean": "rm -rf build/*", + "dev": "backpack dev", + "dev:debug": "backpack dev --inspect=0.0.0.0:9229", + "envsub": "envsub .env.template .env", + "build": "nuxt build && backpack build", + "start": "node build/main.js", + "start:pm2": "pm2 start node build/main.js -n frontend -i 2 --attach", + "deploy": "yarn run envsub && yarn run build && yarn run start:pm2", "precommit": "yarn eslint", "eslint": "eslint --ext .js,.vue .", "styleguide": "vue-styleguidist server", "styleguide:build": "vue-styleguidist build", "test": "ava", - "test:env": "sh scripts/on-dev.sh", "cypress:open": "cypress open", "cypress:run": "cypress run", "coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov" @@ -52,7 +50,7 @@ "@feathersjs/client": "^3.5.3", "@feathersjs/feathers": "^3.1.7", "@feathersjs/socketio": "^3.2.2", - "@nuxtjs/dotenv": "~1.1.0", + "@nuxtjs/dotenv": "^1.1.1", "@nuxtjs/pwa": "~2.0.5", "axios": "^0.18.0", "babel-eslint": "~8.2.5", diff --git a/plugins/api.js b/plugins/api.js index 29633145..9794ac34 100644 --- a/plugins/api.js +++ b/plugins/api.js @@ -5,9 +5,9 @@ import authentication from '@feathersjs/authentication-client' import urlHelper from '~/helpers/urls' import Vue from 'vue' -export default ({app, store, redirect, router}) => { +export default ({app, env, store, redirect, router}) => { const authKey = 'feathers-jwt' - const endpoint = urlHelper.buildEndpointURL(app.$env.API_HOST, { port: app.$env.API_PORT }) + const endpoint = urlHelper.buildEndpointURL(env.API_HOST, { port: env.API_PORT }) const storage = { getItem: (key) => { const res = app.$cookies.get(key) @@ -26,7 +26,7 @@ export default ({app, store, redirect, router}) => { }, clear: () => { const res = app.$cookies.removeAll() - if (process.env.NODE_ENV === 'development') { + if (env.NODE_ENV === 'development') { console.log(`## STORAGE: clear()`, res) } return res @@ -60,7 +60,7 @@ export default ({app, store, redirect, router}) => { all: [ async (hook) => { // hook.accessToken = await api.passport.getJWT() - if (process.env.NODE_ENV === 'development') { + if (env.NODE_ENV === 'development') { console.log('# API:', `${hook.method} ${hook.path}`) console.info('data', hook.data) // console.log('# ' + hook.accessToken) @@ -70,7 +70,7 @@ export default ({app, store, redirect, router}) => { ] }, async error (ctx) { - if (process.env.NODE_ENV === 'development') { + if (env.NODE_ENV === 'development') { console.log('####################') console.error(ctx.error) console.info('JWT TOKEN: ', app.$cookies.get(authKey)) diff --git a/plugins/env.js b/plugins/env.js index 62005f95..d2081cc2 100644 --- a/plugins/env.js +++ b/plugins/env.js @@ -1,8 +1,7 @@ import Vue from 'vue' export default async (context) => { - await context.store.dispatch('env/init', context) - context.app.$env = context.store.getters['env/all'] + context.app.$env = context.env Vue.use({ install (Vue, store) { diff --git a/plugins/i18n.js b/plugins/i18n.js index dc006ab2..7b4dd790 100644 --- a/plugins/i18n.js +++ b/plugins/i18n.js @@ -4,8 +4,8 @@ import { debounce, isEmpty } from 'lodash' import vuexI18n from 'vuex-i18n/dist/vuex-i18n.umd.js' -export default ({ app, req, cookie, store }) => { - const doDebug = process.env.NODE_ENV !== 'production' +export default ({ app, env, req, cookie, store }) => { + const doDebug = env.NODE_ENV !== 'production' const key = 'locale' const changeHandler = debounce((mutation, store) => { diff --git a/plugins/raven-client.js b/plugins/raven-client.js index 7508d33c..0b3cc1dd 100644 --- a/plugins/raven-client.js +++ b/plugins/raven-client.js @@ -2,14 +2,14 @@ import Vue from 'vue' import Raven from 'raven-js' import RavenVue from 'raven-js/plugins/vue' -export default ({app}) => { - if (process.browser && app.$env.SENTRY_DNS_PUBLIC) { +export default ({env}) => { + if (process.browser && env.SENTRY_DNS_PUBLIC) { Raven - .config(app.$env.SENTRY_DNS_PUBLIC, { - release: app.$env.BUILD_DATE, - environment: app.$env.NODE_ENV, + .config(env.SENTRY_DNS_PUBLIC, { + release: env.BUILD_DATE, + environment: env.NODE_ENV, tags: { - deployed: app.$env.DEPLOY_DATE, + deployed: env.DEPLOY_DATE, client: true } }) diff --git a/plugins/raven-server.js b/plugins/raven-server.js index 309cf0b4..6174a99e 100644 --- a/plugins/raven-server.js +++ b/plugins/raven-server.js @@ -1,19 +1,14 @@ import Raven from 'raven' -import dotenv from 'dotenv' -import {readFileSync} from 'fs' -import {resolve} from 'path' export default async function (app) { - const secrets = dotenv.parse(await readFileSync(resolve('./server/.env-secrets'))) - - if (!process.client && secrets.SENTRY_DNS_PRIVATE) { + if (!process.client && process.env.SENTRY_DNS_PRIVATE) { // LOGGING IS ENABLED console.log('SENTRY LOGGING IS ENABLED') - Raven.config(secrets.SENTRY_DNS_PRIVATE, { - release: app.$env.BUILD_COMMIT, - environment: app.$env.NODE_ENV, + Raven.config(process.env.SENTRY_DNS_PRIVATE, { + release: process.env.BUILD_COMMIT, + environment: process.env.NODE_ENV, tags: { - deployed: app.$env.DEPLOY_DATE, + deployed: process.env.DEPLOY_DATE, client: true } }).install() diff --git a/scripts/on-build.sh b/scripts/on-build.sh deleted file mode 100644 index c06c2641..00000000 --- a/scripts/on-build.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -# this script is triggered on build -# it writes the environment variables to the config files -# this is needed as nuxtjs replaces all mentions of process.env -# with static vars at build time but we need them fresh at deploy time - -# set the build datetime -export BUILD_DATE="$(date +'%Y-%m-%d %T')" - -# create .env from .env.tmp and fill in build vars -# while swill keep deploy time variables intact -envsub --protect .env.tmp .env -envsub --protect server/.env-secrets.tmp server/.env-secrets diff --git a/scripts/on-dev.sh b/scripts/on-dev.sh deleted file mode 100644 index 45013694..00000000 --- a/scripts/on-dev.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -sh ./scripts/on-build.sh -sh ./scripts/on-start.sh diff --git a/scripts/on-start.sh b/scripts/on-start.sh deleted file mode 100644 index f00bb2b8..00000000 --- a/scripts/on-start.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env ash - -# this script is triggered always when the image is started -# it writes the environment variables to the config files -# this is needed as nuxtjs replaces all mentions of process.env -# with static vars at build time but we need them fresh at deploy time - -# set the deploy datetime -export DEPLOY_DATE="$(date +'%Y-%m-%d %T')" - -# replace the remaining deploy time variables inside .env -# while also setting all non existing vars to empty values -envsub .env .env \ - --system \ - -e WEBAPP_BASE_URL=http://localhost:3000 \ - -e WEBAPP_HOST=localhost \ - -e WEBAPP_PORT=3000 \ - -e API_HOST=localhost \ - -e API_PORT=3030 \ - -e EMBED_API_URL=http://localhost:3050 \ - -e MAPBOX_TOKEN=pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ -# empty remaining -envsub .env .env -envsub server/.env-secrets.tmp server/.env-secrets diff --git a/scripts/run-local.sh b/scripts/run-local.sh deleted file mode 100644 index e47a9a1b..00000000 --- a/scripts/run-local.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -# start app on the local network -LOCAL_IP=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'); -env WEBAPP_HOST=$LOCAL_IP env WEBAPP_BASE_URL=http://$LOCAL_IP:3000 env API_HOST=$LOCAL_IP yarn dev diff --git a/server/.env-secrets.tmp b/server/.env-secrets.tmp deleted file mode 100644 index 91da751d..00000000 --- a/server/.env-secrets.tmp +++ /dev/null @@ -1,2 +0,0 @@ -SENTRY_DNS_PRIVATE = ${SENTRY_DNS_PRIVATE} -EMBED_API_TOKEN = ${EMBED_API_TOKEN} \ No newline at end of file diff --git a/server/index.js b/server/index.js index dc00508e..bc854d93 100644 --- a/server/index.js +++ b/server/index.js @@ -9,10 +9,6 @@ import redirectSSL from 'redirect-ssl' import avatar from './avatar' import embeds from './embeds' import raven from '../plugins/raven-server' -import { readFileSync } from 'fs' - -// Get .env config -require('dotenv').config() const app = express() @@ -43,9 +39,7 @@ app.use('/embeds', embeds()) // Init Nuxt.js const nuxt = new Nuxt(nuxtConfig) -const env = require('dotenv').parse(readFileSync('./.env')) - -app.set('port', env.WEBAPP_PORT) +app.set('port', process.env.WEBAPP_PORT) // Build only in dev mode if (nuxtConfig.dev) { @@ -56,11 +50,11 @@ if (nuxtConfig.dev) { // Give nuxt middleware to express app.use(nuxt.render) // Listen the server -app.listen(env.WEBAPP_PORT, env.WEBAPP_HOST) -console.log(`Server listening on ${env.WEBAPP_HOST}:${env.WEBAPP_PORT}`) // eslint-disable-line no-console -console.log(`MAINTENANCE ${(Boolean(env.MAINTENANCE) === true).toString()}`) // eslint-disable-line no-console -console.log(`WEBAPP_PORT ${env.WEBAPP_PORT}`) // eslint-disable-line no-console -console.log(`WEBAPP_HOST ${env.WEBAPP_HOST}`) // eslint-disable-line no-console -console.log(`WEBAPP_BASE_URL ${env.WEBAPP_BASE_URL}`) // eslint-disable-line no-console -console.log(`API_PORT ${env.API_PORT}`) // eslint-disable-line no-console -console.log(`API_HOST ${env.API_HOST}`) // eslint-disable-line no-console +app.listen(process.env.WEBAPP_PORT, process.env.WEBAPP_HOST) +console.log(`Server listening on ${process.env.WEBAPP_HOST}:${process.env.WEBAPP_PORT}`) // eslint-disable-line no-console +console.log(`MAINTENANCE ${(Boolean(process.env.MAINTENANCE) === true).toString()}`) // eslint-disable-line no-console +console.log(`WEBAPP_PORT ${process.env.WEBAPP_PORT}`) // eslint-disable-line no-console +console.log(`WEBAPP_HOST ${process.env.WEBAPP_HOST}`) // eslint-disable-line no-console +console.log(`WEBAPP_BASE_URL ${process.env.WEBAPP_BASE_URL}`) // eslint-disable-line no-console +console.log(`API_PORT ${process.env.API_PORT}`) // eslint-disable-line no-console +console.log(`API_HOST ${process.env.API_HOST}`) // eslint-disable-line no-console diff --git a/store/env.js b/store/env.js deleted file mode 100644 index a1f59a5f..00000000 --- a/store/env.js +++ /dev/null @@ -1,25 +0,0 @@ -export const state = () => { - return { - env: {} - } -} - -export const mutations = { - SET_ENV (state, env) { - state.env = env - } -} - -export const getters = { - all (state) { - return state.env - } -} - -export const actions = { - init ({commit}) { - if (process.server) { - commit('SET_ENV', require('dotenv').config().parsed) - } - } -} diff --git a/yarn.lock b/yarn.lock index 420a8a0d..7aeb2146 100644 --- a/yarn.lock +++ b/yarn.lock @@ -250,7 +250,7 @@ version "3.0.0" resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.0.0.tgz#c1de4293081424da3ac30c23afa850af1019bb54" -"@nuxtjs/dotenv@~1.1.0": +"@nuxtjs/dotenv@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@nuxtjs/dotenv/-/dotenv-1.1.1.tgz#c3d68f96d8f76cac4c4ddbc8268702eb95737bbe" dependencies: