add searxng
This commit is contained in:
parent
21f3a70788
commit
22cbbec960
@ -7,6 +7,9 @@ export async function migrateServicesToNewTemplate() {
|
||||
try {
|
||||
const services = await prisma.service.findMany({ include: includeServices })
|
||||
for (const service of services) {
|
||||
if (!service.type) {
|
||||
continue;
|
||||
}
|
||||
if (service.type === 'plausibleanalytics' && service.plausibleAnalytics) await plausibleAnalytics(service)
|
||||
if (service.type === 'fider' && service.fider) await fider(service)
|
||||
if (service.type === 'minio' && service.minio) await minio(service)
|
||||
@ -16,7 +19,9 @@ export async function migrateServicesToNewTemplate() {
|
||||
if (service.type === 'meilisearch' && service.meiliSearch) await meilisearch(service)
|
||||
if (service.type === 'umami' && service.umami) await umami(service)
|
||||
if (service.type === 'hasura' && service.hasura) await hasura(service)
|
||||
if (service.type === 'glitchtip' && service.glitchTip) await glitchtip(service)
|
||||
if (service.type === 'glitchTip' && service.glitchTip) await glitchtip(service)
|
||||
if (service.type === 'searxng' && service.searxng) await searxng(service)
|
||||
|
||||
await createVolumes(service);
|
||||
}
|
||||
} catch (error) {
|
||||
@ -24,6 +29,23 @@ export async function migrateServicesToNewTemplate() {
|
||||
|
||||
}
|
||||
}
|
||||
async function searxng(service: any) {
|
||||
const { secretKey, redisPassword } = service.searxng
|
||||
|
||||
const secrets = [
|
||||
`SECRET_KEY@@@${secretKey}`,
|
||||
`REDIS_PASSWORD@@@${redisPassword}`,
|
||||
]
|
||||
|
||||
const settings = [
|
||||
`SEARXNG_BASE_URL@@@$$generate_fqdn`
|
||||
]
|
||||
await migrateSecrets(secrets, service);
|
||||
await migrateSettings(settings, service);
|
||||
|
||||
// Remove old service data
|
||||
// await prisma.service.update({ where: { id: service.id }, data: { wordpress: { delete: true } } })
|
||||
}
|
||||
async function glitchtip(service: any) {
|
||||
const { postgresqlUser, postgresqlPassword, postgresqlDatabase, secretKeyBase, defaultEmail, defaultUsername, defaultPassword, defaultEmailFrom, emailSmtpHost, emailSmtpPort, emailSmtpUser, emailSmtpPassword, emailSmtpUseTls, emailSmtpUseSsl, emailBackend, mailgunApiKey, sendgridApiKey, enableOpenUserRegistration } = service.glitchTip
|
||||
|
||||
@ -228,7 +250,7 @@ async function fider(service: any) {
|
||||
|
||||
}
|
||||
async function plausibleAnalytics(service: any) {
|
||||
const { email = 'admin@example.com', username = 'admin', password, postgresqlUser, postgresqlPassword, postgresqlDatabase, secretKeyBase, scriptName } = service.plausibleAnalytics;
|
||||
const { email, username, password, postgresqlUser, postgresqlPassword, postgresqlDatabase, secretKeyBase, scriptName } = service.plausibleAnalytics;
|
||||
|
||||
const settings = [
|
||||
`BASE_URL@@@$$generate_fqdn`,
|
||||
@ -248,7 +270,6 @@ async function plausibleAnalytics(service: any) {
|
||||
]
|
||||
await migrateSettings(settings, service);
|
||||
await migrateSecrets(secrets, service);
|
||||
await createVolumes(service);
|
||||
|
||||
// Remove old service data
|
||||
// await prisma.service.update({ where: { id: service.id }, data: { plausibleAnalytics: { delete: true } } })
|
||||
@ -257,7 +278,10 @@ async function plausibleAnalytics(service: any) {
|
||||
async function migrateSettings(settings: any[], service: any) {
|
||||
for (const setting of settings) {
|
||||
if (!setting) continue;
|
||||
const [name, value] = setting.split('@@@')
|
||||
let [name, value] = setting.split('@@@')
|
||||
if (!value || value === 'null') {
|
||||
continue;
|
||||
}
|
||||
// console.log('Migrating setting', name, value, 'for service', service.id, ', service name:', service.name)
|
||||
await prisma.serviceSetting.findFirst({ where: { name, serviceId: service.id } }) || await prisma.serviceSetting.create({ data: { name, value, service: { connect: { id: service.id } } } })
|
||||
}
|
||||
@ -265,14 +289,17 @@ async function migrateSettings(settings: any[], service: any) {
|
||||
async function migrateSecrets(secrets: any[], service: any) {
|
||||
for (const secret of secrets) {
|
||||
if (!secret) continue;
|
||||
const [name, value] = secret.split('@@@')
|
||||
let [name, value] = secret.split('@@@')
|
||||
if (!value || value === 'null') {
|
||||
continue
|
||||
}
|
||||
// console.log('Migrating secret', name, value, 'for service', service.id, ', service name:', service.name)
|
||||
await prisma.serviceSecret.findFirst({ where: { name, serviceId: service.id } }) || await prisma.serviceSecret.create({ data: { name, value, service: { connect: { id: service.id } } } })
|
||||
}
|
||||
}
|
||||
async function createVolumes(service: any) {
|
||||
const volumes = [];
|
||||
let template = templates.find(t => t.name === service.type)
|
||||
let template = templates.find(t => t.name === service.type.toLowerCase());
|
||||
if (template) {
|
||||
template = JSON.parse(JSON.stringify(template).replaceAll('$$id', service.id))
|
||||
for (const s of Object.keys(template.services)) {
|
||||
|
@ -698,9 +698,15 @@ export async function startService(request: FastifyRequest<ServiceStartStop>) {
|
||||
const { workdir } = await createDirectories({ repository: type, buildId: id });
|
||||
const template: any = await parseAndFindServiceTemplates(service, workdir, true)
|
||||
const network = destinationDockerId && destinationDocker.network;
|
||||
|
||||
const config = {};
|
||||
for (const service in template.services) {
|
||||
let newEnviroments = []
|
||||
for (const environment of template.services[service].environment) {
|
||||
const [env, value] = environment.split("=");
|
||||
if (!value.startsWith('$$secret') && value !== '') {
|
||||
newEnviroments.push(`${env}=${value}`)
|
||||
}
|
||||
}
|
||||
config[service] = {
|
||||
container_name: service,
|
||||
build: template.services[service].build || undefined,
|
||||
@ -709,9 +715,11 @@ export async function startService(request: FastifyRequest<ServiceStartStop>) {
|
||||
expose: template.services[service].ports,
|
||||
// ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}),
|
||||
volumes: template.services[service].volumes,
|
||||
environment: template.services[service].environment,
|
||||
environment: newEnviroments,
|
||||
depends_on: template.services[service].depends_on,
|
||||
ulimits: template.services[service].ulimits,
|
||||
cap_drop: template.services[service].cap_drop,
|
||||
cap_add: template.services[service].cap_add,
|
||||
labels: makeLabelForServices(type),
|
||||
...defaultComposeConfiguration(network),
|
||||
}
|
||||
|
@ -1,4 +1,87 @@
|
||||
export default [
|
||||
{
|
||||
"templateVersion": "1.0.0",
|
||||
"serviceDefaultVersion": "2022.10.14-1a5b0965",
|
||||
"name": "searxng",
|
||||
"displayName": "SearXNG",
|
||||
"description": "",
|
||||
"services": {
|
||||
"$$id": {
|
||||
"name": "SearXNG",
|
||||
"depends_on": [
|
||||
"$$id-redis"
|
||||
],
|
||||
"image": "searxng/searxng:$$core_version",
|
||||
"volumes": [
|
||||
"$$id-postgresql-searxng:/etc/searxng",
|
||||
],
|
||||
"environment": [
|
||||
"SEARXNG_BASE_URL=$$config_searxng_base_url",
|
||||
"SECRET_KEY=$$secret_secret_key",
|
||||
],
|
||||
"ports": [
|
||||
"8080"
|
||||
],
|
||||
"extras": {
|
||||
"files": [
|
||||
{
|
||||
source: "$$workdir/schema.postgresql.sql",
|
||||
destination: "/docker-entrypoint-initdb.d/schema.postgresql.sql",
|
||||
content: `
|
||||
# see https://docs.searxng.org/admin/engines/settings.html#use-default-settings
|
||||
use_default_settings: true
|
||||
server:
|
||||
secret_key: $$secret_secret_key
|
||||
limiter: true
|
||||
image_proxy: true
|
||||
ui:
|
||||
static_use_hash: true
|
||||
redis:
|
||||
url: redis://:$$secret_redis_password@$$id-redis:6379/0`
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"$$id-redis": {
|
||||
"name": "Redis",
|
||||
"command": `redis-server --requirepass $$secret_redis_password --save "" --appendonly "no"`,
|
||||
"depends_on": [],
|
||||
"image": "redis:7-alpine",
|
||||
"volumes": [
|
||||
"$$id-redis-data:/data",
|
||||
],
|
||||
"environment": [
|
||||
"REDIS_PASSWORD=$$secret_redis_password",
|
||||
],
|
||||
"ports": [],
|
||||
"cap_drop": ['ALL'],
|
||||
"cap_add": ['SETGID', 'SETUID', 'DAC_OVERRIDE'],
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"id": "$$config_searxng_base_url",
|
||||
"name": "SEARXNG_BASE_URL",
|
||||
"label": "SearXNG Base URL",
|
||||
"defaultValue": "$$generate_fqdn",
|
||||
"description": "",
|
||||
},
|
||||
{
|
||||
"id": "$$secret_secret_key",
|
||||
"name": "SECRET_KEY",
|
||||
"label": "Secret Key",
|
||||
"defaultValue": "$$generate_passphrase",
|
||||
"description": "",
|
||||
},
|
||||
{
|
||||
"id": "$$secret_redis_password",
|
||||
"name": "REDIS_PASSWORD",
|
||||
"label": "Redis Password",
|
||||
"defaultValue": "$$generate_password",
|
||||
"description": "",
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"templateVersion": "1.0.0",
|
||||
"serviceDefaultVersion": "v2.0.6",
|
||||
@ -9,7 +92,8 @@ export default [
|
||||
"$$id": {
|
||||
"name": "GlitchTip",
|
||||
"depends_on": [
|
||||
"$$id-postgresql"
|
||||
"$$id-postgresql",
|
||||
"$$id-redis"
|
||||
],
|
||||
"image": "glitchtip/glitchtip:$$core_version",
|
||||
"volumes": [],
|
||||
@ -67,7 +151,7 @@ export default [
|
||||
{
|
||||
"id": "$$config_glitchtip_domain",
|
||||
"name": "GLITCHTIP_DOMAIN",
|
||||
"label": "GLITCHTIP_DOMAIN URL",
|
||||
"label": "GlitchTip Domain",
|
||||
"defaultValue": "$$generate_fqdn",
|
||||
"description": "",
|
||||
},
|
||||
|
@ -6,13 +6,13 @@ import { prisma, uniqueName, asyncExecShell, getServiceFromDB, getContainerUsage
|
||||
import { day } from '../../../../lib/dayjs';
|
||||
import { checkContainer, isContainerExited } from '../../../../lib/docker';
|
||||
import cuid from 'cuid';
|
||||
import templates from '../../../../lib/templates';
|
||||
|
||||
import type { OnlyId } from '../../../../types';
|
||||
import type { ActivateWordpressFtp, CheckService, CheckServiceDomain, DeleteServiceSecret, DeleteServiceStorage, GetServiceLogs, SaveService, SaveServiceDestination, SaveServiceSecret, SaveServiceSettings, SaveServiceStorage, SaveServiceType, SaveServiceVersion, ServiceStartStop, SetGlitchTipSettings, SetWordpressSettings } from './types';
|
||||
import { supportedServiceTypesAndVersions } from '../../../../lib/services/supportedVersions';
|
||||
import { configureServiceType, removeService } from '../../../../lib/services/common';
|
||||
import { hashPassword } from '../handlers';
|
||||
import templates from '../../../../lib/templates';
|
||||
|
||||
export async function listServices(request: FastifyRequest) {
|
||||
try {
|
||||
@ -113,7 +113,7 @@ export async function getServiceStatus(request: FastifyRequest<OnlyId>) {
|
||||
}
|
||||
}
|
||||
export async function parseAndFindServiceTemplates(service: any, workdir?: string, isDeploy: boolean = false) {
|
||||
const foundTemplate = templates.find(t => t.name === service.type)
|
||||
const foundTemplate = templates.find(t => t.name === service.type.toLowerCase())
|
||||
let parsedTemplate = {}
|
||||
if (foundTemplate) {
|
||||
if (!isDeploy) {
|
||||
@ -155,12 +155,13 @@ export async function parseAndFindServiceTemplates(service: any, workdir?: strin
|
||||
if (service.serviceSetting.length > 0) {
|
||||
for (const setting of service.serviceSetting) {
|
||||
const { name, value } = setting
|
||||
const regex = new RegExp(`\\$\\$config_${name}\\"`, 'gi')
|
||||
if (service.fqdn && value === '$$generate_fqdn') {
|
||||
parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(`$$config_${name.toLowerCase()}`, service.fqdn))
|
||||
parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(regex, service.fqdn + "\""))
|
||||
} else if (service.fqdn && value === '$$generate_domain') {
|
||||
parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(`$$config_${name.toLowerCase()}`, getDomain(service.fqdn)))
|
||||
parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(regex, getDomain(service.fqdn) + "\""))
|
||||
} else {
|
||||
parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(`$$config_${name.toLowerCase()}`, value))
|
||||
parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(regex, value + "\""))
|
||||
|
||||
}
|
||||
}
|
||||
@ -170,7 +171,9 @@ export async function parseAndFindServiceTemplates(service: any, workdir?: strin
|
||||
if (service.serviceSecret.length > 0) {
|
||||
for (const secret of service.serviceSecret) {
|
||||
const { name, value } = secret
|
||||
parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(`$$hashed$$secret_${name.toLowerCase()}`, bcrypt.hashSync(value, 10)).replaceAll(`$$secret_${name.toLowerCase()}`, value))
|
||||
const regex = new RegExp(`\\$\\$secret_${name}\\"`, 'gi')
|
||||
const regexHashed = new RegExp(`\\$\\$hashed\\$\\$secret_${name}\\"`, 'gi')
|
||||
parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(regexHashed, bcrypt.hashSync(value, 10)).replaceAll(regex, value))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -185,13 +188,17 @@ export async function getService(request: FastifyRequest<OnlyId>) {
|
||||
if (!service) {
|
||||
throw { status: 404, message: 'Service not found.' }
|
||||
}
|
||||
const template = await parseAndFindServiceTemplates(service)
|
||||
let template = {}
|
||||
if (service.type) {
|
||||
template = await parseAndFindServiceTemplates(service)
|
||||
}
|
||||
return {
|
||||
settings: await listSettings(),
|
||||
service,
|
||||
template,
|
||||
}
|
||||
} catch ({ status, message }) {
|
||||
console.log(status, message)
|
||||
return errorHandler({ status, message })
|
||||
}
|
||||
}
|
||||
@ -218,19 +225,22 @@ export async function saveServiceType(request: FastifyRequest<SaveServiceType>,
|
||||
if (foundTemplate.variables.length > 0) {
|
||||
foundTemplate.variables = foundTemplate.variables.map(variable => {
|
||||
let { id: variableId } = variable;
|
||||
console.log(variableId)
|
||||
if (variableId.startsWith('$$secret_')) {
|
||||
const length = variable?.extras && variable.extras['length']
|
||||
if (variable.defaultValue === '$$generate_password') {
|
||||
variable.value = generatePassword({ length });
|
||||
} else if (variable.defaultValue === '$$generate_passphrase') {
|
||||
variable.value = generatePassword({ length });
|
||||
} else if (!variable.defaultValue) {
|
||||
variable.defaultValue = undefined
|
||||
}
|
||||
}
|
||||
if (variableId.startsWith('$$config_')) {
|
||||
if (variable.defaultValue === '$$generate_username') {
|
||||
variable.value = cuid();
|
||||
} else {
|
||||
variable.value = variable.defaultValue
|
||||
variable.value = variable.defaultValue || ''
|
||||
}
|
||||
}
|
||||
if (variable.value) {
|
||||
@ -246,19 +256,28 @@ export async function saveServiceType(request: FastifyRequest<SaveServiceType>,
|
||||
variable.value = variable.defaultValue
|
||||
for (const generatedVariable of generatedVariables) {
|
||||
let [id, value] = generatedVariable.split('=')
|
||||
variable.value = variable.value.replaceAll(id, value)
|
||||
if (variable.value) {
|
||||
variable.value = variable.value.replaceAll(id, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
return variable
|
||||
})
|
||||
}
|
||||
|
||||
for (const variable of foundTemplate.variables) {
|
||||
if (variable.id.startsWith('$$secret_')) {
|
||||
if (!variable.value) {
|
||||
continue;
|
||||
}
|
||||
await prisma.serviceSecret.create({
|
||||
data: { name: variable.name, value: encrypt(variable.value), service: { connect: { id } } }
|
||||
})
|
||||
}
|
||||
if (variable.id.startsWith('$$config_')) {
|
||||
if (!variable.value) {
|
||||
variable.value = '';
|
||||
}
|
||||
await prisma.serviceSetting.create({
|
||||
data: { name: variable.name, value: variable.value, service: { connect: { id } } }
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user