mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-12-18 04:04:41 -05:00
Improve the setup database for embedded MariaDB
This commit is contained in:
parent
7975caf29e
commit
d286c534bd
@ -23,6 +23,7 @@ RUN curl https://pkg.cloudflare.com/cloudflare-main.gpg --output /usr/share/keyr
|
|||||||
# Not working for armv7, so use the older version (10.5) of MariaDB from the debian repo
|
# Not working for armv7, so use the older version (10.5) of MariaDB from the debian repo
|
||||||
# curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | bash -s -- --mariadb-server-version="mariadb-11.1" && \
|
# curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | bash -s -- --mariadb-server-version="mariadb-11.1" && \
|
||||||
FROM base2-slim AS base2
|
FROM base2-slim AS base2
|
||||||
|
ENV UPTIME_KUMA_ENABLE_EMBEDDED_MARIADB=1
|
||||||
RUN apt update && \
|
RUN apt update && \
|
||||||
apt --yes --no-install-recommends install chromium fonts-indic fonts-noto fonts-noto-cjk mariadb-server && \
|
apt --yes --no-install-recommends install chromium fonts-indic fonts-noto fonts-noto-cjk mariadb-server && \
|
||||||
apt --yes remove curl && \
|
apt --yes remove curl && \
|
||||||
@ -30,4 +31,4 @@ RUN apt update && \
|
|||||||
apt --yes autoremove && \
|
apt --yes autoremove && \
|
||||||
chown -R node:node /var/lib/mysql
|
chown -R node:node /var/lib/mysql
|
||||||
|
|
||||||
ENV UPTIME_KUMA_ENABLE_EMBEDDED_MARIADB=1
|
|
||||||
|
@ -5,7 +5,7 @@ services:
|
|||||||
container_name: uptime-kuma-dev
|
container_name: uptime-kuma-dev
|
||||||
image: louislam/uptime-kuma:nightly2
|
image: louislam/uptime-kuma:nightly2
|
||||||
volumes:
|
volumes:
|
||||||
- ./data:/app/data
|
#- ./data:/app/data
|
||||||
- ../server:/app/server
|
- ../server:/app/server
|
||||||
ports:
|
ports:
|
||||||
- "3001:3001" # <Host Port>:<Container Port>
|
- "3001:3001" # <Host Port>:<Container Port>
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
"build-docker-builder-go": "docker buildx build -f docker/builder-go.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:builder-go . --push",
|
"build-docker-builder-go": "docker buildx build -f docker/builder-go.dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:builder-go . --push",
|
||||||
"build-docker-slim": "node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:2-slim -t louislam/uptime-kuma:$VERSION-slim --target release --build-arg BASE_IMAGE=louislam/uptime-kuma:base2-slim . --push",
|
"build-docker-slim": "node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:2-slim -t louislam/uptime-kuma:$VERSION-slim --target release --build-arg BASE_IMAGE=louislam/uptime-kuma:base2-slim . --push",
|
||||||
"build-docker-full": "node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:2 -t louislam/uptime-kuma:$VERSION --target release . --push",
|
"build-docker-full": "node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:2 -t louislam/uptime-kuma:$VERSION --target release . --push",
|
||||||
"build-docker-nightly": "npm run build && docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly2 --target nightly --build-arg . --push",
|
"build-docker-nightly": "npm run build && docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly2 --target nightly . --push",
|
||||||
"build-docker-nightly-local": "docker build -f docker/dockerfile -t louislam/uptime-kuma:nightly2 --target nightly .",
|
"build-docker-nightly-local": "npm run build && docker build -f docker/dockerfile -t louislam/uptime-kuma:nightly2 --target nightly .",
|
||||||
"build-docker-pr-test": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64 -t louislam/uptime-kuma:pr-test --target pr-test . --push",
|
"build-docker-pr-test": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64 -t louislam/uptime-kuma:pr-test --target pr-test . --push",
|
||||||
"upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain",
|
"upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain",
|
||||||
"setup": "git checkout 1.22.0 && npm ci --production && npm run download-dist",
|
"setup": "git checkout 1.22.0 && npm ci --production && npm run download-dist",
|
||||||
@ -63,7 +63,7 @@
|
|||||||
"deploy-demo-server": "node extra/deploy-demo-server.js",
|
"deploy-demo-server": "node extra/deploy-demo-server.js",
|
||||||
"sort-contributors": "node extra/sort-contributors.js",
|
"sort-contributors": "node extra/sort-contributors.js",
|
||||||
"quick-run-nightly": "docker run --rm --env NODE_ENV=development -p 3001:3001 louislam/uptime-kuma:nightly2",
|
"quick-run-nightly": "docker run --rm --env NODE_ENV=development -p 3001:3001 louislam/uptime-kuma:nightly2",
|
||||||
"start-dev-container": "cd docker && docker-compose -f docker-compose-dev.yml up"
|
"start-dev-container": "cd docker && docker-compose -f docker-compose-dev.yml up --force-recreate"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@grpc/grpc-js": "~1.7.3",
|
"@grpc/grpc-js": "~1.7.3",
|
||||||
|
@ -76,7 +76,9 @@ log.info("server", "Importing this project modules");
|
|||||||
log.debug("server", "Importing Monitor");
|
log.debug("server", "Importing Monitor");
|
||||||
const Monitor = require("./model/monitor");
|
const Monitor = require("./model/monitor");
|
||||||
log.debug("server", "Importing Settings");
|
log.debug("server", "Importing Settings");
|
||||||
const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, FBSD, doubleCheckPassword, startE2eTests } = require("./util-server");
|
const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, FBSD, doubleCheckPassword, startE2eTests,
|
||||||
|
allowDevAllOrigin
|
||||||
|
} = require("./util-server");
|
||||||
|
|
||||||
log.debug("server", "Importing Notification");
|
log.debug("server", "Importing Notification");
|
||||||
const { Notification } = require("./notification");
|
const { Notification } = require("./notification");
|
||||||
@ -228,6 +230,14 @@ let needSetup = false;
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.get("/setup-database-info", (request, response) => {
|
||||||
|
allowDevAllOrigin(response);
|
||||||
|
response.json({
|
||||||
|
runningSetup: false,
|
||||||
|
needSetup: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
app.post("/test-webhook", async (request, response) => {
|
app.post("/test-webhook", async (request, response) => {
|
||||||
log.debug("test", request.headers);
|
log.debug("test", request.headers);
|
||||||
|
@ -18,6 +18,7 @@ class SetupDatabase {
|
|||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
needSetup = true;
|
needSetup = true;
|
||||||
|
runningSetup = false;
|
||||||
|
|
||||||
server;
|
server;
|
||||||
|
|
||||||
@ -80,6 +81,12 @@ class SetupDatabase {
|
|||||||
let tempServer;
|
let tempServer;
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
|
// Disable Keep Alive, otherwise the server will not shutdown, as the client will keep the connection alive
|
||||||
|
app.use(function (req, res, next) {
|
||||||
|
res.setHeader("Connection", "close");
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
app.get("/", async (request, response) => {
|
app.get("/", async (request, response) => {
|
||||||
response.redirect("/setup-database");
|
response.redirect("/setup-database");
|
||||||
});
|
});
|
||||||
@ -91,9 +98,12 @@ class SetupDatabase {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/info", (request, response) => {
|
app.get("/setup-database-info", (request, response) => {
|
||||||
allowDevAllOrigin(response);
|
allowDevAllOrigin(response);
|
||||||
|
console.log("Request /setup-database-info");
|
||||||
response.json({
|
response.json({
|
||||||
|
runningSetup: this.runningSetup,
|
||||||
|
needSetup: this.needSetup,
|
||||||
isEnabledEmbeddedMariaDB: this.isEnabledEmbeddedMariaDB(),
|
isEnabledEmbeddedMariaDB: this.isEnabledEmbeddedMariaDB(),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -101,7 +111,12 @@ class SetupDatabase {
|
|||||||
app.post("/setup-database", async (request, response) => {
|
app.post("/setup-database", async (request, response) => {
|
||||||
allowDevAllOrigin(response);
|
allowDevAllOrigin(response);
|
||||||
|
|
||||||
console.log(request);
|
if (this.runningSetup) {
|
||||||
|
response.status(400).json("Setup is already running");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.runningSetup = true;
|
||||||
|
|
||||||
let dbConfig = request.body.dbConfig;
|
let dbConfig = request.body.dbConfig;
|
||||||
|
|
||||||
@ -114,42 +129,50 @@ class SetupDatabase {
|
|||||||
// Validate input
|
// Validate input
|
||||||
if (typeof dbConfig !== "object") {
|
if (typeof dbConfig !== "object") {
|
||||||
response.status(400).json("Invalid dbConfig");
|
response.status(400).json("Invalid dbConfig");
|
||||||
|
this.runningSetup = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbConfig.type) {
|
if (!dbConfig.type) {
|
||||||
response.status(400).json("Database Type is required");
|
response.status(400).json("Database Type is required");
|
||||||
|
this.runningSetup = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!supportedDBTypes.includes(dbConfig.type)) {
|
if (!supportedDBTypes.includes(dbConfig.type)) {
|
||||||
response.status(400).json("Unsupported Database Type");
|
response.status(400).json("Unsupported Database Type");
|
||||||
|
this.runningSetup = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbConfig.type === "mariadb") {
|
if (dbConfig.type === "mariadb") {
|
||||||
if (!dbConfig.hostname) {
|
if (!dbConfig.hostname) {
|
||||||
response.status(400).json("Hostname is required");
|
response.status(400).json("Hostname is required");
|
||||||
|
this.runningSetup = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbConfig.port) {
|
if (!dbConfig.port) {
|
||||||
response.status(400).json("Port is required");
|
response.status(400).json("Port is required");
|
||||||
|
this.runningSetup = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbConfig.dbName) {
|
if (!dbConfig.dbName) {
|
||||||
response.status(400).json("Database name is required");
|
response.status(400).json("Database name is required");
|
||||||
|
this.runningSetup = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbConfig.username) {
|
if (!dbConfig.username) {
|
||||||
response.status(400).json("Username is required");
|
response.status(400).json("Username is required");
|
||||||
|
this.runningSetup = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbConfig.password) {
|
if (!dbConfig.password) {
|
||||||
response.status(400).json("Password is required");
|
response.status(400).json("Password is required");
|
||||||
|
this.runningSetup = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,12 +185,17 @@ class SetupDatabase {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Shutdown down this express and start the main server
|
// Shutdown down this express and start the main server
|
||||||
log.info("setup-database", "Database is configured, close setup-database server and start the main server now.");
|
log.info("setup-database", "Database is configured, close the setup-database server and start the main server now.");
|
||||||
if (tempServer) {
|
if (tempServer) {
|
||||||
tempServer.close();
|
tempServer.close(() => {
|
||||||
}
|
log.info("setup-database", "The setup-database server is closed");
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
app.use("/", expressStaticGzip("dist", {
|
app.use("/", expressStaticGzip("dist", {
|
||||||
enableBrotli: true,
|
enableBrotli: true,
|
||||||
|
@ -62,6 +62,8 @@ export default {
|
|||||||
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
// TODO: Check if it is a database setup
|
||||||
|
|
||||||
this.$root.getSocket().emit("needSetup", (needSetup) => {
|
this.$root.getSocket().emit("needSetup", (needSetup) => {
|
||||||
if (! needSetup) {
|
if (! needSetup) {
|
||||||
this.$router.push("/");
|
this.$router.push("/");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="form-container">
|
<div v-if="show" class="form-container">
|
||||||
<form @submit.prevent="submit">
|
<form @submit.prevent="submit">
|
||||||
<div>
|
<div>
|
||||||
<object width="64" height="64" data="/icon.svg" />
|
<object width="64" height="64" data="/icon.svg" />
|
||||||
@ -8,6 +8,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-if="info.runningSetup" class="mt-5">
|
||||||
|
<div class="alert alert-success" role="alert">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<strong>Setting up the database. It may take a while, please be patient.</strong>
|
||||||
|
<div class="spinner-border ml-auto" role="status" aria-hidden="true"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template v-if="!info.runningSetup">
|
||||||
<div class="form-floating short mt-3">
|
<div class="form-floating short mt-3">
|
||||||
<select id="language" v-model="$root.language" class="form-select">
|
<select id="language" v-model="$root.language" class="form-select">
|
||||||
<option v-for="(lang, i) in $i18n.availableLocales" :key="`Lang${i}`" :value="lang">
|
<option v-for="(lang, i) in $i18n.availableLocales" :key="`Lang${i}`" :value="lang">
|
||||||
@ -22,7 +32,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="btn-group" role="group" aria-label="Basic radio toggle button group">
|
<div class="btn-group" role="group" aria-label="Basic radio toggle button group">
|
||||||
<template v-if="isEnabledEmbeddedMariaDB">
|
<template v-if="info.isEnabledEmbeddedMariaDB">
|
||||||
<input id="btnradio3" v-model="dbConfig.type" type="radio" class="btn-check" autocomplete="off" value="embedded-mariadb">
|
<input id="btnradio3" v-model="dbConfig.type" type="radio" class="btn-check" autocomplete="off" value="embedded-mariadb">
|
||||||
|
|
||||||
<label class="btn btn-outline-primary" for="btnradio3">
|
<label class="btn btn-outline-primary" for="btnradio3">
|
||||||
@ -85,6 +95,7 @@
|
|||||||
<button class="btn btn-primary mt-4 short" type="submit" :disabled="disabledButton">
|
<button class="btn btn-primary mt-4 short" type="submit" :disabled="disabledButton">
|
||||||
{{ $t("Next") }}
|
{{ $t("Next") }}
|
||||||
</button>
|
</button>
|
||||||
|
</template>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -98,8 +109,7 @@ const toast = useToast();
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
processing: false,
|
show: false,
|
||||||
isEnabledEmbeddedMariaDB: false,
|
|
||||||
dbConfig: {
|
dbConfig: {
|
||||||
type: undefined,
|
type: undefined,
|
||||||
port: 3306,
|
port: 3306,
|
||||||
@ -108,20 +118,31 @@ export default {
|
|||||||
password: "",
|
password: "",
|
||||||
dbName: "kuma",
|
dbName: "kuma",
|
||||||
},
|
},
|
||||||
|
info: {
|
||||||
|
needSetup: false,
|
||||||
|
runningSetup: false,
|
||||||
|
isEnabledEmbeddedMariaDB: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
disabledButton() {
|
disabledButton() {
|
||||||
return this.dbConfig.type === undefined || this.processing;
|
return this.dbConfig.type === undefined || this.info.runningSetup;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
let res = await axios.get("/info");
|
let res = await axios.get("/setup-database-info");
|
||||||
this.isEnabledEmbeddedMariaDB = res.data.isEnabledEmbeddedMariaDB;
|
this.info = res.data;
|
||||||
|
|
||||||
|
if (this.info && this.info.needSetup === false) {
|
||||||
|
location.href = "/setup";
|
||||||
|
} else {
|
||||||
|
this.show = true;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async submit() {
|
async submit() {
|
||||||
this.processing = true;
|
this.info.runningSetup = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let res = await axios.post("/setup-database", {
|
let res = await axios.post("/setup-database", {
|
||||||
@ -129,12 +150,11 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await sleep(2000);
|
await sleep(2000);
|
||||||
// TODO: an interval to check if the main server is ready, it is ready, go to "/" again to continue the setup of admin account
|
|
||||||
await this.goToMainServerWhenReady();
|
await this.goToMainServerWhenReady();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast.error(e.response.data);
|
toast.error(e.response.data);
|
||||||
} finally {
|
} finally {
|
||||||
this.processing = false;
|
this.info.runningSetup = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
@ -142,10 +162,14 @@ export default {
|
|||||||
async goToMainServerWhenReady() {
|
async goToMainServerWhenReady() {
|
||||||
try {
|
try {
|
||||||
console.log("Trying...");
|
console.log("Trying...");
|
||||||
let res = await axios.get("/api/entry-page");
|
let res = await axios.get("/setup-database-info");
|
||||||
if (res.data && res.data.type === "entryPage") {
|
if (res.data && res.data.needSetup === false) {
|
||||||
location.href = "/";
|
this.show = false;
|
||||||
|
location.href = "/setup";
|
||||||
} else {
|
} else {
|
||||||
|
if (res.data) {
|
||||||
|
this.info = res.data;
|
||||||
|
}
|
||||||
throw new Error("not ready");
|
throw new Error("not ready");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -153,6 +177,10 @@ export default {
|
|||||||
await sleep(2000);
|
await sleep(2000);
|
||||||
await this.goToMainServerWhenReady();
|
await this.goToMainServerWhenReady();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
test() {
|
||||||
|
toast.error("not implemented");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user