WIP - starting to work on deployment and hosting so that they don't use static URLs anymore to reach assets, instead using environment variables to determine what to use.
This commit is contained in:
parent
2546346f36
commit
f5a9c68c69
|
@ -10,6 +10,7 @@ services:
|
|||
environment:
|
||||
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY}
|
||||
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY}
|
||||
MINIO_URL: http://minio-service:9000
|
||||
SELF_HOSTED: 1
|
||||
COUCH_DB_URL: http://${COUCH_DB_USER}:${COUCH_DB_PASSWORD}@couchdb-service:5984
|
||||
BUDIBASE_ENVIRONMENT: ${BUDIBASE_ENVIRONMENT}
|
||||
|
|
|
@ -3,4 +3,5 @@ MINIO_SECRET_KEY=budibase
|
|||
COUCH_DB_PASSWORD=budibase
|
||||
COUCH_DB_USER=budibase
|
||||
BUDIBASE_ENVIRONMENT=PRODUCTION
|
||||
HOSTING_URL="http://localhost:4001"
|
||||
LOGO_URL=https://logoipsum.com/logo/logo-15.svg
|
||||
|
|
|
@ -150,6 +150,9 @@ exports.create = async function(ctx) {
|
|||
name: ctx.request.body.name,
|
||||
template: ctx.request.body.template,
|
||||
instance: instance,
|
||||
deployment: {
|
||||
type: "cloud",
|
||||
},
|
||||
}
|
||||
const instanceDb = new CouchDB(appId)
|
||||
await instanceDb.put(newApplication)
|
||||
|
|
|
@ -20,7 +20,7 @@ exports.postDeployment = async function() {
|
|||
exports.deploy = async function(deployment) {
|
||||
const appId = deployment.getAppId()
|
||||
var objClient = new AWS.S3({
|
||||
endpoint: "http://localhost:9000",
|
||||
endpoint: env.MINIO_URL,
|
||||
s3ForcePathStyle: true, // needed with minio?
|
||||
signatureVersion: "v4",
|
||||
params: {
|
||||
|
@ -46,6 +46,7 @@ exports.deploy = async function(deployment) {
|
|||
exports.replicateDb = async function(deployment) {
|
||||
const appId = deployment.getAppId()
|
||||
const localDb = new PouchDB(appId)
|
||||
|
||||
const remoteDb = new CouchDB(`${env.COUCH_DB_URL}/${appId}`)
|
||||
return performReplication(localDb, remoteDb)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
const CouchDB = require("../../db")
|
||||
const { BUILDER_CONFIG_DB, HOSTING_DOC } = require("../../constants")
|
||||
const {
|
||||
getHostingInfo,
|
||||
HostingTypes,
|
||||
getAppServerUrl,
|
||||
} = require("../../utilities/builder/hosting")
|
||||
|
||||
exports.fetchInfo = async ctx => {
|
||||
ctx.body = {
|
||||
types: Object.values(HostingTypes),
|
||||
}
|
||||
}
|
||||
|
||||
exports.save = async ctx => {
|
||||
const db = new CouchDB(BUILDER_CONFIG_DB)
|
||||
const { type, appServerUrl, objectStoreUrl, useHttps } = ctx.request.body
|
||||
if (type === HostingTypes.CLOUD) {
|
||||
ctx.throw(400, "Cannot update Cloud hosting information")
|
||||
}
|
||||
await db.put({
|
||||
_id: HOSTING_DOC,
|
||||
type,
|
||||
appServerUrl,
|
||||
objectStoreUrl,
|
||||
useHttps,
|
||||
})
|
||||
ctx.body = "Hosting information saved successfully"
|
||||
}
|
||||
|
||||
exports.fetch = async ctx => {
|
||||
ctx.body = await getHostingInfo()
|
||||
}
|
||||
|
||||
exports.fetchUrls = async ctx => {
|
||||
ctx.body = {
|
||||
appServer: getAppServerUrl(ctx.appId),
|
||||
}
|
||||
}
|
|
@ -17,6 +17,22 @@ const setBuilderToken = require("../../../utilities/builder/setBuilderToken")
|
|||
const fileProcessor = require("../../../utilities/fileProcessor")
|
||||
const env = require("../../../environment")
|
||||
|
||||
function appServerUrl(appId) {
|
||||
if (env.SELF_HOSTED) {
|
||||
return env.HOSTING_URL
|
||||
} else {
|
||||
return `https://${appId}.app.budi.live`
|
||||
}
|
||||
}
|
||||
|
||||
function objectStoreUrl() {
|
||||
if (env.SELF_HOSTED) {
|
||||
return env.MINIO_URL
|
||||
} else {
|
||||
return "https://cdn.app.budi.live/assets"
|
||||
}
|
||||
}
|
||||
|
||||
// this was the version before we started versioning the component library
|
||||
const COMP_LIB_BASE_APP_VERSION = "0.2.5"
|
||||
|
||||
|
@ -148,6 +164,7 @@ exports.serveApp = async function(ctx) {
|
|||
title: appInfo.name,
|
||||
production: env.CLOUD,
|
||||
appId: ctx.params.appId,
|
||||
appServerUrl: appServerUrl(ctx.params.appId),
|
||||
})
|
||||
|
||||
const template = handlebars.compile(
|
||||
|
@ -166,8 +183,9 @@ exports.serveAttachment = async function(ctx) {
|
|||
const attachmentsPath = resolve(budibaseAppsDir(), appId, "attachments")
|
||||
|
||||
// Serve from CloudFront
|
||||
// TODO: need to replace this with link to self hosted object store
|
||||
if (env.CLOUD) {
|
||||
const S3_URL = `https://cdn.app.budi.live/assets/${appId}/attachments/${ctx.file}`
|
||||
const S3_URL = join(objectStoreUrl(), appId, "attachments", ctx.file)
|
||||
const response = await fetch(S3_URL)
|
||||
const body = await response.text()
|
||||
ctx.set("Content-Type", response.headers.get("Content-Type"))
|
||||
|
@ -213,7 +231,14 @@ exports.serveComponentLibrary = async function(ctx) {
|
|||
componentLib += `-${COMP_LIB_BASE_APP_VERSION}`
|
||||
}
|
||||
const S3_URL = encodeURI(
|
||||
`https://${appId}.app.budi.live/assets/${componentLib}/${ctx.query.library}/dist/index.js`
|
||||
join(
|
||||
appServerUrl(appId),
|
||||
"assets",
|
||||
componentLib,
|
||||
ctx.query.library,
|
||||
"dist",
|
||||
"index.js"
|
||||
)
|
||||
)
|
||||
const response = await fetch(S3_URL)
|
||||
const body = await response.text()
|
||||
|
|
|
@ -4,12 +4,11 @@
|
|||
|
||||
export let appId
|
||||
export let production
|
||||
|
||||
export const PRODUCTION_ASSETS_URL = `https://${appId}.app.budi.live`
|
||||
export let appServerUrl
|
||||
|
||||
function publicPath(path) {
|
||||
if (production) {
|
||||
return `${PRODUCTION_ASSETS_URL}/assets/${appId}/${path}`
|
||||
return `${appServerUrl}/assets/${appId}/${path}`
|
||||
}
|
||||
|
||||
return `/assets/${path}`
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
const Router = require("@koa/router")
|
||||
const controller = require("../controllers/hosting")
|
||||
const authorized = require("../../middleware/authorized")
|
||||
const { BUILDER } = require("../../utilities/security/permissions")
|
||||
|
||||
const router = Router()
|
||||
|
||||
router
|
||||
.fetch("/api/hosting/info", authorized(BUILDER), controller.fetchInfo)
|
||||
.fetch("/api/hosting", authorized(BUILDER), controller.fetch)
|
||||
.post("/api/hosting", authorized(BUILDER), controller.save)
|
||||
|
||||
module.exports = router
|
|
@ -41,3 +41,5 @@ const USERS_TABLE_SCHEMA = {
|
|||
|
||||
exports.AuthTypes = AuthTypes
|
||||
exports.USERS_TABLE_SCHEMA = USERS_TABLE_SCHEMA
|
||||
exports.BUILDER_CONFIG_DB = "builder-config-db"
|
||||
exports.HOSTING_DOC = "hosting-doc"
|
||||
|
|
|
@ -39,6 +39,8 @@ module.exports = {
|
|||
// self hosting features
|
||||
MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
|
||||
MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
|
||||
MINIO_URL: process.MINIO_URL,
|
||||
HOSTING_URL: process.HOSTING_URL,
|
||||
LOGO_URL: process.env.LOGO_URL,
|
||||
_set(key, value) {
|
||||
process.env[key] = value
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
const CouchDB = require("../../db")
|
||||
const { BUILDER_CONFIG_DB, HOSTING_DOC } = require("../../constants")
|
||||
const { join } = require("path")
|
||||
|
||||
function getProtocol(hostingInfo) {
|
||||
return hostingInfo.useHttps ? "https://" : "http://"
|
||||
}
|
||||
|
||||
exports.HostingTypes = {
|
||||
CLOUD: "cloud",
|
||||
SELF: "self",
|
||||
}
|
||||
|
||||
exports.getHostingInfo = async () => {
|
||||
const db = new CouchDB(BUILDER_CONFIG_DB)
|
||||
let doc
|
||||
try {
|
||||
doc = await db.get(HOSTING_DOC)
|
||||
} catch (err) {
|
||||
// don't write this doc, want to be able to update these default props
|
||||
// for our servers with a new release without needing to worry about state of
|
||||
// PouchDB in peoples installations
|
||||
doc = {
|
||||
_id: HOSTING_DOC,
|
||||
type: exports.HostingTypes.CLOUD,
|
||||
appServerUrl: "app.budi.live",
|
||||
objectStoreUrl: "cdn.app.budi.live",
|
||||
templatesUrl: "prod-budi-templates.s3-eu-west-1.amazonaws.com",
|
||||
useHttps: true,
|
||||
}
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
exports.getAppServerUrl = async (appId) => {
|
||||
const hostingInfo = await exports.getHostingInfo()
|
||||
const protocol = getProtocol(hostingInfo)
|
||||
let url
|
||||
if (hostingInfo.type === "cloud") {
|
||||
url = `${protocol}${appId}.${hostingInfo.appServerUrl}`
|
||||
} else {
|
||||
url = `${protocol}${hostingInfo.appServerUrl}`
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
exports.getTemplatesUrl = async (appId, type, name) => {
|
||||
const hostingInfo = await exports.getHostingInfo()
|
||||
const protocol = getProtocol(hostingInfo)
|
||||
let path
|
||||
if (type && name) {
|
||||
path = join("templates", type, `${name}.tar.gz`)
|
||||
} else {
|
||||
path = "manifest.json"
|
||||
}
|
||||
return join(`${protocol}${hostingInfo.templatesUrl}`, path)
|
||||
}
|
Loading…
Reference in New Issue