diff --git a/.version b/.version index 94f15e9c..0e83a9a9 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.13.1 +2.13.2 diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index fc249ab4..00000000 --- a/Jenkinsfile +++ /dev/null @@ -1,285 +0,0 @@ -import groovy.transform.Field - -@Field -def shOutput = "" -def buildxPushTags = "" - -pipeline { - agent { - label 'docker-multiarch' - } - options { - buildDiscarder(logRotator(numToKeepStr: '5')) - disableConcurrentBuilds() - ansiColor('xterm') - } - environment { - IMAGE = 'nginx-proxy-manager' - BUILD_VERSION = getVersion() - MAJOR_VERSION = '2' - BRANCH_LOWER = "${BRANCH_NAME.toLowerCase().replaceAll('\\\\', '-').replaceAll('/', '-').replaceAll('\\.', '-')}" - BUILDX_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}" - COMPOSE_INTERACTIVE_NO_CLI = 1 - } - stages { - stage('Environment') { - parallel { - stage('Master') { - when { - branch 'master' - } - steps { - script { - buildxPushTags = "-t docker.io/jc21/${IMAGE}:${BUILD_VERSION} -t docker.io/jc21/${IMAGE}:${MAJOR_VERSION} -t docker.io/jc21/${IMAGE}:latest" - } - } - } - stage('Other') { - when { - not { - branch 'master' - } - } - steps { - script { - // Defaults to the Branch name, which is applies to all branches AND pr's - buildxPushTags = "-t docker.io/nginxproxymanager/${IMAGE}-dev:${BRANCH_LOWER}" - } - } - } - stage('Versions') { - steps { - sh 'cat frontend/package.json | jq --arg BUILD_VERSION "${BUILD_VERSION}" \'.version = $BUILD_VERSION\' | sponge frontend/package.json' - sh 'echo -e "\\E[1;36mFrontend Version is:\\E[1;33m $(cat frontend/package.json | jq -r .version)\\E[0m"' - sh 'cat backend/package.json | jq --arg BUILD_VERSION "${BUILD_VERSION}" \'.version = $BUILD_VERSION\' | sponge backend/package.json' - sh 'echo -e "\\E[1;36mBackend Version is:\\E[1;33m $(cat backend/package.json | jq -r .version)\\E[0m"' - sh 'sed -i -E "s/(version-)[0-9]+\\.[0-9]+\\.[0-9]+(-green)/\\1${BUILD_VERSION}\\2/" README.md' - } - } - stage('Docker Login') { - steps { - withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) { - sh 'docker login -u "${duser}" -p "${dpass}"' - } - } - } - } - } - stage('Builds') { - parallel { - stage('Project') { - steps { - script { - // Frontend and Backend - def shStatusCode = sh(label: 'Checking and Building', returnStatus: true, script: ''' - set -e - ./scripts/ci/frontend-build > ${WORKSPACE}/tmp-sh-build 2>&1 - ./scripts/ci/test-and-build > ${WORKSPACE}/tmp-sh-build 2>&1 - ''') - shOutput = readFile "${env.WORKSPACE}/tmp-sh-build" - if (shStatusCode != 0) { - error "${shOutput}" - } - } - } - post { - always { - sh 'rm -f ${WORKSPACE}/tmp-sh-build' - } - failure { - npmGithubPrComment("CI Error:\n\n```\n${shOutput}\n```", true) - } - } - } - stage('Docs') { - steps { - dir(path: 'docs') { - sh 'yarn install' - sh 'yarn build' - } - } - } - } - } - stage('Test Sqlite') { - environment { - COMPOSE_PROJECT_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}_sqlite" - COMPOSE_FILE = 'docker/docker-compose.ci.yml:docker/docker-compose.ci.sqlite.yml' - } - when { - not { - equals expected: 'UNSTABLE', actual: currentBuild.result - } - } - steps { - sh 'rm -rf ./test/results/junit/*' - sh './scripts/ci/fulltest-cypress' - } - post { - always { - // Dumps to analyze later - sh 'mkdir -p debug/sqlite' - sh 'docker logs $(docker compose ps --all -q fullstack) > debug/sqlite/docker_fullstack.log 2>&1' - sh 'docker logs $(docker compose ps --all -q stepca) > debug/sqlite/docker_stepca.log 2>&1' - sh 'docker logs $(docker compose ps --all -q pdns) > debug/sqlite/docker_pdns.log 2>&1' - sh 'docker logs $(docker compose ps --all -q pdns-db) > debug/sqlite/docker_pdns-db.log 2>&1' - sh 'docker logs $(docker compose ps --all -q dnsrouter) > debug/sqlite/docker_dnsrouter.log 2>&1' - junit 'test/results/junit/*' - sh 'docker compose down --remove-orphans --volumes -t 30 || true' - } - unstable { - dir(path: 'test/results') { - archiveArtifacts(allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml') - } - } - } - } - stage('Test Mysql') { - environment { - COMPOSE_PROJECT_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}_mysql" - COMPOSE_FILE = 'docker/docker-compose.ci.yml:docker/docker-compose.ci.mysql.yml' - } - when { - not { - equals expected: 'UNSTABLE', actual: currentBuild.result - } - } - steps { - sh 'rm -rf ./test/results/junit/*' - sh './scripts/ci/fulltest-cypress' - } - post { - always { - // Dumps to analyze later - sh 'mkdir -p debug/mysql' - sh 'docker logs $(docker compose ps --all -q fullstack) > debug/mysql/docker_fullstack.log 2>&1' - sh 'docker logs $(docker compose ps --all -q stepca) > debug/mysql/docker_stepca.log 2>&1' - sh 'docker logs $(docker compose ps --all -q pdns) > debug/mysql/docker_pdns.log 2>&1' - sh 'docker logs $(docker compose ps --all -q pdns-db) > debug/mysql/docker_pdns-db.log 2>&1' - sh 'docker logs $(docker compose ps --all -q dnsrouter) > debug/mysql/docker_dnsrouter.log 2>&1' - junit 'test/results/junit/*' - sh 'docker compose down --remove-orphans --volumes -t 30 || true' - } - unstable { - dir(path: 'test/results') { - archiveArtifacts(allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml') - } - } - } - } - stage('Test Postgres') { - environment { - COMPOSE_PROJECT_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}_postgres" - COMPOSE_FILE = 'docker/docker-compose.ci.yml:docker/docker-compose.ci.postgres.yml' - } - when { - not { - equals expected: 'UNSTABLE', actual: currentBuild.result - } - } - steps { - sh 'rm -rf ./test/results/junit/*' - sh './scripts/ci/fulltest-cypress' - } - post { - always { - // Dumps to analyze later - sh 'mkdir -p debug/postgres' - sh 'docker logs $(docker compose ps --all -q fullstack) > debug/postgres/docker_fullstack.log 2>&1' - sh 'docker logs $(docker compose ps --all -q stepca) > debug/postgres/docker_stepca.log 2>&1' - sh 'docker logs $(docker compose ps --all -q pdns) > debug/postgres/docker_pdns.log 2>&1' - sh 'docker logs $(docker compose ps --all -q pdns-db) > debug/postgres/docker_pdns-db.log 2>&1' - sh 'docker logs $(docker compose ps --all -q dnsrouter) > debug/postgres/docker_dnsrouter.log 2>&1' - sh 'docker logs $(docker compose ps --all -q db-postgres) > debug/postgres/docker_db-postgres.log 2>&1' - sh 'docker logs $(docker compose ps --all -q authentik) > debug/postgres/docker_authentik.log 2>&1' - sh 'docker logs $(docker compose ps --all -q authentik-redis) > debug/postgres/docker_authentik-redis.log 2>&1' - sh 'docker logs $(docke rcompose ps --all -q authentik-ldap) > debug/postgres/docker_authentik-ldap.log 2>&1' - - junit 'test/results/junit/*' - sh 'docker compose down --remove-orphans --volumes -t 30 || true' - } - unstable { - dir(path: 'test/results') { - archiveArtifacts(allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml') - } - } - } - } - stage('MultiArch Build') { - when { - not { - equals expected: 'UNSTABLE', actual: currentBuild.result - } - } - steps { - sh "./scripts/buildx --push ${buildxPushTags}" - } - } - stage('Docs / Comment') { - parallel { - stage('Docs Job') { - when { - allOf { - branch pattern: "^(develop|master)\$", comparator: "REGEXP" - not { - equals expected: 'UNSTABLE', actual: currentBuild.result - } - } - } - steps { - build wait: false, job: 'nginx-proxy-manager-docs', parameters: [string(name: 'docs_branch', value: "$BRANCH_NAME")] - } - } - stage('PR Comment') { - when { - allOf { - changeRequest() - not { - equals expected: 'UNSTABLE', actual: currentBuild.result - } - } - } - steps { - script { - npmGithubPrComment("""Docker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/nginxproxymanager/${IMAGE}-dev): -``` -nginxproxymanager/${IMAGE}-dev:${BRANCH_LOWER} -``` - -> [!NOTE] -> Ensure you backup your NPM instance before testing this image! Especially if there are database changes. -> This is a different docker image namespace than the official image. - -> [!WARNING] -> Changes and additions to DNS Providers require verification by at least 2 members of the community! -""", true) - } - } - } - } - } - } - post { - always { - sh 'echo Reverting ownership' - sh 'docker run --rm -v "$(pwd):/data" jc21/ci-tools chown -R "$(id -u):$(id -g)" /data' - printResult(true) - } - failure { - archiveArtifacts(artifacts: 'debug/**/*.*', allowEmptyArchive: true) - } - unstable { - archiveArtifacts(artifacts: 'debug/**/*.*', allowEmptyArchive: true) - } - } -} - -def getVersion() { - ver = sh(script: 'cat .version', returnStdout: true) - return ver.trim() -} - -def getCommit() { - ver = sh(script: 'git log -n 1 --format=%h', returnStdout: true) - return ver.trim() -} diff --git a/README.md b/README.md index 669be713..683c9681 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@
-
+
diff --git a/backend/db.js b/backend/db.js
index bd74e518..bf540f8a 100644
--- a/backend/db.js
+++ b/backend/db.js
@@ -1,6 +1,8 @@
import knex from "knex";
import {configGet, configHas} from "./lib/config.js";
+let instance = null;
+
const generateDbConfig = () => {
if (!configHas("database")) {
throw new Error(
@@ -30,4 +32,11 @@ const generateDbConfig = () => {
};
};
-export default knex(generateDbConfig());
+const getInstance = () => {
+ if (!instance) {
+ instance = knex(generateDbConfig());
+ }
+ return instance;
+}
+
+export default getInstance;
diff --git a/backend/migrate.js b/backend/migrate.js
index dd3f1b61..4c99cab6 100644
--- a/backend/migrate.js
+++ b/backend/migrate.js
@@ -2,9 +2,9 @@ import db from "./db.js";
import { migrate as logger } from "./logger.js";
const migrateUp = async () => {
- const version = await db.migrate.currentVersion();
+ const version = await db().migrate.currentVersion();
logger.info("Current database version:", version);
- return await db.migrate.latest({
+ return await db().migrate.latest({
tableName: "migrations",
directory: "migrations",
});
diff --git a/backend/models/access_list.js b/backend/models/access_list.js
index 98016a17..427d447d 100644
--- a/backend/models/access_list.js
+++ b/backend/models/access_list.js
@@ -10,7 +10,7 @@ import now from "./now_helper.js";
import ProxyHostModel from "./proxy_host.js";
import User from "./user.js";
-Model.knex(db);
+Model.knex(db());
const boolFields = ["is_deleted", "satisfy_any", "pass_auth"];
diff --git a/backend/models/access_list_auth.js b/backend/models/access_list_auth.js
index a4fd85a5..75bf4352 100644
--- a/backend/models/access_list_auth.js
+++ b/backend/models/access_list_auth.js
@@ -6,7 +6,7 @@ import db from "../db.js";
import accessListModel from "./access_list.js";
import now from "./now_helper.js";
-Model.knex(db);
+Model.knex(db());
class AccessListAuth extends Model {
$beforeInsert() {
diff --git a/backend/models/access_list_client.js b/backend/models/access_list_client.js
index 4b63aec9..91165fe1 100644
--- a/backend/models/access_list_client.js
+++ b/backend/models/access_list_client.js
@@ -6,7 +6,7 @@ import db from "../db.js";
import accessListModel from "./access_list.js";
import now from "./now_helper.js";
-Model.knex(db);
+Model.knex(db());
class AccessListClient extends Model {
$beforeInsert() {
diff --git a/backend/models/audit-log.js b/backend/models/audit-log.js
index a9b2d563..6e2d398f 100644
--- a/backend/models/audit-log.js
+++ b/backend/models/audit-log.js
@@ -6,7 +6,7 @@ import db from "../db.js";
import now from "./now_helper.js";
import User from "./user.js";
-Model.knex(db);
+Model.knex(db());
class AuditLog extends Model {
$beforeInsert() {
diff --git a/backend/models/auth.js b/backend/models/auth.js
index 4ba50b41..e8af582d 100644
--- a/backend/models/auth.js
+++ b/backend/models/auth.js
@@ -8,7 +8,7 @@ import { convertBoolFieldsToInt, convertIntFieldsToBool } from "../lib/helpers.j
import now from "./now_helper.js";
import User from "./user.js";
-Model.knex(db);
+Model.knex(db());
const boolFields = ["is_deleted"];
diff --git a/backend/models/certificate.js b/backend/models/certificate.js
index 9ad03c89..ad6e0a65 100644
--- a/backend/models/certificate.js
+++ b/backend/models/certificate.js
@@ -11,7 +11,7 @@ import redirectionHostModel from "./redirection_host.js";
import streamModel from "./stream.js";
import userModel from "./user.js";
-Model.knex(db);
+Model.knex(db());
const boolFields = ["is_deleted"];
diff --git a/backend/models/dead_host.js b/backend/models/dead_host.js
index 56807012..0acf7ca7 100644
--- a/backend/models/dead_host.js
+++ b/backend/models/dead_host.js
@@ -8,7 +8,7 @@ import Certificate from "./certificate.js";
import now from "./now_helper.js";
import User from "./user.js";
-Model.knex(db);
+Model.knex(db());
const boolFields = ["is_deleted", "ssl_forced", "http2_support", "enabled", "hsts_enabled", "hsts_subdomains"];
diff --git a/backend/models/now_helper.js b/backend/models/now_helper.js
index 4dc71cea..293dcc72 100644
--- a/backend/models/now_helper.js
+++ b/backend/models/now_helper.js
@@ -2,7 +2,7 @@ import { Model } from "objection";
import db from "../db.js";
import { isSqlite } from "../lib/config.js";
-Model.knex(db);
+Model.knex(db());
export default () => {
if (isSqlite()) {
diff --git a/backend/models/proxy_host.js b/backend/models/proxy_host.js
index 119fe2b7..b6ce6361 100644
--- a/backend/models/proxy_host.js
+++ b/backend/models/proxy_host.js
@@ -9,7 +9,7 @@ import Certificate from "./certificate.js";
import now from "./now_helper.js";
import User from "./user.js";
-Model.knex(db);
+Model.knex(db());
const boolFields = [
"is_deleted",
diff --git a/backend/models/redirection_host.js b/backend/models/redirection_host.js
index bb397baa..46c73017 100644
--- a/backend/models/redirection_host.js
+++ b/backend/models/redirection_host.js
@@ -8,7 +8,7 @@ import Certificate from "./certificate.js";
import now from "./now_helper.js";
import User from "./user.js";
-Model.knex(db);
+Model.knex(db());
const boolFields = [
"is_deleted",
diff --git a/backend/models/setting.js b/backend/models/setting.js
index 0e0d6f4f..56f7dc5a 100644
--- a/backend/models/setting.js
+++ b/backend/models/setting.js
@@ -4,7 +4,7 @@
import { Model } from "objection";
import db from "../db.js";
-Model.knex(db);
+Model.knex(db());
class Setting extends Model {
$beforeInsert () {
diff --git a/backend/models/stream.js b/backend/models/stream.js
index 92d335ff..5f61945a 100644
--- a/backend/models/stream.js
+++ b/backend/models/stream.js
@@ -5,7 +5,7 @@ import Certificate from "./certificate.js";
import now from "./now_helper.js";
import User from "./user.js";
-Model.knex(db);
+Model.knex(db());
const boolFields = ["is_deleted", "enabled", "tcp_forwarding", "udp_forwarding"];
diff --git a/backend/models/user.js b/backend/models/user.js
index 64aed05d..68a31446 100644
--- a/backend/models/user.js
+++ b/backend/models/user.js
@@ -7,7 +7,7 @@ import { convertBoolFieldsToInt, convertIntFieldsToBool } from "../lib/helpers.j
import now from "./now_helper.js";
import UserPermission from "./user_permission.js";
-Model.knex(db);
+Model.knex(db());
const boolFields = ["is_deleted", "is_disabled"];
diff --git a/backend/models/user_permission.js b/backend/models/user_permission.js
index 49ea2d90..d8784717 100644
--- a/backend/models/user_permission.js
+++ b/backend/models/user_permission.js
@@ -5,7 +5,7 @@ import { Model } from "objection";
import db from "../db.js";
import now from "./now_helper.js";
-Model.knex(db);
+Model.knex(db());
class UserPermission extends Model {
$beforeInsert () {
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 913f79d5..88ce95ed 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -4,7 +4,6 @@
# This file assumes that the frontend has been built using ./scripts/frontend-build
FROM nginxproxymanager/testca AS testca
-FROM letsencrypt/pebble AS pebbleca
FROM nginxproxymanager/nginx-full:certbot-node
ARG TARGETPLATFORM
@@ -46,7 +45,6 @@ RUN yarn install \
# add late to limit cache-busting by modifications
COPY docker/rootfs /
-COPY --from=pebbleca /test/certs/pebble.minica.pem /etc/ssl/certs/pebble.minica.pem
COPY --from=testca /home/step/certs/root_ca.crt /etc/ssl/certs/NginxProxyManager.crt
# Remove frontend service not required for prod, dev nginx config as well
diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile
index 45d97a32..f0f5ec60 100644
--- a/docker/dev/Dockerfile
+++ b/docker/dev/Dockerfile
@@ -1,5 +1,4 @@
FROM nginxproxymanager/testca AS testca
-FROM letsencrypt/pebble AS pebbleca
FROM nginxproxymanager/nginx-full:certbot-node
LABEL maintainer="Jamie Curnow