From 392c5104f409a3b51b91504b3f8db2ef81b13183 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Sat, 25 Nov 2023 00:24:53 -0800 Subject: [PATCH 01/25] Add files via upload --- app.js | 24 +++++++++++++----------- package-lock.json | 25 ++++++++++++++----------- package.json | 2 +- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/app.js b/app.js index 66518b6..e9b782d 100644 --- a/app.js +++ b/app.js @@ -1,7 +1,17 @@ const express = require("express"); -const session = require("express-session"); -const redis = require('connect-redis'); const app = express(); +const session = require("express-session"); +const redis = require('redis'); +const RedisStore = require("connect-redis").default; +const redisClient = redis.createClient({ + url: "redis://DweebCache:6379", + password: process.env.REDIS_PASS, +}); +redisClient.connect().catch(console.log); +let redisStore = new RedisStore({ + client: redisClient, +}); + const routes = require("./routes"); const { serverStats, containerList, containerStats, containerAction } = require('./functions/system_information'); @@ -10,16 +20,8 @@ const { RefreshSites } = require('./controllers/site_actions'); let sent_list, clicked; app.locals.site_list = ''; -const redisClient = require('redis').createClient({ - url: 'redis://DweebCache:6379', - password: process.env.REDIS_PASS, - legacyMode:true -}); -redisClient.connect().catch(console.log); -const RedisStore = redis(session); - const sessionMiddleware = session({ - store:new RedisStore({client:redisClient}), + store: redisStore, secret: "keyboard cat", resave: false, saveUninitialized: false, diff --git a/package-lock.json b/package-lock.json index 58e6071..ceee248 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "bcrypt": "^5.1.0", "child_process": "^1.0.2", - "connect-redis": "^6.1.3", + "connect-redis": "^7.1.0", "dockerode": "^4.0.0", "dockerode-compose": "^1.4.0", "ejs": "^3.1.9", @@ -173,9 +173,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "20.9.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.4.tgz", - "integrity": "sha512-wmyg8HUhcn6ACjsn8oKYjkN/zUzQeNtMy44weTJSM6p4MMzEOuKbA3OjJ267uPCOW7Xex9dyrNTful8XTQYoDA==", + "version": "20.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.0.tgz", + "integrity": "sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==", "dependencies": { "undici-types": "~5.26.4" } @@ -565,11 +565,14 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/connect-redis": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-6.1.3.tgz", - "integrity": "sha512-aaNluLlAn/3JPxRwdzw7lhvEoU6Enb+d83xnokUNhC9dktqBoawKWL+WuxinxvBLTz6q9vReTnUDnUslaz74aw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-7.1.0.tgz", + "integrity": "sha512-UaqO1EirWjON2ENsyau7N5lbkrdYBpS6mYlXSeff/OYXsd6EGZ+SXSmNPoljL2PSua8fgjAEaldSA73PMZQ9Eg==", "engines": { - "node": ">=12" + "node": ">=16" + }, + "peerDependencies": { + "express-session": ">=1" } }, "node_modules/console-control-strings": { @@ -2403,9 +2406,9 @@ } }, "node_modules/systeminformation": { - "version": "5.21.17", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.21.17.tgz", - "integrity": "sha512-JZYRCbIjk3WuBV59A9/rTla2rROX+aAJ9uo2Z1dI+bjieORcukClN8rlM1zE9NYKpULSbaGc+KKct/870lO0DA==", + "version": "5.21.18", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.21.18.tgz", + "integrity": "sha512-PEoWd95nI5170rvIk4fagLH0SmzwfGt18w0+ex1Ljb2bSXvDs9PQdLNexMazL5L6Pzd6wxlpoWUAjX+hNRKN7g==", "os": [ "darwin", "linux", diff --git a/package.json b/package.json index 41d539f..768113d 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "dependencies": { "bcrypt": "^5.1.0", "child_process": "^1.0.2", - "connect-redis": "^6.1.3", + "connect-redis": "^7.1.0", "dockerode": "^4.0.0", "dockerode-compose": "^1.4.0", "ejs": "^3.1.9", From 1a546999b941d7e00e40974ad45a1a80f512f724 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Sat, 25 Nov 2023 00:29:22 -0800 Subject: [PATCH 02/25] systeminformation 5.21.17 to 5.21.18 last commit included update to connect-redis 7.1.0 systeminformation 5.21.17 to 5.21.18 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index ceee248..4859665 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "sequelize": "^6.35.1", "socket.io": "^4.6.1", "sqlite3": "^5.1.6", - "systeminformation": "^5.21.17" + "systeminformation": "^5.21.18" } }, "node_modules/@balena/dockerignore": { diff --git a/package.json b/package.json index 768113d..a63f313 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "sequelize": "^6.35.1", "socket.io": "^4.6.1", "sqlite3": "^5.1.6", - "systeminformation": "^5.21.17" + "systeminformation": "^5.21.18" }, "description": "" } From b1d9ff38b4f5a2803973e5dd71a602a29fda8f5b Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Sat, 25 Nov 2023 00:32:34 -0800 Subject: [PATCH 03/25] removed "no frameworks" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fa40689..e566c25 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Pre-Pre-Pre-Pre-Pre Alpha v0.06 ( :fire: Experimental. Don't install on any serv * [ ] User pages: Shortcuts, Requests, Support. (planned) * [x] Support for Windows, Linux, and MacOS. * [ ] Import compose files. (planned) -* [x] Pure javascript. No frameworks or typescript. +* [x] Javascript, Node.js, and Express. * [x] Templates.json maintains compatability with Portainer, allowing you to use the template without needing to use DweebUI. * [ ] Manage your Docker networks, images, and volumes. (planned) * [ ] Preset variables. (planned) From fe5359ccf47f72473ac11b97d8371dde4e7702b4 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Sun, 26 Nov 2023 17:18:43 -0800 Subject: [PATCH 04/25] env.PORT DweebUI port can be changed from compose file. --- compose.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compose.yaml b/compose.yaml index 122a373..9d2123f 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,9 +1,9 @@ services: dweebui: container_name: DweebUI - image: lllllllillllllillll/dweebui:v0.06 + image: lllllllillllllillll/dweebui:v0.07-dev environment: - NODE_ENV: production + PORT: 8000 REDIS_PASS: replace_with_password_for_redis # Proxy_Manager: enabled restart: unless-stopped @@ -28,4 +28,4 @@ services: volumes: dweebui: cache: - caddyfiles: + caddyfiles: \ No newline at end of file From ef2157af1f7827ec1926c5777d8c5138eaa50991 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Sun, 26 Nov 2023 17:23:50 -0800 Subject: [PATCH 05/25] updated compose and credits --- README.md | 62 +++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index e566c25..720d5a2 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # DweebUI DweebUI is a simple Docker web interface created with javascript and node.js -Pre-Pre-Pre-Pre-Pre Alpha v0.06 ( :fire: Experimental. Don't install on any servers you care about :fire: ) +Pre-Pre-Pre-Pre-Pre Alpha v0.07 ( :fire: Experimental. Don't install on any servers you care about :fire: ) [![GitHub Stars](https://img.shields.io/github/stars/lllllllillllllillll/DweebUI)](https://github.com/lllllllillllllillll) [![GitHub License](https://img.shields.io/github/license/lllllllillllllillll/DweebUI)](https://github.com/lllllllillllllillll/DweebUI/blob/main/LICENSE) @@ -39,36 +39,36 @@ Pre-Pre-Pre-Pre-Pre Alpha v0.06 ( :fire: Experimental. Don't install on any serv * Docker compose.yaml: ``` services: - dweebui: - container_name: DweebUI - image: lllllllillllllillll/dweebui:v0.06 - environment: - NODE_ENV: production - REDIS_PASS: replace_with_password_for_redis - # Proxy_Manager: enabled - restart: unless-stopped - ports: - - 8000:8000 - depends_on: - - cache - links: - - cache - volumes: - - dweebui:/app - - caddyfiles:/app/caddyfiles - - /var/run/docker.sock:/var/run/docker.sock - cache: - container_name: DweebCache - image: redis:6.2-alpine - restart: always - command: redis-server --save 20 1 --loglevel warning --requirepass replace_with_password_for_redis - volumes: - - cache:/data +  dweebui: +    container_name: DweebUI +    image: lllllllillllllillll/dweebui:v0.07-dev +    environment: +      PORT: 8000 +      REDIS_PASS: replace_with_password_for_redis +      # Proxy_Manager: enabled +    restart: unless-stopped +    ports: +      - 8000:8000 +    depends_on: +      - cache +    links: +      - cache +    volumes: +      - dweebui:/app +      - caddyfiles:/app/caddyfiles +      - /var/run/docker.sock:/var/run/docker.sock +  cache: +    container_name: DweebCache +    image: redis:6.2-alpine +    restart: always +    command: redis-server --save 20 1 --loglevel warning --requirepass replace_with_password_for_redis +    volumes: +      - cache:/data volumes: - dweebui: - cache: - caddyfiles: +  dweebui: +  cache: +  caddyfiles: ``` * Using setup.sh: @@ -83,5 +83,5 @@ sudo ./setup.sh ## Credit * UI was built using HTML and CSS elements from https://tabler.io/ -* Apps template based on Portainer template provided by Lissy93 here: https://github.com/Lissy93/portainer-templates -* Most of the app icons were sourced from Walkxcode's dashboard icons here: https://github.com/walkxcode/dashboard-icons +* Apps template based on Portainer template provided by Lissy93: https://github.com/Lissy93/portainer-templates +* Icons from Walkxcode with some renames and additions: https://github.com/walkxcode/dashboard-icons From ca8a40c06537e5ad4d34f29c7ae47f24324d6ce4 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Sun, 26 Nov 2023 17:27:10 -0800 Subject: [PATCH 06/25] removed snake_case from app.js renamed function system_information.js to system.js --- app.js | 65 ++++----- components/dashCard.js | 61 ++++----- controllers/site_actions.js | 2 +- functions/compose.js | 205 ++++++++++++++++++++++++++++ functions/package_manager.js | 8 +- functions/system.js | 256 +++++++++++++++++++++++++++++++++++ routes/index.js | 9 +- 7 files changed, 530 insertions(+), 76 deletions(-) create mode 100644 functions/compose.js create mode 100644 functions/system.js diff --git a/app.js b/app.js index e9b782d..4b201cd 100644 --- a/app.js +++ b/app.js @@ -1,25 +1,25 @@ +// Express const express = require("express"); const app = express(); const session = require("express-session"); +const PORT = process.env.PORT || 8000; + +// Redis const redis = require('redis'); const RedisStore = require("connect-redis").default; -const redisClient = redis.createClient({ - url: "redis://DweebCache:6379", - password: process.env.REDIS_PASS, -}); +const redisClient = redis.createClient({ url: "redis://DweebCache:6379", password: process.env.REDIS_PASS, }); redisClient.connect().catch(console.log); -let redisStore = new RedisStore({ - client: redisClient, -}); +let redisStore = new RedisStore({ client: redisClient }); +// Routes const routes = require("./routes"); -const { serverStats, containerList, containerStats, containerAction } = require('./functions/system_information'); -const { RefreshSites } = require('./controllers/site_actions'); - -let sent_list, clicked; +// Functions and variables +const { serverStats, containerList, containerStats, containerAction } = require('./functions/system'); +let sentList, clicked; app.locals.site_list = ''; +// Configure Session const sessionMiddleware = session({ store: redisStore, secret: "keyboard cat", @@ -28,10 +28,11 @@ const sessionMiddleware = session({ cookie:{ secure:false, // Only set to true if you are using HTTPS. httpOnly:false, // Only set to true if you are using HTTPS. - maxAge:3600000 * 8// Session max age in milliseconds. 3600000 = 1 hour. + maxAge:3600000 * 8 // Session max age in milliseconds. 3600000 = 1 hour. } }) +// Middleware app.set('view engine', 'ejs'); app.use([ express.static("public"), @@ -41,49 +42,49 @@ app.use([ routes ]); -const server = app.listen(8000, async () => { - console.log(`App listening on port 8000`); +// Start Express server +const server = app.listen(PORT, async () => { + console.log(`App listening on port ${PORT}`); }); +// Start Socket.io const io = require('socket.io')(server); io.engine.use(sessionMiddleware); - io.on('connection', (socket) => { - // set user session + + // Set user session const user_session = socket.request.session; console.log(`${user_session.user} connected from ${socket.handshake.headers.host} ${socket.handshake.address}`); - // check if a list of containers needs to be sent - if (sent_list != null) { socket.emit('cards', sent_list); } - - // check if an install card has to be sent + // Check if a list of containers or an install card needs to be sent + if (sentList != null) { socket.emit('cards', sentList); } if((app.locals.install != '') && (app.locals.install != null)){ socket.emit('install', app.locals.install); } - // send server metrics + // Send server metrics let ServerStats = setInterval(async () => { socket.emit('metrics', await serverStats()); }, 1000); - // send container list + // Send list of containers let ContainerList = setInterval(async () => { - let card_list = await containerList(); - if (sent_list !== card_list) { - sent_list = card_list; + let cardList = await containerList(); + if (sentList !== cardList) { + sentList = cardList; app.locals.install = ''; - socket.emit('cards', card_list); + socket.emit('cards', cardList); } }, 1000); - // send container metrics + // Send container metrics let ContainerStats = setInterval(async () => { - let container_stats = await containerStats(); - for (let i = 0; i < container_stats.length; i++) { - socket.emit('container_stats', container_stats[i]); + let stats = await containerStats(); + for (let i = 0; i < stats.length; i++) { + socket.emit('containerStats', stats[i]); } }, 1000); - // play/pause/stop/restart container + // Container controls socket.on('clicked', (data) => { if (clicked == true) { return; } clicked = true; let buttonPress = { @@ -96,7 +97,7 @@ io.on('connection', (socket) => { containerAction(buttonPress); clicked = false; }); - + socket.on('disconnect', () => { clearInterval(ServerStats); clearInterval(ContainerList); diff --git a/components/dashCard.js b/components/dashCard.js index fe4ea19..44d2e8a 100644 --- a/components/dashCard.js +++ b/components/dashCard.js @@ -270,50 +270,35 @@ module.exports.dashCard = function dashCard(data) { diff --git a/controllers/site_actions.js b/controllers/site_actions.js index 2d569a3..0d15d4c 100644 --- a/controllers/site_actions.js +++ b/controllers/site_actions.js @@ -1,7 +1,7 @@ const { readFileSync, writeFileSync, appendFileSync, readdirSync } = require('fs'); const { execSync } = require("child_process"); const { siteCard } = require('../components/siteCard'); -const { containerExec } = require('../functions/system_information') +const { containerExec } = require('../functions/system') exports.AddSite = async function (req, res) { diff --git a/functions/compose.js b/functions/compose.js new file mode 100644 index 0000000..153f982 --- /dev/null +++ b/functions/compose.js @@ -0,0 +1,205 @@ +const { writeFileSync, mkdirSync, readFileSync } = require("fs"); +const yaml = require('js-yaml'); + +const { exec, execSync } = require("child_process"); + +const { docker } = require('./system'); + +var DockerodeCompose = require('dockerode-compose'); + + +module.exports.install = async function (data) { + + console.log(`[Start of install function]`); + + let { service_name, name, image, command_check, command, net_mode, restart_policy } = data; + let { port0, port1, port2, port3, port4, port5 } = data; + let { volume0, volume1, volume2, volume3, volume4, volume5 } = data; + let { env0, env1, env2, env3, env4, env5, env6, env7, env8, env9, env10, env11 } = data; + let { label0, label1, label2, label3, label4, label5, label6, label7, label8, label9, label10, label11 } = data; + + + if ((service_name.includes('caddy')) || (name.includes('caddy'))) { + req.app.locals.caddy = 'enabled'; + } + + let docker_volumes = []; + + if (image.startsWith('https://')){ + mkdirSync(`./appdata/${name}`, { recursive: true }); + execSync(`curl -o ./appdata/${name}/${name}_stack.yml -L ${image}`); + console.log(`Downloaded stackfile: ${image}`); + let stackfile = yaml.load(readFileSync(`./appdata/${name}/${name}_stack.yml`, 'utf8')); + let services = Object.keys(stackfile.services); + + for ( let i = 0; i < services.length; i++ ) { + try { + console.log(stackfile.services[Object.keys(stackfile.services)[i]].environment); + } catch { console.log('no env') } + } + + } else { + + let compose_file = `version: '3'`; + compose_file += `\nservices:` + compose_file += `\n ${service_name}:` + compose_file += `\n container_name: ${name}`; + compose_file += `\n image: ${image}`; + + // Command + if (command_check == 'on') { + compose_file += `\n command: ${command}` + } + + // Network mode + if (net_mode == 'host') { + compose_file += `\n network_mode: 'host'` + } + else if (net_mode != 'host' && net_mode != 'docker') { + compose_file += `\n network_mode: '${net_mode}'` + } + + // Restart policy + if (restart_policy != '') { + compose_file += `\n restart: ${restart_policy}` + } + + // Ports + if ((port0 == 'on' || port1 == 'on' || port2 == 'on' || port3 == 'on' || port4 == 'on' || port5 == 'on') && (net_mode != 'host')) { + compose_file += `\n ports:` + + for (let i = 0; i < 6; i++) { + if (data[`port${i}`] == 'on') { + compose_file += `\n - ${data[`port_${i}_external`]}:${data[`port_${i}_internal`]}/${data[`port_${i}_protocol`]}` + } + } + } + + // Volumes + if (volume0 == 'on' || volume1 == 'on' || volume2 == 'on' || volume3 == 'on' || volume4 == 'on' || volume5 == 'on') { + compose_file += `\n volumes:` + + for (let i = 0; i < 6; i++) { + + // if volume is on and neither bind or container is empty, it's a bind mount (ex /mnt/user/appdata/config:/config ) + if ((data[`volume${i}`] == 'on') && (data[`volume_${i}_bind`] != '') && (data[`volume_${i}_container`] != '')) { + compose_file += `\n - ${data[`volume_${i}_bind`]}:${data[`volume_${i}_container`]}:${data[`volume_${i}_readwrite`]}` + } + + // if bind is empty create a docker volume (ex container_name_config:/config) convert any '/' in container name to '_' + else if ((data[`volume${i}`] == 'on') && (data[`volume_${i}_bind`] == '') && (data[`volume_${i}_container`] != '')) { + let volume_name = data[`volume_${i}_container`].replace(/\//g, '_'); + compose_file += `\n - ${name}_${volume_name}:${data[`volume_${i}_container`]}:${data[`volume_${i}_readwrite`]}` + docker_volumes.push(`${name}_${volume_name}`); + } + } + } + + // Environment variables + if (env0 == 'on' || env1 == 'on' || env2 == 'on' || env3 == 'on' || env4 == 'on' || env5 == 'on' || env6 == 'on' || env7 == 'on' || env8 == 'on' || env9 == 'on' || env10 == 'on' || env11 == 'on') { + compose_file += `\n environment:` + } + for (let i = 0; i < 12; i++) { + if (data[`env${i}`] == 'on') { + compose_file += `\n - ${data[`env_${i}_name`]}=${data[`env_${i}_default`]}` + + } + } + + // Add labels + if (label0 == 'on' || label1 == 'on' || label2 == 'on' || label3 == 'on' || label4 == 'on' || label5 == 'on' || label6 == 'on' || label7 == 'on' || label8 == 'on' || label9 == 'on' || label10 == 'on' || label11 == 'on') { + compose_file += `\n labels:` + } + for (let i = 0; i < 12; i++) { + if (data[`label${i}`] == 'on') { + compose_file += `\n - ${data[`label_${i}_name`]}=${data[`label_${i}_value`]}` + } + } + + // Add privileged mode + + if (data.privileged == 'on') { + compose_file += `\n privileged: true` + } + + + // Add hardware acceleration to the docker-compose file if one of the environment variables has the label DRINODE + if (env0 == 'on' || env1 == 'on' || env2 == 'on' || env3 == 'on' || env4 == 'on' || env5 == 'on' || env6 == 'on' || env7 == 'on' || env8 == 'on' || env9 == 'on' || env10 == 'on' || env11 == 'on') { + for (let i = 0; i < 12; i++) { + if (data[`env${i}`] == 'on') { + if (data[`env_${i}_name`] == 'DRINODE') { + compose_file += `\n deploy:` + compose_file += `\n resources:` + compose_file += `\n reservations:` + compose_file += `\n devices:` + compose_file += `\n - driver: nvidia` + compose_file += `\n count: 1` + compose_file += `\n capabilities: [gpu]` + } + } + } + } + + + // add any docker volumes to the docker-compose file + if ( docker_volumes.length > 0 ) { + compose_file += `\n` + compose_file += `\nvolumes:` + + // check docker_volumes for duplicates and remove them completely + docker_volumes = docker_volumes.filter((item, index) => docker_volumes.indexOf(item) === index) + + for (let i = 0; i < docker_volumes.length; i++) { + if ( docker_volumes[i] != '') { + compose_file += `\n ${docker_volumes[i]}:` + } + } + } + + try { + mkdirSync(`./appdata/${name}`, { recursive: true }); + writeFileSync(`./appdata/${name}/docker-compose.yml`, compose_file, function (err) { console.log(err) }); + + } catch { console.log('error creating directory or compose file') } + + try { + var compose = new DockerodeCompose(docker, `./appdata/${name}/docker-compose.yml`, `${name}`); + + (async () => { + await compose.pull(); + await compose.up(); + })(); + + } catch { console.log('error running compose file')} + + } + + +} + + + +module.exports.uninstall = async function (data) { + + + if (data.confirm == 'Yes') { + + + var containerName = docker.getContainer(`${data.service_name}`); + + try { + containerName.stop(function (err, data) { + if (data) { + containerName.remove(function (err, data) { + }); + } + }); + } catch { + containerName.remove(function (err, data) { + }); + } + + } + + +} \ No newline at end of file diff --git a/functions/package_manager.js b/functions/package_manager.js index 31fe1a0..153f982 100644 --- a/functions/package_manager.js +++ b/functions/package_manager.js @@ -3,7 +3,8 @@ const yaml = require('js-yaml'); const { exec, execSync } = require("child_process"); -const { docker } = require('./system_information'); +const { docker } = require('./system'); + var DockerodeCompose = require('dockerode-compose'); @@ -17,6 +18,11 @@ module.exports.install = async function (data) { let { env0, env1, env2, env3, env4, env5, env6, env7, env8, env9, env10, env11 } = data; let { label0, label1, label2, label3, label4, label5, label6, label7, label8, label9, label10, label11 } = data; + + if ((service_name.includes('caddy')) || (name.includes('caddy'))) { + req.app.locals.caddy = 'enabled'; + } + let docker_volumes = []; if (image.startsWith('https://')){ diff --git a/functions/system.js b/functions/system.js new file mode 100644 index 0000000..9f941e8 --- /dev/null +++ b/functions/system.js @@ -0,0 +1,256 @@ +const { currentLoad, mem, networkStats, fsSize, dockerContainerStats } = require('systeminformation'); +var Docker = require('dockerode'); +var docker = new Docker({ socketPath: '/var/run/docker.sock' }); +const { dashCard } = require('../components/dashCard'); + +// export docker +module.exports.docker = docker; + +module.exports.serverStats = async function () { + const cpuUsage = await currentLoad(); + const ramUsage = await mem(); + const netUsage = await networkStats(); + const diskUsage = await fsSize(); + + const info = { + cpu: Math.round(cpuUsage.currentLoad), + ram: Math.round((ramUsage.active / ramUsage.total) * 100), + tx: netUsage[0].tx_bytes, + rx: netUsage[0].rx_bytes, + disk: diskUsage[0].use, + }; + + return info; +} + + + +module.exports.containerList = async function () { + let card_list = ''; + + const data = await docker.listContainers({ all: true }); + for (const container of data) { + + + if ((container.Names[0].slice(1) != 'DweebUI') && (container.Names[0].slice(1) != 'DweebCache')) { + + let imageVersion = container.Image.split('/'); + let service = imageVersion[imageVersion.length - 1].split(':')[0]; + + let containerId = docker.getContainer(container.Id); + let containerInfo = await containerId.inspect(); + + // Get ports ////////////////////////// + let ports_list = []; + try { + for (const [key, value] of Object.entries(containerInfo.HostConfig.PortBindings)) { + let ports = { + check : 'checked', + external: value[0].HostPort, + internal: key.split('/')[0], + protocol: key.split('/')[1] + } + ports_list.push(ports); + } + } catch { console.log('no ports') } + + for (let i = 0; i < 12; i++) { + if (ports_list[i] == undefined) { + let ports = { + check : '', + external: '', + internal: '', + protocol: '' + } + ports_list[i] = ports; + } + } ///////////////////////////////////// + + + // Get volumes //////////////////////// + let volumes_list = []; + try { for (const [key, value] of Object.entries(containerInfo.HostConfig.Binds)) { + let volumes = { + check : 'checked', + bind: value.split(':')[0], + container: value.split(':')[1], + readwrite: value.split(':')[2] + } + volumes_list.push(volumes); + }} catch { console.log('no volumes') } + for (let i = 0; i < 12; i++) { + if (volumes_list[i] == undefined) { + let volumes = { + check : '', + bind: '', + container: '', + readwrite: '' + } + volumes_list[i] = volumes; + } + } ///////////////////////////////////// + + + // Get environment variables. + let environment_variables = []; + try { for (const [key, value] of Object.entries(containerInfo.Config.Env)) { + let env = { + check : 'checked', + name: value.split('=')[0], + default: value.split('=')[1] + } + environment_variables.push(env); + }} catch { console.log('no env') } + for (let i = 0; i < 12; i++) { + if (environment_variables[i] == undefined) { + let env = { + check : '', + name: '', + default: '' + } + environment_variables[i] = env; + } + } + + // Get labels. + let labels = []; + for (const [key, value] of Object.entries(containerInfo.Config.Labels)) { + let label = { + check : 'checked', + name: key, + value: value + } + labels.push(label); + } + for (let i = 0; i < 12; i++) { + if (labels[i] == undefined) { + let label = { + check : '', + name: '', + value: '' + } + labels[i] = label; + } + } + + + let container_info = { + name: container.Names[0].slice(1), + service: service, + id: container.Id, + state: container.State, + image: container.Image, + external_port: ports_list[0].external || 0, + internal_port: ports_list[0].internal || 0, + ports: ports_list, + volumes: volumes_list, + environment_variables: environment_variables, + labels: labels, + } + + let dockerCard = dashCard(container_info); + + card_list += dockerCard; + } + + } + + return card_list; +} + + + + + + + +module.exports.containerStats = async function () { + + let container_stats = []; + + const data = await docker.listContainers({ all: true }); + + for (const container of data) { + + if ((container.Names[0].slice(1) != 'DweebUI') && (container.Names[0].slice(1) != 'DweebCache')) { + const stats = await dockerContainerStats(container.Id); + let container_stat = { + name: container.Names[0].slice(1), + cpu: Math.round(stats[0].cpuPercent), + ram: Math.round(stats[0].memPercent) + } + + //push stats to an array + container_stats.push(container_stat); + } + } + return container_stats; +} + + + + + + +module.exports.containerAction = async function (data) { + + let { user, role, action, container, state } = data; + + console.log(`${user} wants to: ${action} ${container}`); + + if (role == 'admin') { + var containerName = docker.getContainer(container); + + if ((action == 'start') && (state == 'stopped')) { + containerName.start(); + } else if ((action == 'start') && (state == 'paused')) { + containerName.unpause(); + } else if ((action == 'stop') && (state != 'stopped')) { + containerName.stop(); + } else if ((action == 'pause') && (state == 'running')) { + containerName.pause(); + } else if ((action == 'pause') && (state == 'paused')) { + containerName.unpause(); + } else if (action == 'restart') { + containerName.restart(); + } + } else { + console.log('User is not an admin'); + } +} + + + +module.exports.containerExec = async function (data) { + + let { container, command } = data; + + var containerName = docker.getContainer(container); + + var options = { + Cmd: ['/bin/sh', '-c', command], + AttachStdout: true, + AttachStderr: true, + Tty: true + }; + + containerName.exec(options, function (err, exec) { + if (err) return; + + exec.start(function (err, stream) { + if (err) return; + + containerName.modem.demuxStream(stream, process.stdout, process.stderr); + + exec.inspect(function (err, data) { + if (err) return; + + + }); + }); + }); + +} + + + diff --git a/routes/index.js b/routes/index.js index c0e37cd..fb47428 100644 --- a/routes/index.js +++ b/routes/index.js @@ -16,10 +16,6 @@ const { Register, processRegister } = require("../controllers/register"); router.get("/", Dashboard); - -router.post("/install", Install) -router.post("/uninstall", Uninstall) - router.post("/addsite", AddSite) router.post("/removesite", RemoveSite) router.get("/refreshsites", RefreshSites) @@ -27,6 +23,11 @@ router.post("/disablesite", DisableSite) router.post("/enablesite", EnableSite) +router.post("/install", Install) +router.post("/uninstall", Uninstall) + + + router.get("/users", Users); router.get("/apps", Apps); From fb3fb345320a7db705795b38ac3bfba44a60ab41 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Sun, 26 Nov 2023 17:53:25 -0800 Subject: [PATCH 07/25] Delete functions/system_information.js --- functions/system_information.js | 256 -------------------------------- 1 file changed, 256 deletions(-) delete mode 100644 functions/system_information.js diff --git a/functions/system_information.js b/functions/system_information.js deleted file mode 100644 index c34498a..0000000 --- a/functions/system_information.js +++ /dev/null @@ -1,256 +0,0 @@ -const { currentLoad, mem, networkStats, fsSize, dockerContainerStats } = require('systeminformation'); -var Docker = require('dockerode'); -var docker = new Docker({ socketPath: '/var/run/docker.sock' }); -const { dashCard } = require('../components/dashCard'); - -// export docker -module.exports.docker = docker; - -module.exports.serverStats = async function () { - const cpuUsage = await currentLoad(); - const ramUsage = await mem(); - const netUsage = await networkStats(); - const diskUsage = await fsSize(); - - const info = { - cpu: Math.round(cpuUsage.currentLoad), - ram: Math.round((ramUsage.active / ramUsage.total) * 100), - tx: netUsage[0].tx_bytes, - rx: netUsage[0].rx_bytes, - disk: diskUsage[0].use, - }; - - return info; -} - - - -module.exports.containerList = async function () { - let card_list = ''; - - const data = await docker.listContainers({ all: true }); - for (const container of data) { - - - if ((container.Names[0].slice(1) != 'DweebUI') && (container.Names[0].slice(1) != 'DweebCache') && (container.Names[0].slice(1) != 'DweebProxy')) { - - let imageVersion = container.Image.split('/'); - let service = imageVersion[imageVersion.length - 1].split(':')[0]; - - let containerId = docker.getContainer(container.Id); - let containerInfo = await containerId.inspect(); - - // Get ports ////////////////////////// - let ports_list = []; - try { - for (const [key, value] of Object.entries(containerInfo.HostConfig.PortBindings)) { - let ports = { - check : 'checked', - external: value[0].HostPort, - internal: key.split('/')[0], - protocol: key.split('/')[1] - } - ports_list.push(ports); - } - } catch { console.log('no ports') } - - for (let i = 0; i < 12; i++) { - if (ports_list[i] == undefined) { - let ports = { - check : '', - external: '', - internal: '', - protocol: '' - } - ports_list[i] = ports; - } - } ///////////////////////////////////// - - - // Get volumes //////////////////////// - let volumes_list = []; - try { for (const [key, value] of Object.entries(containerInfo.HostConfig.Binds)) { - let volumes = { - check : 'checked', - bind: value.split(':')[0], - container: value.split(':')[1], - readwrite: value.split(':')[2] - } - volumes_list.push(volumes); - }} catch { console.log('no volumes') } - for (let i = 0; i < 12; i++) { - if (volumes_list[i] == undefined) { - let volumes = { - check : '', - bind: '', - container: '', - readwrite: '' - } - volumes_list[i] = volumes; - } - } ///////////////////////////////////// - - - // Get environment variables. - let environment_variables = []; - try { for (const [key, value] of Object.entries(containerInfo.Config.Env)) { - let env = { - check : 'checked', - name: value.split('=')[0], - default: value.split('=')[1] - } - environment_variables.push(env); - }} catch { console.log('no env') } - for (let i = 0; i < 12; i++) { - if (environment_variables[i] == undefined) { - let env = { - check : '', - name: '', - default: '' - } - environment_variables[i] = env; - } - } - - // Get labels. - let labels = []; - for (const [key, value] of Object.entries(containerInfo.Config.Labels)) { - let label = { - check : 'checked', - name: key, - value: value - } - labels.push(label); - } - for (let i = 0; i < 12; i++) { - if (labels[i] == undefined) { - let label = { - check : '', - name: '', - value: '' - } - labels[i] = label; - } - } - - - let container_info = { - name: container.Names[0].slice(1), - service: service, - id: container.Id, - state: container.State, - image: container.Image, - external_port: ports_list[0].external || 0, - internal_port: ports_list[0].internal || 0, - ports: ports_list, - volumes: volumes_list, - environment_variables: environment_variables, - labels: labels, - } - - let dockerCard = dashCard(container_info); - - card_list += dockerCard; - } - - } - - return card_list; -} - - - - - - - -module.exports.containerStats = async function () { - - let container_stats = []; - - const data = await docker.listContainers({ all: true }); - - for (const container of data) { - - if ((container.Names[0].slice(1) != 'DweebUI') && (container.Names[0].slice(1) != 'DweebCache') && (container.Names[0].slice(1) != 'DweebProxy')) { - const stats = await dockerContainerStats(container.Id); - let container_stat = { - name: container.Names[0].slice(1), - cpu: Math.round(stats[0].cpuPercent), - ram: Math.round(stats[0].memPercent) - } - - //push stats to an array - container_stats.push(container_stat); - } - } - return container_stats; -} - - - - - - -module.exports.containerAction = async function (data) { - - let { user, role, action, container, state } = data; - - console.log(`${user} wants to: ${action} ${container}`); - - if (role == 'admin') { - var containerName = docker.getContainer(container); - - if ((action == 'start') && (state == 'stopped')) { - containerName.start(); - } else if ((action == 'start') && (state == 'paused')) { - containerName.unpause(); - } else if ((action == 'stop') && (state != 'stopped')) { - containerName.stop(); - } else if ((action == 'pause') && (state == 'running')) { - containerName.pause(); - } else if ((action == 'pause') && (state == 'paused')) { - containerName.unpause(); - } else if (action == 'restart') { - containerName.restart(); - } - } else { - console.log('User is not an admin'); - } -} - - - -module.exports.containerExec = async function (data) { - - let { container, command } = data; - - var containerName = docker.getContainer(container); - - var options = { - Cmd: ['/bin/sh', '-c', command], - AttachStdout: true, - AttachStderr: true, - Tty: true - }; - - containerName.exec(options, function (err, exec) { - if (err) return; - - exec.start(function (err, stream) { - if (err) return; - - containerName.modem.demuxStream(stream, process.stdout, process.stderr); - - exec.inspect(function (err, data) { - if (err) return; - - - }); - }); - }); - -} - - - From da0a5b84012765e8708f114d2c8e4db647c3d2ff Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Sun, 3 Dec 2023 14:24:30 -0800 Subject: [PATCH 08/25] Viewable container logs You can now view a containers logs. Code clean-up. --- app.js | 17 ++- components/dashCard.js | 62 +---------- controllers/auth.js | 150 ++++++++++++++++++++++++++ controllers/dashboard.js | 218 ++++++++++++++++++++++++++++++++++++++ functions/system.js | 39 +++++++ public/js/main.js | 19 +++- routes/index.js | 11 +- views/pages/dashboard.ejs | 32 ++++++ views/partials/footer.ejs | 2 +- 9 files changed, 478 insertions(+), 72 deletions(-) create mode 100644 controllers/auth.js diff --git a/app.js b/app.js index 4b201cd..cff12db 100644 --- a/app.js +++ b/app.js @@ -11,11 +11,11 @@ const redisClient = redis.createClient({ url: "redis://DweebCache:6379", passwor redisClient.connect().catch(console.log); let redisStore = new RedisStore({ client: redisClient }); -// Routes +// Router const routes = require("./routes"); // Functions and variables -const { serverStats, containerList, containerStats, containerAction } = require('./functions/system'); +const { serverStats, containerList, containerStats, containerAction, containerLogs } = require('./functions/system'); let sentList, clicked; app.locals.site_list = ''; @@ -98,6 +98,19 @@ io.on('connection', (socket) => { clicked = false; }); + + // Container logs + socket.on('logs', (data) => { + containerLogs(data.container) + .then(logs => { + socket.emit('logString', logs); + }) + .catch(err => { + console.error(err); + }); + }); + + // On disconnect socket.on('disconnect', () => { clearInterval(ServerStats); clearInterval(ContainerList); diff --git a/components/dashCard.js b/components/dashCard.js index 44d2e8a..3b14a3b 100644 --- a/components/dashCard.js +++ b/components/dashCard.js @@ -140,7 +140,7 @@ module.exports.dashCard = function dashCard(data) { - - - - - - - - - - - - - - - - - - - - - - - - + + +
diff --git a/views/partials/footer.ejs b/views/partials/footer.ejs index 54c763a..e0c7cbc 100644 --- a/views/partials/footer.ejs +++ b/views/partials/footer.ejs @@ -24,7 +24,7 @@
  • - v0.06 + v0.07
  • From 1508ae41c2e186e0f67183ccc277d742335626f1 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Sun, 3 Dec 2023 16:22:10 -0800 Subject: [PATCH 09/25] Delete controllers/logout.js --- controllers/logout.js | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 controllers/logout.js diff --git a/controllers/logout.js b/controllers/logout.js deleted file mode 100644 index d372a13..0000000 --- a/controllers/logout.js +++ /dev/null @@ -1,6 +0,0 @@ -exports.Logout = function(req,res){ - // clear the session. - req.session.destroy(); - // Redirect to the login page. - res.redirect("/login"); -} \ No newline at end of file From 234bcd7afa3f9912be64a3b04c1e4c4c999840a2 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Sun, 3 Dec 2023 16:22:22 -0800 Subject: [PATCH 10/25] Delete controllers/register.js --- controllers/register.js | 83 ----------------------------------------- 1 file changed, 83 deletions(-) delete mode 100644 controllers/register.js diff --git a/controllers/register.js b/controllers/register.js deleted file mode 100644 index a2b3b5e..0000000 --- a/controllers/register.js +++ /dev/null @@ -1,83 +0,0 @@ -const User = require('../database/UserModel'); -const bcrypt = require('bcrypt'); - - -exports.Register = function(req,res){ - // Check whether we have a session - if(req.session.user){ - // Redirect to log out. - res.redirect("/logout"); - } else { - // Render the signup page. - res.render("pages/register",{ - "error":"", - isLoggedIn:false - }); - } -} - -exports.processRegister = async function(req,res){ - - // Get the data. - let { first_name, last_name, username, email, password, avatar, tos } = req.body; - let role = "user"; - - // Check the data. - if(first_name && last_name && email && password && username && tos){ - - // Check if there is an existing user with that username. - let existingUser = await User.findOne({ where: {username:username}}); - - let adminUser = await User.findOne({ where: {role:"admin"}}); - - if(!existingUser){ - // hash the password. - let hashedPassword = bcrypt.hashSync(password,10); - - if(!adminUser){ - console.log('Creating admin User'); - role = "admin"; - } - - try { - const user = await User.create({ - first_name: first_name, - last_name: last_name, - username: username, - email: email, - password: hashedPassword, - role: role, - group: 'all', - avatar: `` - }); - - // set the session. - req.session.user = user.username; - req.session.UUID = user.UUID; - req.session.role = user.role; - // Redirect to the home page. - res.redirect("/"); - } - catch (err) { - // return an error. - res.render("pages/register",{ - "error":"Something went wrong when creating account.", - isLoggedIn:false - }); - } - - }else{ - // return an error. - res.render("pages/register",{ - "error":"User with that username already exists.", - isLoggedIn:false - }); - } - }else{ - // Redirect to the signup page. - res.render("pages/register",{ - "error":"Please fill in all the fields and accept TOS.", - isLoggedIn:false - }); - } -} \ No newline at end of file From 6f83ebef2ebecaa2993cd32043bf57d40afd1971 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Sun, 3 Dec 2023 16:22:36 -0800 Subject: [PATCH 11/25] Delete controllers/site_actions.js --- controllers/site_actions.js | 214 ------------------------------------ 1 file changed, 214 deletions(-) delete mode 100644 controllers/site_actions.js diff --git a/controllers/site_actions.js b/controllers/site_actions.js deleted file mode 100644 index 0d15d4c..0000000 --- a/controllers/site_actions.js +++ /dev/null @@ -1,214 +0,0 @@ -const { readFileSync, writeFileSync, appendFileSync, readdirSync } = require('fs'); -const { execSync } = require("child_process"); -const { siteCard } = require('../components/siteCard'); -const { containerExec } = require('../functions/system') - -exports.AddSite = async function (req, res) { - - let { domain, type, host, port } = req.body; - - if ((req.session.role == "admin") && ( domain && type && host && port)) { - - - let { domain, type, host, port } = req.body; - - // build caddyfile - let caddyfile = `${domain} {` - caddyfile += `\n\t${type} ${host}:${port}` - caddyfile += `\n\theader {` - caddyfile += `\n\t\tStrict-Transport-Security "max-age=31536000; includeSubDomains; preload"` - caddyfile += `\n\t}` - caddyfile += `\n}` - - - // save caddyfile - writeFileSync(`./caddyfiles/sites/${domain}.Caddyfile`, caddyfile, function (err) { console.log(err) }); - - - // format caddyfile - let format = { - container: 'DweebProxy', - command: `caddy fmt --overwrite /etc/caddy/sites/${domain}.Caddyfile` - } - await containerExec(format, function(err, data) { - if (err) { - console.error(err); - return; - } - console.log(`Formatted ${domain}.Caddyfile`); - }); - - ///////////////// convert caddyfile to json - let convert = { - container: 'DweebProxy', - command: `caddy adapt --config /etc/caddy/sites/${domain}.Caddyfile --pretty >> /etc/caddy/sites/${domain}.json` - } - await containerExec(convert, function(err, data) { - if (err) { - console.error(err); - return; - } - console.log(`Converted ${domain}.Caddyfile to JSON`); - }); - - ////////////// reload caddy - let reload = { - container: 'DweebProxy', - command: `caddy reload --config /etc/caddy/Caddyfile` - } - await containerExec(reload, function(err, data) { - if (err) { - console.error(err); - return; - } - console.log(`Reloaded Caddy Config`); - }); - - let site = siteCard(type, domain, host, port, 0); - - req.app.locals.site_list += site; - - - res.redirect("/"); - } else { - // Redirect - console.log('not admin or missing info') - res.redirect("/"); - } -} - - -exports.RemoveSite = async function (req, res) { - - if (req.session.role == "admin") { - - - for (const [key, value] of Object.entries(req.body)) { - - execSync(`rm ./caddyfiles/sites/${value}.Caddyfile`, (err, stdout, stderr) => { - if (err) { console.error(`error: ${err.message}`); return; } - if (stderr) { console.error(`stderr: ${stderr}`); return; } - console.log(`removed ${value}.Caddyfile`); - }); - - } - - let reload = { - container: 'DweebProxy', - command: `caddy reload --config /etc/caddy/Caddyfile` - } - await containerExec(reload); - - - console.log('Removed Site(s)') - - res.redirect("/refreshsites"); - } else { - res.redirect("/"); - } - -} - - -exports.RefreshSites = async function (req, res) { - - let domain, type, host, port; - let id = 1; - - if (req.session.role == "admin") { - - - // Clear site_list.ejs - req.app.locals.site_list = ""; - - - // check if ./caddyfiles/sites contains any .json files, then delete them - try { - let files = readdirSync('./caddyfiles/sites/'); - files.forEach(file => { - if (file.includes(".json")) { - execSync(`rm ./caddyfiles/sites/${file}`, (err, stdout, stderr) => { - if (err) { console.error(`error: ${err.message}`); return; } - if (stderr) { console.error(`stderr: ${stderr}`); return; } - console.log(`removed ${file}`); - }); - } - }); - } catch (error) { console.log("No .json files to delete") } - - // get list of Caddyfiles - let sites = readdirSync('./caddyfiles/sites/'); - - - sites.forEach(site_name => { - // convert the caddyfile of each site to json - let convert = { - container: 'DweebProxy', - command: `caddy adapt --config ./caddyfiles/sites/${site_name} --pretty >> ./caddyfiles/sites/${site_name}.json` - } - containerExec(convert); - - try { - // read the json file - let site_file = readFileSync(`./caddyfiles/sites/${site_name}.json`, 'utf8'); - // fix whitespace and parse the json file - site_file = site_file.replace(/ /g, " "); - site_file = JSON.parse(site_file); - } catch (error) { console.log("No .json file to read") } - - - // get the domain, type, host, and port from the json file - try { domain = site_file.apps.http.servers.srv0.routes[0].match[0].host[0] } catch (error) { console.log("No Domain") } - try { type = site_file.apps.http.servers.srv0.routes[0].handle[0].routes[0].handle[1].handler } catch (error) { console.log("No Type") } - try { host = site_file.apps.http.servers.srv0.routes[0].handle[0].routes[0].handle[1].upstreams[0].dial.split(":")[0] } catch (error) { console.log("Not Localhost") } - try { port = site_file.apps.http.servers.srv0.routes[0].handle[0].routes[0].handle[1].upstreams[0].dial.split(":")[1] } catch (error) { console.log("No Port") } - - // build the site card - let site = siteCard(type, domain, host, port, id); - - // append the site card to site_list - req.app.locals.site_list += site; - - id++; - }); - - - res.redirect("/"); - } else { - // Redirect to the login page - res.redirect("/"); - } -} - - - -exports.DisableSite = async function (req, res) { - - if (req.session.role == "admin") { - - - console.log(req.body) - console.log('Disable Site') - - res.redirect("/"); - } else { - // Redirect to the login page - res.redirect("/login"); - } -} - - -exports.EnableSite = async function (req, res) { - - if (req.session.role == "admin") { - - - console.log(req.body) - console.log('Enable Site') - - res.redirect("/"); - } else { - // Redirect to the login page - res.redirect("/login"); - } -} \ No newline at end of file From d73edb3ed15a42a746a4744cfbdc56eb03ec201a Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Sun, 3 Dec 2023 16:22:53 -0800 Subject: [PATCH 12/25] Delete controllers/login.js --- controllers/login.js | 60 -------------------------------------------- 1 file changed, 60 deletions(-) delete mode 100644 controllers/login.js diff --git a/controllers/login.js b/controllers/login.js deleted file mode 100644 index f11c1ed..0000000 --- a/controllers/login.js +++ /dev/null @@ -1,60 +0,0 @@ -const User = require('../database/UserModel'); -const bcrypt = require('bcrypt'); - - -exports.Login = function(req,res){ - - // check whether we have a session - if(req.session.user){ - // Redirect to log out. - res.redirect("/logout"); - }else{ - // Render the login page. - res.render("pages/login",{ - "error":"", - "isLoggedIn": false - }); - } -} - -exports.processLogin = async function(req,res){ - // get the data. - let email = req.body.email; - let password = req.body.password; - // check if we have data. - if(email && password){ - // check if the user exists. - let existingUser = await User.findOne({ where: {email:email}}); - if(existingUser){ - // compare the password. - let match = await bcrypt.compare(password,existingUser.password); - if(match){ - // set the session. - req.session.user = existingUser.username; - req.session.UUID = existingUser.UUID; - req.session.role = existingUser.role; - - // Redirect to the home page. - res.redirect("/"); - }else{ - // return an error. - res.render("pages/login",{ - "error":"Invalid password", - isLoggedIn: false - }); - } - }else{ - // return an error. - res.render("pages/login",{ - "error":"User with that email does not exist.", - isLoggedIn:false - }); - } - }else{ - res.status(400); - res.render("pages/login",{ - "error":"Please fill in all the fields.", - isLoggedIn:false - }); - } -} \ No newline at end of file From ab909bbe0e502080cbc7acdc61f534ee5ab3043c Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Mon, 4 Dec 2023 00:06:46 -0800 Subject: [PATCH 13/25] uninstall fix improved uninstall function and fixed duplicate form id --- components/dashCard.js | 6 +++--- functions/package_manager.js | 36 +++++++++++++++--------------------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/components/dashCard.js b/components/dashCard.js index 3b14a3b..7974973 100644 --- a/components/dashCard.js +++ b/components/dashCard.js @@ -184,8 +184,8 @@ module.exports.dashCard = function dashCard(data) {

    Remove ${name}?

    -
    - + +
     
    @@ -246,7 +246,7 @@ module.exports.dashCard = function dashCard(data) {
    - +
    diff --git a/functions/package_manager.js b/functions/package_manager.js index 153f982..6769ac7 100644 --- a/functions/package_manager.js +++ b/functions/package_manager.js @@ -180,26 +180,20 @@ module.exports.install = async function (data) { module.exports.uninstall = async function (data) { - - - if (data.confirm == 'Yes') { - - - var containerName = docker.getContainer(`${data.service_name}`); - - try { - containerName.stop(function (err, data) { - if (data) { - containerName.remove(function (err, data) { - }); - } - }); - } catch { - containerName.remove(function (err, data) { - }); - } - + if (data.confirm == 'Yes') { + console.log(`Uninstalling ${data.service_name}: ${data}`); + var containerName = docker.getContainer(`${data.service_name}`); + try { + await containerName.stop(); + console.log(`Stopped ${data.service_name} container`); + } catch { + console.log(`Error stopping ${data.service_name} container`); } - - + try { + await containerName.remove(); + console.log(`Removed ${data.service_name} container`); + } catch { + console.log(`Error removing ${data.service_name} container`); + } + } } \ No newline at end of file From 93ba77b4e3a582b8f250358ff271506d3334a9c0 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Mon, 4 Dec 2023 01:18:45 -0800 Subject: [PATCH 14/25] v0.07 ( dev ) ## v0.07 ( dev ) * View container logs. * Improved uninstall function and form id fix. * WebUI Port can be changed in compose.yml * Code clean-up. * Updated dependencies (redis-connect and systeminformation). --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6a02aa..de7effb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## v0.07 ( dev ) +* View container logs. +* Improved uninstall function and form id fix. +* WebUI Port can be changed in compose.yml +* Code clean-up. +* Updated dependencies (redis-connect and systeminformation). + ## v0.06 ( Nov 24th 2023 ) * Multi-platform image (amd64/arm64). * Removed Caddy from compose file. From 8a8d28ad8f0bc3b458f14219e84ed6ece440eb9c Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Mon, 4 Dec 2023 01:37:06 -0800 Subject: [PATCH 15/25] container metrics fix --- functions/system.js | 4 ++-- public/js/main.js | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/functions/system.js b/functions/system.js index 7de1c36..f34a531 100644 --- a/functions/system.js +++ b/functions/system.js @@ -168,19 +168,19 @@ module.exports.containerList = async function () { module.exports.containerStats = async function () { let container_stats = []; - const data = await docker.listContainers({ all: true }); for (const container of data) { if ((container.Names[0].slice(1) != 'DweebUI') && (container.Names[0].slice(1) != 'DweebCache')) { const stats = await dockerContainerStats(container.Id); + let container_stat = { name: container.Names[0].slice(1), cpu: Math.round(stats[0].cpuPercent), ram: Math.round(stats[0].memPercent) } - + //push stats to an array container_stats.push(container_stat); } diff --git a/public/js/main.js b/public/js/main.js index 895a303..bf3f660 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -158,10 +158,12 @@ socket.on('cards', (data) => { }); -socket.on('container_stats', (data) => { +socket.on('containerStats', (data) => { let {name, cpu, ram} = data; + console.log(`drawing chart for ${name}`) + var cpu_array = JSON.parse(localStorage.getItem(`${name}_cpu`)); var ram_array = JSON.parse(localStorage.getItem(`${name}_ram`)); From 4eeb8f6b25ff69d81d52d46fc2207e31af80a094 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Mon, 4 Dec 2023 23:21:27 -0800 Subject: [PATCH 16/25] removed redis --- app.js | 8 ---- package-lock.json | 107 +++------------------------------------------- package.json | 2 - 3 files changed, 6 insertions(+), 111 deletions(-) diff --git a/app.js b/app.js index cff12db..7be165b 100644 --- a/app.js +++ b/app.js @@ -4,13 +4,6 @@ const app = express(); const session = require("express-session"); const PORT = process.env.PORT || 8000; -// Redis -const redis = require('redis'); -const RedisStore = require("connect-redis").default; -const redisClient = redis.createClient({ url: "redis://DweebCache:6379", password: process.env.REDIS_PASS, }); -redisClient.connect().catch(console.log); -let redisStore = new RedisStore({ client: redisClient }); - // Router const routes = require("./routes"); @@ -21,7 +14,6 @@ app.locals.site_list = ''; // Configure Session const sessionMiddleware = session({ - store: redisStore, secret: "keyboard cat", resave: false, saveUninitialized: false, diff --git a/package-lock.json b/package-lock.json index 4859665..c8343ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,14 +11,12 @@ "dependencies": { "bcrypt": "^5.1.0", "child_process": "^1.0.2", - "connect-redis": "^7.1.0", "dockerode": "^4.0.0", "dockerode-compose": "^1.4.0", "ejs": "^3.1.9", "express": "^4.18.2", "express-session": "^1.17.3", "js-yaml": "^4.1.0", - "redis": "^4.6.11", "sequelize": "^6.35.1", "socket.io": "^4.6.1", "sqlite3": "^5.1.6", @@ -79,59 +77,6 @@ "node": ">=10" } }, - "node_modules/@redis/bloom": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", - "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/client": { - "version": "1.5.12", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.12.tgz", - "integrity": "sha512-/ZjE18HRzMd80eXIIUIPcH81UoZpwulbo8FmbElrjPqH0QC0SeIKu1BOU49bO5trM5g895kAjhvalt5h77q+4A==", - "dependencies": { - "cluster-key-slot": "1.1.2", - "generic-pool": "3.9.0", - "yallist": "4.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@redis/graph": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", - "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/json": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", - "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/search": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", - "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/time-series": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, "node_modules/@socket.io/component-emitter": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", @@ -173,9 +118,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "20.10.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.0.tgz", - "integrity": "sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==", + "version": "20.10.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", + "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", "dependencies": { "undici-types": "~5.26.4" } @@ -527,14 +472,6 @@ "node": ">=6" } }, - "node_modules/cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -564,17 +501,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, - "node_modules/connect-redis": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-7.1.0.tgz", - "integrity": "sha512-UaqO1EirWjON2ENsyau7N5lbkrdYBpS6mYlXSeff/OYXsd6EGZ+SXSmNPoljL2PSua8fgjAEaldSA73PMZQ9Eg==", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "express-session": ">=1" - } - }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -1094,14 +1020,6 @@ "node": ">=10" } }, - "node_modules/generic-pool": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", - "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", - "engines": { - "node": ">= 4" - } - }, "node_modules/get-intrinsic": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", @@ -1973,19 +1891,6 @@ "node": ">= 6" } }, - "node_modules/redis": { - "version": "4.6.11", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.11.tgz", - "integrity": "sha512-kg1Lt4NZLYkAjPOj/WcyIGWfZfnyfKo1Wg9YKVSlzhFwxpFIl3LYI8BWy1Ab963LLDsTz2+OwdsesHKljB3WMQ==", - "dependencies": { - "@redis/bloom": "1.2.0", - "@redis/client": "1.5.12", - "@redis/graph": "1.1.1", - "@redis/json": "1.0.6", - "@redis/search": "1.1.6", - "@redis/time-series": "1.0.5" - } - }, "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", @@ -2406,9 +2311,9 @@ } }, "node_modules/systeminformation": { - "version": "5.21.18", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.21.18.tgz", - "integrity": "sha512-PEoWd95nI5170rvIk4fagLH0SmzwfGt18w0+ex1Ljb2bSXvDs9PQdLNexMazL5L6Pzd6wxlpoWUAjX+hNRKN7g==", + "version": "5.21.20", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.21.20.tgz", + "integrity": "sha512-AyS1fNc+MDoAJtFknFbbo587H8h6yejJwM+H9rVusnOToIEkiMehMyD5JM7o3j55Cto20MawIZrcgNMgd4BfOQ==", "os": [ "darwin", "linux", diff --git a/package.json b/package.json index a63f313..ba0f742 100644 --- a/package.json +++ b/package.json @@ -8,14 +8,12 @@ "dependencies": { "bcrypt": "^5.1.0", "child_process": "^1.0.2", - "connect-redis": "^7.1.0", "dockerode": "^4.0.0", "dockerode-compose": "^1.4.0", "ejs": "^3.1.9", "express": "^4.18.2", "express-session": "^1.17.3", "js-yaml": "^4.1.0", - "redis": "^4.6.11", "sequelize": "^6.35.1", "socket.io": "^4.6.1", "sqlite3": "^5.1.6", From 69f2eec789b61f7e0dc5f04757ffcd2e089a651c Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Tue, 5 Dec 2023 01:02:58 -0800 Subject: [PATCH 17/25] Update CHANGELOG.md added: removed redis --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de7effb..ac320c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,10 @@ ## v0.07 ( dev ) * View container logs. +* Removed Redis. * Improved uninstall function and form id fix. * WebUI Port can be changed in compose.yml * Code clean-up. -* Updated dependencies (redis-connect and systeminformation). +* Updated dependencies (systeminformation). ## v0.06 ( Nov 24th 2023 ) * Multi-platform image (amd64/arm64). From 0a5681d745e5b839a843c7c715fc9eb0069d1674 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:11:51 -0800 Subject: [PATCH 18/25] removed redis --- compose.yaml | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/compose.yaml b/compose.yaml index 9d2123f..efa6ef2 100644 --- a/compose.yaml +++ b/compose.yaml @@ -3,29 +3,18 @@ services: container_name: DweebUI image: lllllllillllllillll/dweebui:v0.07-dev environment: - PORT: 8000 + NODE_ENV: production REDIS_PASS: replace_with_password_for_redis + PORT: 8000 # Proxy_Manager: enabled restart: unless-stopped ports: - 8000:8000 - depends_on: - - cache - links: - - cache volumes: - dweebui:/app - caddyfiles:/app/caddyfiles - /var/run/docker.sock:/var/run/docker.sock - cache: - container_name: DweebCache - image: redis:6.2-alpine - restart: always - command: redis-server --save 20 1 --loglevel warning --requirepass replace_with_password_for_redis - volumes: - - cache:/data volumes: dweebui: - cache: caddyfiles: \ No newline at end of file From 58a006e48e99e84d483bda78e7535e9372b13670 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Tue, 5 Dec 2023 19:39:32 -0800 Subject: [PATCH 19/25] Update README.md --- README.md | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 720d5a2..2053900 100644 --- a/README.md +++ b/README.md @@ -43,31 +43,20 @@ services:     container_name: DweebUI     image: lllllllillllllillll/dweebui:v0.07-dev     environment: -      PORT: 8000 +      NODE_ENV: production       REDIS_PASS: replace_with_password_for_redis +      PORT: 8000       # Proxy_Manager: enabled     restart: unless-stopped     ports:       - 8000:8000 -    depends_on: -      - cache -    links: -      - cache     volumes:       - dweebui:/app       - caddyfiles:/app/caddyfiles       - /var/run/docker.sock:/var/run/docker.sock -  cache: -    container_name: DweebCache -    image: redis:6.2-alpine -    restart: always -    command: redis-server --save 20 1 --loglevel warning --requirepass replace_with_password_for_redis -    volumes: -      - cache:/data volumes:   dweebui: -  cache:   caddyfiles: ``` From b49545965a48eb553af5ce7d82f33b66b37b467f Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Wed, 6 Dec 2023 01:49:08 -0800 Subject: [PATCH 20/25] Bump systeminformation from 5.21.17 to 5.21.20 #30 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index c8343ff..36df813 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "sequelize": "^6.35.1", "socket.io": "^4.6.1", "sqlite3": "^5.1.6", - "systeminformation": "^5.21.18" + "systeminformation": "^5.21.20" } }, "node_modules/@balena/dockerignore": { diff --git a/package.json b/package.json index ba0f742..5c43d34 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "sequelize": "^6.35.1", "socket.io": "^4.6.1", "sqlite3": "^5.1.6", - "systeminformation": "^5.21.18" + "systeminformation": "^5.21.20" }, "description": "" } From 3d110c137c2c73f6cec9d8aa20be2fed332b7e67 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Thu, 7 Dec 2023 19:34:01 -0800 Subject: [PATCH 21/25] Delete LICENSE --- LICENSE | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 LICENSE diff --git a/LICENSE b/LICENSE deleted file mode 100644 index afd0d19..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 lllllllillllllillll - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. From 02dce5eb093191fe7dc14daaf98d0ca9099c0ac7 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Fri, 8 Dec 2023 01:22:55 -0800 Subject: [PATCH 22/25] v0.07 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2053900..ccebcfc 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Pre-Pre-Pre-Pre-Pre Alpha v0.07 ( :fire: Experimental. Don't install on any serv services:   dweebui:     container_name: DweebUI -    image: lllllllillllllillll/dweebui:v0.07-dev +    image: lllllllillllllillll/dweebui:v0.07     environment:       NODE_ENV: production       REDIS_PASS: replace_with_password_for_redis From b563f8bd01ceb52fe8c3f2cfa0d1a2f4b88928d2 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Fri, 8 Dec 2023 01:26:02 -0800 Subject: [PATCH 23/25] v0.07 --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index ccebcfc..43f04ad 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,6 @@ services:     image: lllllllillllllillll/dweebui:v0.07     environment:       NODE_ENV: production -      REDIS_PASS: replace_with_password_for_redis       PORT: 8000       # Proxy_Manager: enabled     restart: unless-stopped From ea2e0f9fd87b56b9874c4f5cf7890e55a464a16d Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Fri, 8 Dec 2023 01:26:46 -0800 Subject: [PATCH 24/25] removed redis --- compose.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compose.yaml b/compose.yaml index efa6ef2..11cf584 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,10 +1,9 @@ services: dweebui: container_name: DweebUI - image: lllllllillllllillll/dweebui:v0.07-dev + image: lllllllillllllillll/dweebui:v0.07 environment: NODE_ENV: production - REDIS_PASS: replace_with_password_for_redis PORT: 8000 # Proxy_Manager: enabled restart: unless-stopped @@ -17,4 +16,4 @@ services: volumes: dweebui: - caddyfiles: \ No newline at end of file + caddyfiles: From e35dbb54669cf8e6c23c4c434eddd691190b4dc2 Mon Sep 17 00:00:00 2001 From: lllllllillllllillll <147879489+lllllllillllllillll@users.noreply.github.com> Date: Fri, 8 Dec 2023 01:32:47 -0800 Subject: [PATCH 25/25] v0.07 release date --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac320c0..26e792c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## v0.07 ( dev ) +## v0.07 (Dec 8th 2023) * View container logs. * Removed Redis. * Improved uninstall function and form id fix. @@ -6,7 +6,7 @@ * Code clean-up. * Updated dependencies (systeminformation). -## v0.06 ( Nov 24th 2023 ) +## v0.06 (Nov 24th 2023) * Multi-platform image (amd64/arm64). * Removed Caddy from compose file. * Proxy Manager UI can be enabled from environment variable. @@ -14,7 +14,7 @@ * Repo change: Implemented image build-and-publish and dependabot (Thank you, gaby). * Updated dependencies. -## v0.05 ( Nov 17th 2023 ) +## v0.05 (Nov 17th 2023) * Environment Variables and Labels are now unchecked by default. * Support for Docker volumes. * Fixed app uninstall.