Compare commits

..

10 Commits

Author SHA1 Message Date
4400ba5dd6 WIP 2023-12-10 20:29:14 +08:00
2b428e139c Merge branch 'master' into build-windows
# Conflicts:
#	pnpm-lock.yaml
2023-12-10 13:23:15 +08:00
587d2dcaca Fix URLs with env 2023-12-10 13:17:04 +08:00
5f1f3593fd Add pnpm run dev 2023-12-10 13:16:40 +08:00
e570374a48 WIP 2023-12-10 13:07:24 +08:00
316c566c76 Update dependencies 2023-12-10 02:39:39 +08:00
d32bd3937f Fix: .env code change is not reactive (#270) 2023-12-10 02:29:05 +08:00
007eac7b58 Envsubst YAML in order to display the correct values in the UI instead of tags (#268)
* WIP

* Add envsubst

* WIP
2023-12-10 00:59:28 +08:00
b945ddea55 Fix check update (#269)
* Fix check-version.ts
2023-12-10 00:59:05 +08:00
bd58de535e Update README.md (#264)
Correct spelling errors.
2023-12-08 23:49:29 +08:00
10 changed files with 837 additions and 409 deletions

View File

@ -148,13 +148,13 @@ Yes, you can. However, you need to move your compose file into the stacks direct
3. In Dockge, click the " Scan Stacks Folder" button in the top-right corner's dropdown menu
4. Now you should see your stack in the list
#### Is Dockge a Portainer replcement?
#### Is Dockge a Portainer replacement?
Yes or no. Portainer provides a lot of Docker features. While Dockge is currently only focusing on docker-compose with a better user interface and better user experience.
If you want to manage your container with docker-compose only, the answer may be yes.
If you still need to manage something like docker networks, signle containers, the answer may be no.
If you still need to manage something like docker networks, single containers, the answer may be no.
#### Can I install both Dockge and Portainer?

View File

@ -3,69 +3,55 @@ import compareVersions from "compare-versions";
import packageJSON from "../package.json";
import { Settings } from "./settings";
export const obj = {
version: packageJSON.version,
latestVersion: null,
};
export default obj;
// How much time in ms to wait between update checks
const UPDATE_CHECKER_INTERVAL_MS = 1000 * 60 * 60 * 48;
const CHECK_URL = "https://dockge.kuma.pet/version";
let interval : NodeJS.Timeout;
class CheckVersion {
version = packageJSON.version;
latestVersion? : string;
interval? : NodeJS.Timeout;
export function startInterval() {
const check = async () => {
if (await Settings.get("checkUpdate") === false) {
return;
}
log.debug("update-checker", "Retrieving latest versions");
try {
const res = await fetch(CHECK_URL);
const data = await res.json();
// For debug
if (process.env.TEST_CHECK_VERSION === "1") {
data.slow = "1000.0.0";
async startInterval() {
const check = async () => {
if (await Settings.get("checkUpdate") === false) {
return;
}
const checkBeta = await Settings.get("checkBeta");
log.debug("update-checker", "Retrieving latest versions");
if (checkBeta && data.beta) {
if (compareVersions.compare(data.beta, data.slow, ">")) {
obj.latestVersion = data.beta;
return;
try {
const res = await fetch(CHECK_URL);
const data = await res.json();
// For debug
if (process.env.TEST_CHECK_VERSION === "1") {
data.slow = "1000.0.0";
}
const checkBeta = await Settings.get("checkBeta");
if (checkBeta && data.beta) {
if (compareVersions.compare(data.beta, data.slow, ">")) {
this.latestVersion = data.beta;
return;
}
}
if (data.slow) {
this.latestVersion = data.slow;
}
} catch (_) {
log.info("update-checker", "Failed to check for new versions");
}
if (data.slow) {
obj.latestVersion = data.slow;
}
};
} catch (_) {
log.info("update-checker", "Failed to check for new versions");
}
};
check();
interval = setInterval(check, UPDATE_CHECKER_INTERVAL_MS);
}
/**
* Enable the check update feature
* @param value Should the check update feature be enabled?
* @returns
*/
export async function enableCheckUpdate(value : boolean) {
await Settings.set("checkUpdate", value);
clearInterval(interval);
if (value) {
startInterval();
await check();
this.interval = setInterval(check, UPDATE_CHECKER_INTERVAL_MS);
}
}
const checkVersion = new CheckVersion();
export default checkVersion;

View File

@ -1,3 +0,0 @@
export class Docker {
}

View File

@ -308,6 +308,7 @@ export class DockgeServer {
this.sendStackList(true);
});
checkVersion.startInterval();
});
gracefulShutdown(this.httpServer, {

92
extra/build-windows.ts Normal file
View File

@ -0,0 +1,92 @@
import fsAsync from "fs/promises";
import unzipper from "unzipper";
import stream from "node:stream";
import { fileExists } from "../backend/util-server";
const version = process.env.VERSION;
if (!version) {
console.error("VERSION env not set");
process.exit(1);
}
const output = `./private/build/dockgen-${version}-win-x64.zip`;
if (await fileExists(output)) {
console.error(`${output} already exists`);
process.exit(1);
}
console.log(`Building ${output}`);
const nodeVersion = "18.17.1";
const buildPath = "./private/build/windows";
const nodePath = `${buildPath}/node`;
const nodeTempPath = `${buildPath}/node-v${nodeVersion}-win-x64`;
const corePath = `${buildPath}/core`;
// Clear
await fsAsync.rm(`${buildPath}/dockge-${version}`, {
recursive: true,
force: true
});
await fsAsync.rm(corePath, {
recursive: true,
force: true
});
// mkdir
await fsAsync.mkdir(buildPath, {
recursive: true
});
// Download Node.js if not exists
// Download,pipe to unzipper and extract to nodePath
if (!await fileExists(nodePath)) {
console.log(`Downloading Node.js ${nodeVersion}`);
try {
await download(`https://nodejs.org/dist/v${nodeVersion}/node-v${nodeVersion}-win-x64.zip`);
// Rename folder
await fsAsync.rename(nodeTempPath, nodePath);
} catch (e) {
if (e instanceof Error) {
console.error(e.message);
}
process.exit(1);
}
} else {
console.log(`Node.js ${nodeVersion} already exists, skipping download`);
}
// Download Dockge from GitHub
console.log(`Downloading Dockge ${version} from GitHub`);
try {
await download(`https://github.com/louislam/dockge/archive/refs/tags/${version}.zip`);
// Rename folder
await fsAsync.rename(`${buildPath}/dockge-${version}`, corePath);
} catch (e) {
if (e instanceof Error) {
console.error(e.message);
}
process.exit(1);
}
function download(url : string) {
return new Promise((resolve, reject) => {
fetch(url).then((res) => {
if (res.body) {
// @ts-ignore
stream.Readable.fromWeb(res.body)
.pipe(unzipper.Extract({
path: buildPath,
}))
.on("close", resolve);
} else {
reject(new Error(`Unable to download ${url}`));
}
});
});
}

View File

@ -98,5 +98,6 @@
"reconnecting...": "Reconnecting…",
"connecting...": "Connecting to the socket server…",
"url": "URL | URLs",
"extra": "Extra"
"extra": "Extra",
"newUpdate": "New Update"
}

View File

@ -16,8 +16,8 @@
<span class="fs-4 title">Dockge</span>
</router-link>
<a v-if="hasNewVersion" target="_blank" href="https://github.com/louislam/dockge/releases" class="btn btn-info me-3">
<font-awesome-icon icon="arrow-alt-circle-up" /> {{ $t("New Update") }}
<a v-if="hasNewVersion" target="_blank" href="https://github.com/louislam/dockge/releases" class="btn btn-warning me-3">
<font-awesome-icon icon="arrow-alt-circle-up" /> {{ $t("newUpdate") }}
</a>
<ul class="nav nav-pills">

View File

@ -299,12 +299,12 @@ export default {
computed: {
urls() {
if (!this.jsonConfig["x-dockge"] || !this.jsonConfig["x-dockge"].urls || !Array.isArray(this.jsonConfig["x-dockge"].urls)) {
if (!this.envsubstJSONConfig["x-dockge"] || !this.envsubstJSONConfig["x-dockge"].urls || !Array.isArray(this.envsubstJSONConfig["x-dockge"].urls)) {
return [];
}
let urls = [];
for (const url of this.jsonConfig["x-dockge"].urls) {
for (const url of this.envsubstJSONConfig["x-dockge"].urls) {
let display;
try {
let obj = new URL(url);
@ -374,6 +374,17 @@ export default {
},
deep: true,
},
"stack.composeENV": {
handler() {
if (this.editorFocus) {
console.debug("env code changed");
this.yamlCodeChange();
}
},
deep: true,
},
jsonConfig: {
handler() {
if (!this.editorFocus) {

View File

@ -10,13 +10,15 @@
"lint": "eslint \"**/*.{ts,vue}\"",
"check-ts": "tsc --noEmit",
"start": "tsx ./backend/index.ts",
"dev": "concurrently -k -r \"wait-on tcp:5000 && pnpm run dev:backend \" \"pnpm run dev:frontend\"",
"dev:backend": "cross-env NODE_ENV=development tsx watch --inspect ./backend/index.ts",
"dev:frontend": "cross-env NODE_ENV=development vite --host --config ./frontend/vite.config.ts",
"release-final": "tsx ./extra/test-docker.ts && tsx extra/update-version.ts && pnpm run build:frontend && npm run build:docker",
"release-final": "tsx ./extra/test-docker.ts && tsx extra/update-version.ts && pnpm run build:frontend && pnpm run build:docker",
"build:frontend": "vite build --config ./frontend/vite.config.ts",
"build:docker-base": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/dockge:base -f ./docker/Base.Dockerfile . --push",
"build:docker": "node ./extra/env2arg.js docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/dockge:latest -t louislam/dockge:1 -t louislam/dockge:$VERSION --target release -f ./docker/Dockerfile . --push",
"build:docker-nightly": "pnpm run build:frontend && docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/dockge:nightly --target nightly -f ./docker/Dockerfile . --push",
"build:windows": "tsx ./extra/build-windows.ts",
"build:healthcheck": "docker buildx build -f docker/BuildHealthCheck.Dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/dockge:build-healthcheck . --push",
"start-docker": "docker run --rm -p 5001:5001 --name dockge louislam/dockge:latest",
"mark-as-nightly": "tsx ./extra/mark-as-nightly.ts",
@ -24,7 +26,7 @@
"reset-password": "tsx ./extra/reset-password.ts"
},
"dependencies": {
"@homebridge/node-pty-prebuilt-multiarch": "~0.11.11",
"@homebridge/node-pty-prebuilt-multiarch": "~0.11.12",
"@inventage/envsubst": "^0.16.0",
"@louislam/sqlite3": "~15.1.6",
"bcryptjs": "~2.4.3",
@ -42,7 +44,8 @@
"jwt-decode": "~3.1.2",
"knex": "~2.5.1",
"limiter-es6-compat": "~2.1.2",
"mysql2": "~3.6.3",
"mysql2": "~3.6.5",
"node-windows": "1.0.0-beta.8",
"promisify-child-process": "~4.1.2",
"redbean-node": "~0.3.3",
"socket.io": "~4.7.2",
@ -55,21 +58,23 @@
},
"devDependencies": {
"@actions/github": "^6.0.0",
"@fontsource/jetbrains-mono": "^5.0.17",
"@fontsource/jetbrains-mono": "^5.0.18",
"@fortawesome/fontawesome-svg-core": "6.4.2",
"@fortawesome/free-regular-svg-icons": "6.4.2",
"@fortawesome/free-solid-svg-icons": "6.4.2",
"@fortawesome/vue-fontawesome": "3.0.3",
"@types/bcryptjs": "^2.4.6",
"@types/bootstrap": "~5.2.9",
"@types/bootstrap": "~5.2.10",
"@types/command-exists": "~1.2.3",
"@types/express": "~4.17.21",
"@types/jsonwebtoken": "~9.0.5",
"@types/unzipper": "^0.10.9",
"@typescript-eslint/eslint-plugin": "~6.8.0",
"@typescript-eslint/parser": "~6.8.0",
"@vitejs/plugin-vue": "~4.5.0",
"@vitejs/plugin-vue": "~4.5.2",
"bootstrap": "5.3.2",
"bootstrap-vue-next": "~0.14.10",
"concurrently": "^8.2.2",
"cross-env": "~7.0.3",
"eslint": "~8.50.0",
"eslint-plugin-jsdoc": "~46.8.2",
@ -78,15 +83,17 @@
"sass": "~1.68.0",
"typescript": "~5.2.2",
"unplugin-vue-components": "~0.25.2",
"vite": "~5.0.0",
"unzipper": "^0.10.14",
"vite": "~5.0.7",
"vite-plugin-compression": "~0.5.1",
"vue": "~3.3.8",
"vue": "~3.3.11",
"vue-eslint-parser": "~9.3.2",
"vue-i18n": "~9.5.0",
"vue-prism-editor": "2.0.0-alpha.2",
"vue-qrcode": "~2.2.0",
"vue-router": "~4.2.5",
"vue-toastification": "2.0.0-rc.5",
"wait-on": "^7.2.0",
"xterm": "5.4.0-beta.37",
"xterm-addon-web-links": "~0.9.0"
}

1011
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff