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:
mike12345567 2020-12-14 18:31:48 +00:00
parent 2546346f36
commit f5a9c68c69
11 changed files with 149 additions and 6 deletions

View File

@ -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}

View File

@ -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

View File

@ -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)

View File

@ -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)
}

View File

@ -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),
}
}

View File

@ -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()

View File

@ -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}`

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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)
}