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/controllers/auth.js b/controllers/auth.js
new file mode 100644
index 0000000..b4c176a
--- /dev/null
+++ b/controllers/auth.js
@@ -0,0 +1,150 @@
+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
+ });
+ }
+}
+
+
+exports.Logout = function(req,res){
+ // clear the session.
+ req.session.destroy();
+ // Redirect to the login page.
+ res.redirect("/login");
+}
+
+
+
+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
diff --git a/controllers/dashboard.js b/controllers/dashboard.js
index 09aee37..4425ee6 100644
--- a/controllers/dashboard.js
+++ b/controllers/dashboard.js
@@ -1,4 +1,10 @@
const User = require('../database/UserModel');
+const { readFileSync, writeFileSync, appendFileSync, readdirSync } = require('fs');
+const { execSync } = require("child_process");
+const { siteCard } = require('../components/siteCard');
+const { containerExec } = require('../functions/system')
+
+
exports.Dashboard = async function (req, res) {
@@ -26,4 +32,216 @@ exports.Dashboard = async function (req, res) {
// Redirect to the login page
res.redirect("/login");
}
+}
+
+
+
+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
diff --git a/functions/system.js b/functions/system.js
index 9f941e8..7de1c36 100644
--- a/functions/system.js
+++ b/functions/system.js
@@ -2,6 +2,7 @@ const { currentLoad, mem, networkStats, fsSize, dockerContainerStats } = require
var Docker = require('dockerode');
var docker = new Docker({ socketPath: '/var/run/docker.sock' });
const { dashCard } = require('../components/dashCard');
+const { Readable } = require('stream');
// export docker
module.exports.docker = docker;
@@ -254,3 +255,41 @@ module.exports.containerExec = async function (data) {
+
+
+
+
+
+
+
+module.exports.containerLogs = function (data) {
+ return new Promise((resolve, reject) => {
+ let logString = '';
+
+ var options = {
+ follow: false,
+ stdout: true,
+ stderr: false,
+ timestamps: false
+ };
+
+ var containerName = docker.getContainer(data);
+
+ containerName.logs(options, function (err, stream) {
+ if (err) {
+ reject(err);
+ return;
+ }
+
+ const readableStream = Readable.from(stream);
+
+ readableStream.on('data', function (chunk) {
+ logString += chunk.toString('utf8');
+ });
+
+ readableStream.on('end', function () {
+ resolve(logString);
+ });
+ });
+ });
+};
\ No newline at end of file
diff --git a/public/js/main.js b/public/js/main.js
index 2b8797a..895a303 100644
--- a/public/js/main.js
+++ b/public/js/main.js
@@ -22,7 +22,7 @@ const diskBar = document.getElementById('disk-bar');
const dockerCards = document.getElementById('cards');
-// create
+const logViewer = document.getElementById('logView');
//Update usage bars
socket.on('metrics', (data) => {
@@ -115,10 +115,25 @@ function buttonAction(button) {
socket.emit('clicked', {container: button.name, state: button.id, action: button.value});
}
+
+let containerLogs;
+
function viewLogs(button) {
- console.log(`trying to view logs for ${button.name}`);
+
+ if (button.name != 'refresh') {
+ containerLogs = button.name;
+ }
+
+
+ socket.emit('logs', {container: containerLogs});
}
+socket.on('logString', (data) => {
+ logViewer.innerHTML = `
${data}
`;
+});
+
+
+
socket.on('cards', (data) => {
console.log('cards deleted');
diff --git a/routes/index.js b/routes/index.js
index fb47428..30146c3 100644
--- a/routes/index.js
+++ b/routes/index.js
@@ -1,17 +1,13 @@
const express = require("express");
const router = express.Router();
-const { Dashboard } = require("../controllers/dashboard");
-
-const { AddSite, RemoveSite, RefreshSites, DisableSite, EnableSite } = require("../controllers/site_actions");
+const { Dashboard, AddSite, RemoveSite, RefreshSites, DisableSite, EnableSite } = require("../controllers/dashboard");
+const { Login, processLogin, Logout, Register, processRegister } = require("../controllers/auth");
const { Apps, searchApps, Install, Uninstall } = require("../controllers/apps");
const { Users } = require("../controllers/users");
const { Account } = require("../controllers/account");
const { Settings } = require("../controllers/settings");
-const { Logout } = require("../controllers/logout");
-const { Login, processLogin } = require("../controllers/login");
-const { Register, processRegister } = require("../controllers/register");
@@ -44,4 +40,7 @@ router.post("/register",processRegister); // Process Register
router.get("/logout",Logout); // Logout
+
+
+
module.exports = router;
\ No newline at end of file
diff --git a/views/pages/dashboard.ejs b/views/pages/dashboard.ejs
index 5d5cba4..f37fc34 100644
--- a/views/pages/dashboard.ejs
+++ b/views/pages/dashboard.ejs
@@ -126,6 +126,38 @@
+
+
+
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.