mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-06-14 16:42:35 +02:00
add support for deployment in subfolder
configurable using BASE_PATH env variable
This commit is contained in:
parent
0ca68f791f
commit
8cf827e6e1
8 changed files with 34 additions and 19 deletions
|
@ -7,6 +7,7 @@ const postcssRTLCSS = require("postcss-rtlcss");
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
base: "./",
|
||||||
plugins: [
|
plugins: [
|
||||||
vue(),
|
vue(),
|
||||||
legacy({
|
legacy({
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<base href="/" >
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="./apple-touch-icon.png">
|
||||||
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
|
<link rel="icon" type="image/svg+xml" href="./icon.svg" />
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="./manifest.json" />
|
||||||
<meta name="theme-color" id="theme-color" content="" />
|
<meta name="theme-color" id="theme-color" content="" />
|
||||||
<meta name="description" content="Uptime Kuma monitoring tool" />
|
<meta name="description" content="Uptime Kuma monitoring tool" />
|
||||||
<title>Uptime Kuma</title>
|
<title>Uptime Kuma</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script type="module" src="/src/main.js"></script>
|
<script type="module" src="./src/main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "Uptime Kuma",
|
"name": "Uptime Kuma",
|
||||||
"short_name": "Uptime Kuma",
|
"short_name": "Uptime Kuma",
|
||||||
"start_url": "/",
|
"start_url": "./",
|
||||||
"background_color": "#fff",
|
"background_color": "#fff",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"icons": [
|
"icons": [
|
||||||
|
|
|
@ -76,6 +76,8 @@ if (hostname) {
|
||||||
|
|
||||||
const port = parseInt(process.env.UPTIME_KUMA_PORT || process.env.PORT || args.port || 3001);
|
const port = parseInt(process.env.UPTIME_KUMA_PORT || process.env.PORT || args.port || 3001);
|
||||||
|
|
||||||
|
const basePath = process.env.UPTIME_KUMA_BASE_PATH || process.env.BASE_PATH || '/'
|
||||||
|
|
||||||
// SSL
|
// SSL
|
||||||
const sslKey = process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || args["ssl-key"] || undefined;
|
const sslKey = process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || args["ssl-key"] || undefined;
|
||||||
const sslCert = process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || args["ssl-cert"] || undefined;
|
const sslCert = process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || args["ssl-cert"] || undefined;
|
||||||
|
@ -113,7 +115,7 @@ if (sslKey && sslCert) {
|
||||||
server = http.createServer(app);
|
server = http.createServer(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
const io = new Server(server);
|
const io = new Server(server, {path: basePath + '/socket.io'});
|
||||||
module.exports.io = io;
|
module.exports.io = io;
|
||||||
|
|
||||||
// Must be after io instantiation
|
// Must be after io instantiation
|
||||||
|
@ -165,6 +167,7 @@ let indexHTML = "";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
indexHTML = fs.readFileSync("./dist/index.html").toString();
|
indexHTML = fs.readFileSync("./dist/index.html").toString();
|
||||||
|
indexHTML = indexHTML.replace(/\<base href.*?\>/, `<base href="${basePath}">`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// "dist/index.html" is not necessary for development
|
// "dist/index.html" is not necessary for development
|
||||||
if (process.env.NODE_ENV !== "development") {
|
if (process.env.NODE_ENV !== "development") {
|
||||||
|
@ -180,6 +183,8 @@ exports.entryPage = "dashboard";
|
||||||
await initDatabase(testMode);
|
await initDatabase(testMode);
|
||||||
|
|
||||||
exports.entryPage = await setting("entryPage");
|
exports.entryPage = await setting("entryPage");
|
||||||
|
|
||||||
|
const mainRouter = express.Router();
|
||||||
|
|
||||||
console.log("Adding route");
|
console.log("Adding route");
|
||||||
|
|
||||||
|
@ -188,16 +193,16 @@ exports.entryPage = "dashboard";
|
||||||
// ***************************
|
// ***************************
|
||||||
|
|
||||||
// Entry Page
|
// Entry Page
|
||||||
app.get("/", async (_request, response) => {
|
mainRouter.get("/", async (_request, response) => {
|
||||||
if (exports.entryPage === "statusPage") {
|
if (exports.entryPage === "statusPage") {
|
||||||
response.redirect("/status");
|
response.redirect("status");
|
||||||
} else {
|
} else {
|
||||||
response.redirect("/dashboard");
|
response.redirect("dashboard");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Robots.txt
|
// Robots.txt
|
||||||
app.get("/robots.txt", async (_request, response) => {
|
mainRouter.get("/robots.txt", async (_request, response) => {
|
||||||
let txt = "User-agent: *\nDisallow:";
|
let txt = "User-agent: *\nDisallow:";
|
||||||
if (! await setting("searchEngineIndex")) {
|
if (! await setting("searchEngineIndex")) {
|
||||||
txt += " /";
|
txt += " /";
|
||||||
|
@ -210,29 +215,31 @@ exports.entryPage = "dashboard";
|
||||||
|
|
||||||
// Prometheus API metrics /metrics
|
// Prometheus API metrics /metrics
|
||||||
// With Basic Auth using the first user's username/password
|
// With Basic Auth using the first user's username/password
|
||||||
app.get("/metrics", basicAuth, prometheusAPIMetrics());
|
mainRouter.get("/metrics", basicAuth, prometheusAPIMetrics());
|
||||||
|
|
||||||
app.use("/", express.static("dist"));
|
mainRouter.use("/", express.static("dist"));
|
||||||
|
|
||||||
// ./data/upload
|
// ./data/upload
|
||||||
app.use("/upload", express.static(Database.uploadDir));
|
mainRouter.use("/upload", express.static(Database.uploadDir));
|
||||||
|
|
||||||
app.get("/.well-known/change-password", async (_, response) => {
|
mainRouter.get("/.well-known/change-password", async (_, response) => {
|
||||||
response.redirect("https://github.com/louislam/uptime-kuma/wiki/Reset-Password-via-CLI");
|
response.redirect("https://github.com/louislam/uptime-kuma/wiki/Reset-Password-via-CLI");
|
||||||
});
|
});
|
||||||
|
|
||||||
// API Router
|
// API Router
|
||||||
const apiRouter = require("./routers/api-router");
|
const apiRouter = require("./routers/api-router");
|
||||||
app.use(apiRouter);
|
mainRouter.use(apiRouter);
|
||||||
|
|
||||||
// Universal Route Handler, must be at the end of all express routes.
|
// Universal Route Handler, must be at the end of all express routes.
|
||||||
app.get("*", async (_request, response) => {
|
mainRouter.get("*", async (_request, response) => {
|
||||||
if (_request.originalUrl.startsWith("/upload/")) {
|
if (_request.originalUrl.startsWith("/upload/")) {
|
||||||
response.status(404).send("File not found.");
|
response.status(404).send("File not found.");
|
||||||
} else {
|
} else {
|
||||||
response.send(indexHTML);
|
response.send(indexHTML);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.use(basePath, mainRouter);
|
||||||
|
|
||||||
console.log("Adding socket handler");
|
console.log("Adding socket handler");
|
||||||
io.on("connection", async (socket) => {
|
io.on("connection", async (socket) => {
|
||||||
|
|
|
@ -90,7 +90,7 @@ module.exports.statusPageSocketHandler = (socket) => {
|
||||||
|
|
||||||
// Convert to file
|
// Convert to file
|
||||||
await ImageDataURI.outputFile(imgDataUrl, Database.uploadDir + "logo.png");
|
await ImageDataURI.outputFile(imgDataUrl, Database.uploadDir + "logo.png");
|
||||||
config.logo = "/upload/logo.png?t=" + Date.now();
|
config.logo = "./upload/logo.png?t=" + Date.now();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
config.icon = imgDataUrl;
|
config.icon = imgDataUrl;
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
|
|
||||||
<ul class="nav nav-pills">
|
<ul class="nav nav-pills">
|
||||||
<li class="nav-item me-2">
|
<li class="nav-item me-2">
|
||||||
<a href="/status" class="nav-link status-page">
|
<router-link href="/status" class="nav-link status-page">
|
||||||
<font-awesome-icon icon="stream" /> {{ $t("Status Page") }}
|
<font-awesome-icon icon="stream" /> {{ $t("Status Page") }}
|
||||||
</a>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="$root.loggedIn" class="nav-item me-2">
|
<li v-if="$root.loggedIn" class="nav-item me-2">
|
||||||
<router-link to="/dashboard" class="nav-link">
|
<router-link to="/dashboard" class="nav-link">
|
||||||
|
|
|
@ -67,8 +67,11 @@ export default {
|
||||||
wsHost = protocol + location.host;
|
wsHost = protocol + location.host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const urlBase = document.querySelector("head base").getAttribute("href");
|
||||||
|
|
||||||
socket = io(wsHost, {
|
socket = io(wsHost, {
|
||||||
transports: ["websocket"],
|
transports: ["websocket"],
|
||||||
|
path: urlBase + "/socket.io"
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("info", (info) => {
|
socket.on("info", (info) => {
|
||||||
|
|
3
vue.config.js
Normal file
3
vue.config.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
publicPath: './',
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue