2
0
Эх сурвалжийг харах

feat: Heroku support - setup

NGPixel 8 жил өмнө
parent
commit
451b2a646f

+ 4 - 1
client/js/configure.js

@@ -1,6 +1,6 @@
 'use strict'
 
-/* global appconfig */
+/* global appconfig, runmode */
 
 import jQuery from 'jquery'
 import _ from 'lodash'
@@ -180,6 +180,9 @@ jQuery(document).ready(function ($) {
       },
       proceedToDb: function (ev) {
         let self = this
+        if (runmode.staticMongo) {
+          return self.proceedToDbcheck()
+        }
         self.state = 'db'
         self.loading = false
         self.$nextTick(() => {

+ 0 - 0
config.docker.yml → npm/configs/config.docker.yml


+ 153 - 0
npm/configs/config.heroku.yml

@@ -0,0 +1,153 @@
+#######################################################################
+# Wiki.js - CONFIGURATION                                             #
+#######################################################################
+# Full explanation + examples in the documentation:
+# https://docs.requarks.io/wiki/install
+
+# ---------------------------------------------------------------------
+# Title of this site
+# ---------------------------------------------------------------------
+
+title: Wiki
+
+# ---------------------------------------------------------------------
+# Full public path to the site, without the trailing slash
+# ---------------------------------------------------------------------
+
+host: https://YOURAPP.herokuapp.com/
+
+# ---------------------------------------------------------------------
+# Port the main server should listen to (80 by default)
+# ---------------------------------------------------------------------
+
+port: $(PORT)
+
+# ---------------------------------------------------------------------
+# Data Directories
+# ---------------------------------------------------------------------
+
+paths:
+  repo: ./repo
+  data: ./data
+
+# ---------------------------------------------------------------------
+# Upload Limits
+# ---------------------------------------------------------------------
+# In megabytes (MB)
+
+uploads:
+  maxImageFileSize: 3
+  maxOtherFileSize: 100
+
+# ---------------------------------------------------------------------
+# Site Language
+# ---------------------------------------------------------------------
+# Possible values: en, de, es, fr, ko, pt or ru
+
+lang: en
+
+# ---------------------------------------------------------------------
+# Site Authentication
+# ---------------------------------------------------------------------
+
+public: false
+
+auth:
+  defaultReadAccess: false
+  local:
+    enabled: true
+  google:
+    enabled: true
+    clientId: GOOGLE_CLIENT_ID
+    clientSecret: GOOGLE_CLIENT_SECRET
+  microsoft:
+    enabled: true
+    clientId: MS_APP_ID
+    clientSecret: MS_APP_SECRET
+  facebook:
+    enabled: false
+    clientId: FACEBOOK_APP_ID
+    clientSecret: FACEBOOK_APP_SECRET
+  github:
+    enabled: false
+    clientId: GITHUB_CLIENT_ID
+    clientSecret: GITHUB_CLIENT_SECRET
+  slack:
+    enabled: false
+    clientId: SLACK_CLIENT_ID
+    clientSecret: SLACK_CLIENT_SECRET
+  ldap:
+    enabled: false
+    url: ldap://serverhost:389
+    bindDn: cn='root'
+    bindCredentials: BIND_PASSWORD
+    searchBase: o=users,o=example.com
+    searchFilter: (uid={{username}})
+    tlsEnabled: false
+    tlsCertPath: C:\example\root_ca_cert.crt
+  azure:
+    enabled: false
+    clientID: APP_ID
+    clientSecret: APP_SECRET_KEY
+    resource: '00000002-0000-0000-c000-000000000000'
+    tenant: 'YOUR_TENANT.onmicrosoft.com'
+
+# ---------------------------------------------------------------------
+# Secret key to use when encrypting sessions
+# ---------------------------------------------------------------------
+# Use a long and unique random string (256-bit keys are perfect!)
+
+sessionSecret: 1234567890abcdefghijklmnopqrstuvxyz
+
+# ---------------------------------------------------------------------
+# Database Connection String
+# ---------------------------------------------------------------------
+
+db: $(MONGO_URI)
+
+# ---------------------------------------------------------------------
+# Git Connection Info
+# ---------------------------------------------------------------------
+
+git:
+  url: https://github.com/Organization/Repo
+  branch: master
+  auth:
+
+    # Type: basic or ssh
+    type: ssh
+
+    # Only for Basic authentication:
+    username: marty
+    password: MartyMcFly88
+
+    # Only for SSH authentication:
+    privateKey: /etc/wiki/keys/git.pem
+
+    sslVerify: true
+
+  # Default email to use as commit author
+  serverEmail: marty@example.com
+
+  # Whether to use user email as author in commits
+  showUserEmail: true
+
+# ---------------------------------------------------------------------
+# Features
+# ---------------------------------------------------------------------
+# You can enable / disable specific features below
+
+features:
+  mathjax: true
+
+# ---------------------------------------------------------------------
+# External Logging
+# ---------------------------------------------------------------------
+
+externalLogging:
+  bugsnag: false
+  loggly: false
+  papertrail: false
+  rollbar: false
+  sentry: false
+

+ 13 - 5
npm/install.js

@@ -136,11 +136,13 @@ const tasks = {
       // Is New Install
       if (err.code === 'ENOENT') {
         ora.text = 'First-time install, creating a new config.yml...'
-        let sourceConfigFile = 'config.sample.yml'
-        if (process.env.WIKI_JS_DOCKER) {
-          sourceConfigFile = 'config.docker.yml'
+        let sourceConfigFile = path.join(installDir, 'config.sample.yml')
+        if (process.env.IS_HEROKU) {
+          sourceConfigFile = path.join(__dirname, 'configs/config.heroku.yml')
+        } else if (process.env.WIKI_JS_DOCKER) {
+          sourceConfigFile = path.join(__dirname, 'configs/config.docker.yml')
         }
-        return fs.copyAsync(path.join(installDir, sourceConfigFile), path.join(installDir, 'config.yml')).then(() => {
+        return fs.copyAsync(sourceConfigFile, path.join(installDir, 'config.yml')).then(() => {
           ora.succeed('Installation succeeded.')
           return true
         })
@@ -200,7 +202,11 @@ const tasks = {
         })
       })
     } else {
-      console.info(colors.cyan('[WARNING] Non-interactive terminal detected. You must manually start the configuration wizard using the command: node wiki configure'))
+      if (!process.env.IS_HEROKU && !process.env.WIKI_JS_DOCKER) {
+        console.info(colors.cyan('[WARNING] Non-interactive terminal detected. You must manually start the configuration wizard using the command: node wiki configure'))
+      } else {
+        console.info('Container environment detected. Skipping setup wizard auto-start. OK.')
+      }
     }
   }
 }
@@ -217,6 +223,8 @@ if (!process.env.IS_HEROKU && !process.env.WIKI_JS_DOCKER) {
     ' \\  /\\  /| |   <| |_ | \\__ \\ \n' +
     '  \\/  \\/ |_|_|\\_\\_(_)/ |___/ \n' +
     '                   |__/\n'))
+} else {
+  console.info('=-=-= WIKI.JS =-=-=')
 }
 
 let ora = require('ora')({ text: 'Initializing...', spinner: 'dots12' }).start()

+ 15 - 6
server/configure.js

@@ -20,6 +20,7 @@ module.exports = (port, spinner) => {
   const fs = Promise.promisifyAll(require('fs-extra'))
   const yaml = require('js-yaml')
   const _ = require('lodash')
+  const cfgHelper = require('./helpers/config')
 
   // ----------------------------------------
   // Define Express App
@@ -62,7 +63,14 @@ module.exports = (port, spinner) => {
     } catch (err) {
       console.error(err)
     }
-    res.render('configure/index', { langs, conf })
+    res.render('configure/index', {
+      langs,
+      conf,
+      runmode: {
+        staticPort: (process.env.IS_HEROKU || process.env.WIKI_JS_DOCKER) || true,
+        staticMongo: (!_.isNil(process.env.IS_HEROKU)) || true
+      }
+    })
   })
 
   /**
@@ -127,7 +135,7 @@ module.exports = (port, spinner) => {
    */
   app.post('/dbcheck', (req, res) => {
     let mongo = require('mongodb').MongoClient
-    let mongoURI = (_.startsWith(req.body.db, '$')) ? process.env[req.body.db.slice(1)] : req.body.db
+    let mongoURI = cfgHelper.parseConfigValue(req.body.db)
     mongo.connect(mongoURI, {
       autoReconnect: false,
       reconnectTries: 2,
@@ -166,13 +174,13 @@ module.exports = (port, spinner) => {
     const exec = require('execa')
     const url = require('url')
 
-    const dataDir = path.resolve(ROOTPATH, req.body.pathData)
-    const gitDir = path.resolve(ROOTPATH, req.body.pathRepo)
+    const dataDir = path.resolve(ROOTPATH, cfgHelper.parseConfigValue(req.body.pathData))
+    const gitDir = path.resolve(ROOTPATH, cfgHelper.parseConfigValue(req.body.pathRepo))
 
     let gitRemoteUrl = ''
 
     if (req.body.gitUseRemote === true) {
-      let urlObj = url.parse(req.body.gitUrl)
+      let urlObj = url.parse(cfgHelper.parseConfigValue(req.body.gitUrl))
       if (req.body.gitAuthType === 'basic') {
         urlObj.auth = req.body.gitAuthUser + ':' + req.body.gitAuthPass
       }
@@ -254,10 +262,11 @@ module.exports = (port, spinner) => {
     const bcrypt = require('bcryptjs-then')
     const crypto = Promise.promisifyAll(require('crypto'))
     let mongo = require('mongodb').MongoClient
+    let parsedMongoConStr = cfgHelper.parseConfigValue(req.body.db)
 
     Promise.join(
       new Promise((resolve, reject) => {
-        mongo.connect(req.body.db, {
+        mongo.connect(parsedMongoConStr, {
           autoReconnect: false,
           reconnectTries: 2,
           reconnectInterval: 1000,

+ 20 - 0
server/helpers/config.js

@@ -0,0 +1,20 @@
+'use strict'
+
+const _ = require('lodash')
+
+module.exports = {
+  /**
+   * Parse configuration value for environment vars
+   *
+   * @param {any} cfg Configuration value
+   * @returns Parse configuration value
+   */
+  parseConfigValue (cfg) {
+    return _.replace(
+      cfg,
+      (/\$\([A-Z0-9_]+\)/g,
+      (m) => { return process.env[m] })
+    )
+  }
+}
+

+ 10 - 8
server/views/configure/index.pug

@@ -12,6 +12,7 @@ html(data-logic='configure')
     // JS / CSS
     script(type='text/javascript').
       var appconfig = !{JSON.stringify(conf)};
+      var runmode = !{JSON.stringify(runmode)};
     script(type='text/javascript', src='/js/configure.min.js')
 
   body
@@ -89,13 +90,14 @@ html(data-logic='configure')
                   section
                     p.control.is-fullwidth
                       label.label Host
-                      input(type='text', placeholder='http://', v-model='conf.host', data-vv-scope='general', name='ipt-host', v-validate='{ required: true, url: true }')
-                      span.desc The full URL to your wiki, without the trailing slash. E.g.: http://wiki.domain.com. Note that sub-folders are not supported.
-                  section
-                    p.control
-                      label.label Port
-                      input(type='text', placeholder='e.g. 80', v-model.number='conf.port', data-vv-scope='general', name='ipt-port', v-validate='{ required: true, numeric: true, min_value: 0, max_value: 65535 }')
-                      span.desc The port on which Wiki.js will listen to. Usually port 80 if connecting directly, or a random port (e.g. 3000) if using a web server in front of it.<br>Set <strong>0</strong> to use $PORT system environment variable.
+                      input(type='text', placeholder='http://', v-model='conf.host', data-vv-scope='general', name='ipt-host', v-validate='{ required: true, min: 4 }')
+                      span.desc The full URL to your wiki, without the trailing slash. E.g.: http://wiki.domain.com. Note that sub-folders are #[u not supported].
+                  if !runmode.staticPort
+                    section
+                      p.control
+                        label.label Port
+                        input(type='text', placeholder='e.g. 80', v-model.number='conf.port', data-vv-scope='general', name='ipt-port', v-validate='{ required: true }')
+                        span.desc The port on which Wiki.js will listen to. Usually port 80 if connecting directly, or a random port (e.g. 3000) if using a web server in front of it.<br>Set <strong>$(PORT)</strong> to use PORT environment variable.
                   section
                     p.control
                       label.label Site UI Language
@@ -160,7 +162,7 @@ html(data-logic='configure')
                     p.control.is-fullwidth
                       label.label MongoDB Connection String
                       input(type='text', placeholder='e.g. mongodb://localhost:27017/wiki', v-model='conf.db', data-vv-scope='db', name='ipt-db', v-validate='{ required: true, min: 3 }')
-                      span.desc The connection string to your MongoDB server. Leave the default localhost value if MongoDB is installed on the same server.<br />You can also specify an environment variable as the connection string (e.g. $MONGO_URI).
+                      span.desc The connection string to your MongoDB server. Leave the default localhost value if MongoDB is installed on the same server.<br />You can also specify an environment variable as the connection string, e.g. $(MONGO_URI).
                 .panel-footer
                   .progress-bar: div(v-bind:style='{width: currentProgress}')
                   button.button.is-light-blue.is-outlined(v-on:click='proceedToConsiderations', v-bind:disabled='loading') Back