From 10f61595e18054690cbe657170f5244ae629032a Mon Sep 17 00:00:00 2001 From: jeff Date: Sun, 13 Oct 2024 15:45:33 -0300 Subject: [PATCH] added postgresql support & added a postgres containers --- backend/db.js | 16 +++++ backend/lib/config.js | 19 ++++++ backend/package.json | 1 + backend/setup.js | 10 ++- backend/yarn.lock | 88 ++++++++++++++++++++++++ docker/dev/Dockerfile | 1 + docker/docker-compose.ci.postgresql.yml | 29 ++++++++ docker/docker-compose.dev2.yml | 91 +++++++++++++++++++++++++ 8 files changed, 249 insertions(+), 6 deletions(-) create mode 100644 docker/docker-compose.ci.postgresql.yml create mode 100644 docker/docker-compose.dev2.yml diff --git a/backend/db.js b/backend/db.js index 1a8b1634..cfa107d5 100644 --- a/backend/db.js +++ b/backend/db.js @@ -9,6 +9,22 @@ function generateDbConfig() { if (cfg.engine === 'knex-native') { return cfg.knex; } + if (cfg.engine === 'pg') { + + return { + client: cfg.engine, + connection: { + host: cfg.host, + user: cfg.user, + password: cfg.password, + database: cfg.name, + port: cfg.port + }, + migrations: { + tableName: 'migrations' + } + }; + } return { client: cfg.engine, connection: { diff --git a/backend/lib/config.js b/backend/lib/config.js index b42f9e3c..8ab0e535 100644 --- a/backend/lib/config.js +++ b/backend/lib/config.js @@ -45,6 +45,25 @@ const configure = () => { }; return; } + const envPostgresqlHost = process.env.DB_POSTGRESQL_HOST || null; + const envPostgresqlUser = process.env.DB_POSTGRESQL_USER || null; + const envPostgresqlName = process.env.DB_POSTGRESQL_NAME || null; + if (envPostgresqlHost && envPostgresqlUser && envPostgresqlName) { + // we have enough mysql creds to go with mysql + logger.info('Using POSTGRESQL configuration'); + instance = { + database: { + engine: 'pg', + host: envPostgresqlHost, + port: process.env.DB_POSTGRESQL_PORT || 3306, + user: envPostgresqlUser, + password: process.env.DB_POSTGRESQL_PASSWORD, + name: envPostgresqlName, + }, + keys: getKeys(), + }; + return; + } const envSqliteFile = process.env.DB_SQLITE_FILE || '/data/database.sqlite'; logger.info(`Using Sqlite: ${envSqliteFile}`); diff --git a/backend/package.json b/backend/package.json index 1bc3ef16..46f72dea 100644 --- a/backend/package.json +++ b/backend/package.json @@ -23,6 +23,7 @@ "node-rsa": "^1.0.8", "objection": "3.0.1", "path": "^0.12.7", + "pg": "^8.13.0", "signale": "1.4.0", "sqlite3": "5.1.6", "temp-write": "^4.0.0" diff --git a/backend/setup.js b/backend/setup.js index 9a7b6970..4d39d255 100644 --- a/backend/setup.js +++ b/backend/setup.js @@ -15,11 +15,10 @@ const certbot = require('./lib/certbot'); const setupDefaultUser = () => { return userModel .query() - .select(userModel.raw('COUNT(`id`) as `count`')) + .select('id') .where('is_deleted', 0) - .first() .then((row) => { - if (!row.count) { + if (!row.length || !row[0].id) { // Create a new user and set password let email = process.env.INITIAL_ADMIN_EMAIL || 'admin@example.com'; let password = process.env.INITIAL_ADMIN_PASSWORD || 'changeme'; @@ -77,11 +76,10 @@ const setupDefaultUser = () => { const setupDefaultSettings = () => { return settingModel .query() - .select(settingModel.raw('COUNT(`id`) as `count`')) + .select('id') .where({id: 'default-site'}) - .first() .then((row) => { - if (!row.count) { + if (!row.length || !row[0].id) { settingModel .query() .insert({ diff --git a/backend/yarn.lock b/backend/yarn.lock index 5441a511..9420b8a7 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -2735,11 +2735,67 @@ path@^0.12.7: process "^0.11.1" util "^0.10.3" +pg-cloudflare@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98" + integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q== + pg-connection-string@2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ== +pg-connection-string@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.7.0.tgz#f1d3489e427c62ece022dba98d5262efcb168b37" + integrity sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA== + +pg-int8@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== + +pg-pool@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.7.0.tgz#d4d3c7ad640f8c6a2245adc369bafde4ebb8cbec" + integrity sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g== + +pg-protocol@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.7.0.tgz#ec037c87c20515372692edac8b63cf4405448a93" + integrity sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ== + +pg-types@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" + integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== + dependencies: + pg-int8 "1.0.1" + postgres-array "~2.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.4" + postgres-interval "^1.1.0" + +pg@^8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.13.0.tgz#e3d245342eb0158112553fcc1890a60720ae2a3d" + integrity sha512-34wkUTh3SxTClfoHB3pQ7bIMvw9dpFU1audQQeZG837fmHfHpr14n/AELVDoOYVDW2h5RDWU78tFjkD+erSBsw== + dependencies: + pg-connection-string "^2.7.0" + pg-pool "^3.7.0" + pg-protocol "^1.7.0" + pg-types "^2.1.0" + pgpass "1.x" + optionalDependencies: + pg-cloudflare "^1.1.1" + +pgpass@1.x: + version "1.0.5" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" + integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== + dependencies: + split2 "^4.1.0" + picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -2758,6 +2814,28 @@ pkg-conf@^2.1.0: find-up "^2.0.0" load-json-file "^4.0.0" +postgres-array@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" + integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== + +postgres-bytea@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== + +postgres-date@~1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" + integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== + +postgres-interval@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" + integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== + dependencies: + xtend "^4.0.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -3194,6 +3272,11 @@ socks@^2.6.2: ip "^2.0.0" smart-buffer "^4.2.0" +split2@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -3665,6 +3748,11 @@ xdg-basedir@^4.0.0: resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + y18n@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index 3c21849c..da2f8f06 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -28,6 +28,7 @@ RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager # s6 overlay COPY scripts/install-s6 /tmp/install-s6 RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6 +RUN chmod 644 -R /root/.cache EXPOSE 80 81 443 ENTRYPOINT [ "/init" ] diff --git a/docker/docker-compose.ci.postgresql.yml b/docker/docker-compose.ci.postgresql.yml new file mode 100644 index 00000000..7b4676c8 --- /dev/null +++ b/docker/docker-compose.ci.postgresql.yml @@ -0,0 +1,29 @@ +# WARNING: This is a CI docker-compose file used for building and testing of the entire app, it should not be used for production. +services: + + fullstack: + environment: + DB_POSTGRESQL_HOST: 'db' + DB_POSTGRESQL_PORT: '5432' + DB_POSTGRESQL_USER: 'npm' + DB_POSTGRESQL_PASSWORD: 'npmpass' + DB_POSTGRESQL_NAME: 'npm' + depends_on: + - db-postgresql + + db-postgresql: + image: postgres:14.2-alpine + environment: + POSTGRES_PASSWORD: "npmpass" + POSTGRES_USER: "npm" + POSTGRES_DB: "npm" + ports: + - 5432:5432 + volumes: + - postgres_vol:/var/lib/postgresql/data + networks: + - fulltest + + +volumes: + postgres_vol: diff --git a/docker/docker-compose.dev2.yml b/docker/docker-compose.dev2.yml new file mode 100644 index 00000000..fe9994a2 --- /dev/null +++ b/docker/docker-compose.dev2.yml @@ -0,0 +1,91 @@ +# WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production. +services: + + npm: + image: nginxproxymanager:dev + container_name: npm_core + build: + context: ./ + dockerfile: ./dev/Dockerfile + ports: + - 3080:80 + - 3081:81 + - 3443:443 + networks: + - nginx_proxy_manager + environment: + PUID: 1000 + PGID: 1000 + FORCE_COLOR: 1 + # specifically for dev: + DEBUG: 'true' + DEVELOPMENT: 'true' + LE_STAGING: 'true' + # db: + DB_POSTGRESQL_HOST: 'db' + DB_POSTGRESQL_PORT: '5432' + DB_POSTGRESQL_USER: 'npm' + DB_POSTGRESQL_PASSWORD: 'npmpass' + DB_POSTGRESQL_NAME: 'npm' + # DB_SQLITE_FILE: "/data/database.sqlite" + # DISABLE_IPV6: "true" + volumes: + - npm_data:/data + - le_data:/etc/letsencrypt + - ../backend:/app + - ../frontend:/app/frontend + - ../global:/app/global + depends_on: + - db + working_dir: /app + + db: + image: postgres:14.2-alpine + container_name: npm_db + ports: + - 5432:5432 + networks: + - nginx_proxy_manager + environment: + POSTGRES_PASSWORD: "npmpass" + POSTGRES_USER: "npm" + POSTGRES_DB: "npm" + volumes: + - db_data:/var/lib/postgresql/data + pgadmin: + image: dpage/pgadmin4 + environment: + PGADMIN_DEFAULT_EMAIL: "admin@example.com" + PGADMIN_DEFAULT_PASSWORD: "changeme" + ports: + - 5080:80 + networks: + - nginx_proxy_manager + depends_on: + - db + + + swagger: + image: swaggerapi/swagger-ui:latest + container_name: npm_swagger + ports: + - 3082:80 + environment: + URL: "http://npm:81/api/schema" + PORT: '80' + depends_on: + - npm + +volumes: + npm_data: + name: npm_core_data + le_data: + name: npm_le_data + db_data: + name: npm_db_data + db_data1: + name: npm_db_data1 + +networks: + nginx_proxy_manager: + name: npm_network