mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-12-17 19:54:39 -05:00
Merge branch 'master' into 1.23.X-merge-to-2.X.X
# Conflicts: # docker/debian-base.dockerfile # package-lock.json # server/database.js # server/model/monitor.js # server/uptime-kuma-server.js # server/util-server.js
This commit is contained in:
commit
ace1fe00c2
@ -6,7 +6,7 @@ You can modifiy Uptime Kuma in your browser without setting up a local developme
|
||||
|
||||
1. Click `Code` -> `Create codespace on master`
|
||||
2. Wait a few minutes until you see there are two exposed ports
|
||||
3. Go to the `3000` url, see if it is working
|
||||
3. Go to the `3000` url, see if it is working
|
||||
|
||||
![image](https://github.com/louislam/uptime-kuma/assets/1336778/909b2eb4-4c5e-44e4-ac26-6d20ed856e7f)
|
||||
|
||||
|
@ -13,9 +13,10 @@
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"dbaeumer.vscode-eslint"
|
||||
]
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"GitHub.copilot-chat"
|
||||
]
|
||||
}
|
||||
},
|
||||
"forwardPorts": [3000, 3001]
|
||||
|
@ -1,6 +1,6 @@
|
||||
/.idea
|
||||
/node_modules
|
||||
/data
|
||||
/data*
|
||||
/cypress
|
||||
/out
|
||||
/test
|
||||
@ -30,7 +30,6 @@ SECURITY.md
|
||||
tsconfig.json
|
||||
.env
|
||||
/tmp
|
||||
/babel.config.js
|
||||
/ecosystem.config.js
|
||||
/extra/healthcheck.exe
|
||||
/extra/healthcheck
|
||||
|
66
.eslintrc.js
66
.eslintrc.js
@ -1,6 +1,7 @@
|
||||
module.exports = {
|
||||
ignorePatterns: [
|
||||
"test/*",
|
||||
"test/*.js",
|
||||
"test/cypress",
|
||||
"server/modules/apicache/*",
|
||||
"src/util.js"
|
||||
],
|
||||
@ -14,13 +15,18 @@ module.exports = {
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:vue/vue3-recommended",
|
||||
"plugin:jsdoc/recommended-error",
|
||||
],
|
||||
parser: "vue-eslint-parser",
|
||||
parserOptions: {
|
||||
parser: "@babel/eslint-parser",
|
||||
parser: "@typescript-eslint/parser",
|
||||
sourceType: "module",
|
||||
requireConfigFile: false,
|
||||
},
|
||||
plugins: [
|
||||
"jsdoc",
|
||||
"@typescript-eslint",
|
||||
],
|
||||
rules: {
|
||||
"yoda": "error",
|
||||
eqeqeq: [ "warn", "smart" ],
|
||||
@ -71,7 +77,7 @@ module.exports = {
|
||||
"no-var": "error",
|
||||
"key-spacing": "warn",
|
||||
"keyword-spacing": "warn",
|
||||
"space-infix-ops": "warn",
|
||||
"space-infix-ops": "error",
|
||||
"arrow-spacing": "warn",
|
||||
"no-trailing-spaces": "error",
|
||||
"no-constant-condition": [ "error", {
|
||||
@ -97,7 +103,43 @@ module.exports = {
|
||||
}],
|
||||
"no-control-regex": "off",
|
||||
"one-var": [ "error", "never" ],
|
||||
"max-statements-per-line": [ "error", { "max": 1 }]
|
||||
"max-statements-per-line": [ "error", { "max": 1 }],
|
||||
"jsdoc/check-tag-names": [
|
||||
"error",
|
||||
{
|
||||
"definedTags": [ "link" ]
|
||||
}
|
||||
],
|
||||
"jsdoc/no-undefined-types": "off",
|
||||
"jsdoc/no-defaults": [
|
||||
"error",
|
||||
{ "noOptionalParamNames": true }
|
||||
],
|
||||
"jsdoc/require-throws": "warn",
|
||||
"jsdoc/require-jsdoc": [
|
||||
"error",
|
||||
{
|
||||
"require": {
|
||||
"FunctionDeclaration": true,
|
||||
"MethodDefinition": true,
|
||||
}
|
||||
}
|
||||
],
|
||||
"jsdoc/no-blank-block-descriptions": "error",
|
||||
"jsdoc/require-returns-description": "warn",
|
||||
"jsdoc/require-returns-check": [
|
||||
"error",
|
||||
{ "reportMissingReturnForUndefinedTypes": false }
|
||||
],
|
||||
"jsdoc/require-returns": [
|
||||
"warn",
|
||||
{
|
||||
"forceRequireReturn": true,
|
||||
"forceReturnsWithAsync": true
|
||||
}
|
||||
],
|
||||
"jsdoc/require-param-type": "warn",
|
||||
"jsdoc/require-param-description": "warn"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
@ -122,6 +164,22 @@ module.exports = {
|
||||
context: true,
|
||||
jestPuppeteer: true,
|
||||
},
|
||||
},
|
||||
|
||||
// Override for TypeScript
|
||||
{
|
||||
"files": [
|
||||
"**/*.ts",
|
||||
],
|
||||
extends: [
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
],
|
||||
"rules": {
|
||||
"jsdoc/require-returns-type": "off",
|
||||
"jsdoc/require-param-type": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"prefer-const": "off",
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
2
.github/ISSUE_TEMPLATE/security.md
vendored
2
.github/ISSUE_TEMPLATE/security.md
vendored
@ -12,8 +12,6 @@ labels:
|
||||
|
||||
DO NOT PROVIDE ANY DETAILS HERE. Please privately report to https://github.com/louislam/uptime-kuma/security/advisories/new.
|
||||
|
||||
|
||||
Why need this issue? It is because GitHub Advisory do not send a notification to @louislam, it is a workaround to do so.
|
||||
|
||||
Your GitHub Advisory URL:
|
||||
|
||||
|
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,7 +1,7 @@
|
||||
⚠️⚠️⚠️ Since we do not accept all types of pull requests and do not want to waste your time. Please be sure that you have read pull request rules:
|
||||
https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md#can-i-create-a-pull-request-for-uptime-kuma
|
||||
|
||||
Tick the checkbox if you understand [x]:
|
||||
Tick the checkbox if you understand [x]:
|
||||
- [ ] I have read and understand the pull request rules.
|
||||
|
||||
# Description
|
||||
|
35
.github/workflows/auto-test.yml
vendored
35
.github/workflows/auto-test.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest, windows-latest, ARM64]
|
||||
node: [ 14, 20 ]
|
||||
node: [ 14, 20.5 ]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
|
||||
steps:
|
||||
@ -71,27 +71,28 @@ jobs:
|
||||
- run: git config --global core.autocrlf false # Mainly for Windows
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js 14
|
||||
- name: Use Node.js 20
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14
|
||||
node-version: 20
|
||||
- run: npm install
|
||||
- run: npm run lint
|
||||
|
||||
e2e-tests:
|
||||
needs: [ check-linters ]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: git config --global core.autocrlf false # Mainly for Windows
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js 14
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14
|
||||
- run: npm install
|
||||
- run: npm run build
|
||||
- run: npm run cy:test
|
||||
# TODO: Temporarily disable, as it cannot pass the test in 2.0.0 yet
|
||||
# e2e-tests:
|
||||
# needs: [ check-linters ]
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - run: git config --global core.autocrlf false # Mainly for Windows
|
||||
# - uses: actions/checkout@v3
|
||||
#
|
||||
# - name: Use Node.js 14
|
||||
# uses: actions/setup-node@v3
|
||||
# with:
|
||||
# node-version: 14
|
||||
# - run: npm install
|
||||
# - run: npm run build
|
||||
# - run: npm run cy:test
|
||||
|
||||
frontend-unit-tests:
|
||||
needs: [ check-linters ]
|
||||
|
43
.github/workflows/codeql-analysis.yml
vendored
Normal file
43
.github/workflows/codeql-analysis.yml
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master", "1.23.X"]
|
||||
pull_request:
|
||||
branches: [ "master", "1.23.X"]
|
||||
schedule:
|
||||
- cron: '16 22 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 360
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'go', 'javascript-typescript' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
17
.github/workflows/prevent-file-change.yml
vendored
Normal file
17
.github/workflows/prevent-file-change.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
name: prevent-file-change
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
check-file-changes:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Prevent file change
|
||||
uses: xalvarez/prevent-file-change-action@v1
|
||||
with:
|
||||
githubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Regex, /src/lang/*.json is not allowed to be changed, except for /src/lang/en.json
|
||||
pattern: '^(?!src/lang/en\.json$)src/lang/.*\.json$'
|
||||
trustedAuthors: UptimeKumaBot
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,6 +7,7 @@ dist-ssr
|
||||
|
||||
/data
|
||||
!/data/.gitkeep
|
||||
/data*
|
||||
.vscode
|
||||
|
||||
/private
|
||||
|
@ -34,24 +34,27 @@ Yes or no, it depends on what you will try to do. Since I don't want to waste yo
|
||||
|
||||
Here are some references:
|
||||
|
||||
### ✅ Usually accepted:
|
||||
### ✅ Usually accepted
|
||||
|
||||
- Bug fix
|
||||
- Security fix
|
||||
- Adding notification providers
|
||||
- Adding new language files (see [these instructions](https://github.com/louislam/uptime-kuma/blob/master/src/lang/README.md))
|
||||
- Adding new language keys: `$t("...")`
|
||||
|
||||
### ⚠️ Discussion required:
|
||||
### ⚠️ Discussion required
|
||||
|
||||
- Large pull requests
|
||||
- New features
|
||||
|
||||
### ❌ Won't be merged:
|
||||
### ❌ Won't be merged
|
||||
|
||||
- A dedicated PR for translating existing languages (see [these instructions](https://github.com/louislam/uptime-kuma/blob/master/src/lang/README.md))
|
||||
- Do not pass the auto-test
|
||||
- Any breaking changes
|
||||
- Duplicated pull requests
|
||||
- Buggy
|
||||
- UI/UX is not close to Uptime Kuma
|
||||
- UI/UX is not close to Uptime Kuma
|
||||
- Modifications or deletions of existing logic without a valid reason.
|
||||
- Adding functions that is completely out of scope
|
||||
- Converting existing code into other programming languages
|
||||
@ -65,7 +68,6 @@ I will assign your pull request to a [milestone](https://github.com/louislam/upt
|
||||
|
||||
Also, please don't rush or ask for an ETA, because I have to understand the pull request, make sure it is no breaking changes and stick to my vision of this project, especially for large pull requests.
|
||||
|
||||
|
||||
### Recommended Pull Request Guideline
|
||||
|
||||
Before deep into coding, discussion first is preferred. Creating an empty pull request for discussion would be recommended.
|
||||
@ -112,6 +114,18 @@ I personally do not like something that requires so many configurations before y
|
||||
- IDE that supports [`ESLint`](https://eslint.org/) and EditorConfig (I am using [`IntelliJ IDEA`](https://www.jetbrains.com/idea/))
|
||||
- A SQLite GUI tool (f.ex. [`SQLite Expert Personal`](https://www.sqliteexpert.com/download.html) or [`DBeaver Community`](https://dbeaver.io/download/))
|
||||
|
||||
### GitHub Codespace
|
||||
|
||||
If you don't want to setup an local environment, you can now develop on GitHub Codespace, read more:
|
||||
|
||||
https://github.com/louislam/uptime-kuma/tree/master/.devcontainer
|
||||
|
||||
## Git Branches
|
||||
|
||||
- `master`: 2.X.X development. If you want to add a new feature, your pull request should base on this.
|
||||
- `1.23.X`: 1.23.X development. If you want to fix a bug for v1 and v2, your pull request should base on this.
|
||||
- All other branches are unused, outdated or for dev.
|
||||
|
||||
## Install Dependencies for Development
|
||||
|
||||
```bash
|
||||
@ -131,7 +145,8 @@ npm run dev
|
||||
```
|
||||
|
||||
But sometimes, you would like to restart the server, but not the frontend, you can run these commands in two terminals:
|
||||
```
|
||||
|
||||
```bash
|
||||
npm run start-frontend-dev
|
||||
npm run start-server-dev
|
||||
```
|
||||
@ -140,15 +155,14 @@ npm run start-server-dev
|
||||
|
||||
It binds to `0.0.0.0:3001` by default.
|
||||
|
||||
|
||||
It is mainly a socket.io app + express.js.
|
||||
|
||||
express.js is used for:
|
||||
express.js is used for:
|
||||
|
||||
- entry point such as redirecting to a status page or the dashboard
|
||||
- serving the frontend built files (index.html, .js and .css etc.)
|
||||
- serving internal APIs of the status page
|
||||
|
||||
|
||||
### Structure in /server/
|
||||
|
||||
- jobs/ (Jobs that are running in another process)
|
||||
@ -163,9 +177,9 @@ express.js is used for:
|
||||
|
||||
## Frontend Dev Server
|
||||
|
||||
It binds to `0.0.0.0:3000` by default. The frontend dev server is used for development only.
|
||||
It binds to `0.0.0.0:3000` by default. The frontend dev server is used for development only.
|
||||
|
||||
For production, it is not used. It will be compiled to `dist` directory instead.
|
||||
For production, it is not used. It will be compiled to `dist` directory instead.
|
||||
|
||||
You can use Vue.js devtools Chrome extension for debugging.
|
||||
|
||||
@ -187,8 +201,7 @@ The data and socket logic are in `src/mixins/socket.js`.
|
||||
|
||||
## Database Migration
|
||||
|
||||
1. Create `patch-{name}.sql` in `./db/`
|
||||
2. Add your patch filename in the `patchList` list in `./server/database.js`
|
||||
See: https://github.com/louislam/uptime-kuma/tree/master/db/knex_migrations
|
||||
|
||||
## Unit Test
|
||||
|
||||
@ -220,7 +233,7 @@ If for security / bug / other reasons, a library must be updated, breaking chang
|
||||
|
||||
Please add **all** the strings which are translatable to `src/lang/en.json` (If translation keys are omitted, they can not be translated).
|
||||
|
||||
**Don't include any other languages in your initial Pull-Request** (even if this is your mother tongue), to avoid merge-conflicts between weblate and `master`.
|
||||
**Don't include any other languages in your initial Pull-Request** (even if this is your mother tongue), to avoid merge-conflicts between weblate and `master`.
|
||||
The translations can then (after merging a PR into `master`) be translated by awesome people donating their language skills.
|
||||
|
||||
If you want to help by translating Uptime Kuma into your language, please visit the [instructions on how to translate using weblate](https://github.com/louislam/uptime-kuma/blob/master/src/lang/README.md).
|
||||
@ -236,6 +249,42 @@ Since there is no way to make a pull request to wiki's repo, I have set up anoth
|
||||
|
||||
https://github.com/louislam/uptime-kuma-wiki
|
||||
|
||||
## Docker
|
||||
|
||||
### Arch
|
||||
|
||||
- amd64
|
||||
- arm64
|
||||
- armv7
|
||||
|
||||
### Docker Tags
|
||||
|
||||
#### v2
|
||||
|
||||
- `2`, `latest-2`: v2 with full features such as Chromium and bundled MariaDB
|
||||
- `2.x.x`
|
||||
- `2-slim`: v2 with basic features
|
||||
- `2.x.x-slim`
|
||||
- `beta2`: Latest beta build
|
||||
- `2.x.x-beta.x`
|
||||
- `nightly2`: Dev build
|
||||
- `base2`: Basic Debian setup without Uptime Kuma source code (Full features)
|
||||
- `base2-slim`: Basic Debian setup without Uptime Kuma source code
|
||||
- `pr-test2`: For testing pull request without setting up a local environment
|
||||
|
||||
#### v1
|
||||
|
||||
- `1`, `latest`, `1-debian`, `debian`: Latest version of v1
|
||||
- `1.x.x`, `1.x.x-debian`
|
||||
- `1.x.x-beta.x`: Beta build
|
||||
- `beta`: Latest beta build
|
||||
- `nightly`: Dev build
|
||||
- `base-debian`: Basic Debian setup without Uptime Kuma source code
|
||||
- `pr-test`: For testing pull request without setting up a local environment
|
||||
- `base-alpine`: (Deprecated) Basic Alpine setup without Uptime Kuma source code
|
||||
- `1-alpine`, `alpine`: (Deprecated)
|
||||
- `1.x.x-alpine`: (Deprecated)
|
||||
|
||||
## Maintainer
|
||||
|
||||
Check the latest issues and pull requests:
|
||||
@ -246,12 +295,12 @@ https://github.com/louislam/uptime-kuma/issues?q=sort%3Aupdated-desc
|
||||
1. Draft a release note
|
||||
2. Make sure the repo is cleared
|
||||
3. If the healthcheck is updated, remember to re-compile it: `npm run build-docker-builder-go`
|
||||
3. `npm run release-final with env vars: `VERSION` and `GITHUB_TOKEN`
|
||||
4. Wait until the `Press any key to continue`
|
||||
5. `git push`
|
||||
6. Publish the release note as 1.X.X
|
||||
7. Press any key to continue
|
||||
8. Deploy to the demo server: `npm run deploy-demo-server`
|
||||
4. `npm run release-final` with env vars: `VERSION` and `GITHUB_TOKEN`
|
||||
5. Wait until the `Press any key to continue`
|
||||
6. `git push`
|
||||
7. Publish the release note as 1.X.X
|
||||
8. Press any key to continue
|
||||
9. Deploy to the demo server: `npm run deploy-demo-server`
|
||||
|
||||
Checking:
|
||||
|
||||
@ -284,3 +333,11 @@ git remote add production https://github.com/louislam/uptime-kuma.wiki.git
|
||||
git pull
|
||||
git push production master
|
||||
```
|
||||
|
||||
## Useful Commands
|
||||
|
||||
Change the base of a pull request such as `master` to `1.23.X`
|
||||
|
||||
```bash
|
||||
git rebase --onto <new parent> <old parent>
|
||||
```
|
||||
|
67
README.md
67
README.md
@ -23,17 +23,17 @@ It is a temporary live demo, all data will be deleted after 10 minutes. Use the
|
||||
|
||||
## ⭐ Features
|
||||
|
||||
* Monitoring uptime for HTTP(s) / TCP / HTTP(s) Keyword / HTTP(s) Json Query / Ping / DNS Record / Push / Steam Game Server / Docker Containers
|
||||
* Fancy, Reactive, Fast UI/UX
|
||||
* Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [90+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/tree/master/src/components/notifications)
|
||||
* 20-second intervals
|
||||
* [Multi Languages](https://github.com/louislam/uptime-kuma/tree/master/src/lang)
|
||||
* Multiple status pages
|
||||
* Map status pages to specific domains
|
||||
* Ping chart
|
||||
* Certificate info
|
||||
* Proxy support
|
||||
* 2FA support
|
||||
- Monitoring uptime for HTTP(s) / TCP / HTTP(s) Keyword / HTTP(s) Json Query / Ping / DNS Record / Push / Steam Game Server / Docker Containers
|
||||
- Fancy, Reactive, Fast UI/UX
|
||||
- Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [90+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/tree/master/src/components/notifications)
|
||||
- 20-second intervals
|
||||
- [Multi Languages](https://github.com/louislam/uptime-kuma/tree/master/src/lang)
|
||||
- Multiple status pages
|
||||
- Map status pages to specific domains
|
||||
- Ping chart
|
||||
- Certificate info
|
||||
- Proxy support
|
||||
- 2FA support
|
||||
|
||||
## 🔧 How to Install
|
||||
|
||||
@ -43,25 +43,27 @@ It is a temporary live demo, all data will be deleted after 10 minutes. Use the
|
||||
docker run -d --restart=always -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:1
|
||||
```
|
||||
|
||||
⚠️ Please use a **local volume** only. Other types such as NFS are not supported.
|
||||
|
||||
Uptime Kuma is now running on http://localhost:3001
|
||||
|
||||
> [!WARNING]
|
||||
> File Systems like **NFS** (Network File System) are **NOT** supported. Please map to a local directory or volume.
|
||||
|
||||
### 💪🏻 Non-Docker
|
||||
|
||||
Requirements:
|
||||
|
||||
- Platform
|
||||
- ✅ Major Linux distros such as Debian, Ubuntu, CentOS, Fedora and ArchLinux etc.
|
||||
- ✅ Windows 10 (x64), Windows Server 2012 R2 (x64) or higher
|
||||
- ❌ Replit / Heroku
|
||||
- [Node.js](https://nodejs.org/en/download/) 14 / 16 / 18 / 20.4
|
||||
- [npm](https://docs.npmjs.com/cli/) >= 7
|
||||
- [npm](https://docs.npmjs.com/cli/) 9
|
||||
- [Git](https://git-scm.com/downloads)
|
||||
- [pm2](https://pm2.keymetrics.io/) - For running Uptime Kuma in the background
|
||||
|
||||
```bash
|
||||
# Update your npm to the latest version
|
||||
npm install npm -g
|
||||
# Update your npm
|
||||
npm install npm@9 -g
|
||||
|
||||
git clone https://github.com/louislam/uptime-kuma.git
|
||||
cd uptime-kuma
|
||||
@ -76,9 +78,8 @@ npm install pm2 -g && pm2 install pm2-logrotate
|
||||
|
||||
# Start Server
|
||||
pm2 start server/server.js --name uptime-kuma
|
||||
|
||||
|
||||
```
|
||||
|
||||
Uptime Kuma is now running on http://localhost:3001
|
||||
|
||||
More useful PM2 Commands
|
||||
@ -91,10 +92,6 @@ pm2 monit
|
||||
pm2 save && pm2 startup
|
||||
```
|
||||
|
||||
### Windows Portable (x64)
|
||||
|
||||
https://github.com/louislam/uptime-kuma/releases/download/1.23.1/uptime-kuma-windows-x64-portable-1.23.1.zip
|
||||
|
||||
### Advanced Installation
|
||||
|
||||
If you need more options or need to browse via a reverse proxy, please read:
|
||||
@ -113,10 +110,6 @@ I will assign requests/issues to the next milestone.
|
||||
|
||||
https://github.com/louislam/uptime-kuma/milestones
|
||||
|
||||
Project Plan:
|
||||
|
||||
https://github.com/users/louislam/projects/4/views/1
|
||||
|
||||
## ❤️ Sponsors
|
||||
|
||||
Thank you so much! (GitHub Sponsors will be updated manually. OpenCollective sponsors will be updated automatically, the list will be cached by GitHub though. It may need some time to be updated)
|
||||
@ -143,28 +136,27 @@ Telegram Notification Sample:
|
||||
|
||||
## Motivation
|
||||
|
||||
* I was looking for a self-hosted monitoring tool like "Uptime Robot", but it is hard to find a suitable one. One of the close ones is statping. Unfortunately, it is not stable and no longer maintained.
|
||||
* Want to build a fancy UI.
|
||||
* Learn Vue 3 and vite.js.
|
||||
* Show the power of Bootstrap 5.
|
||||
* Try to use WebSocket with SPA instead of REST API.
|
||||
* Deploy my first Docker image to Docker Hub.
|
||||
- I was looking for a self-hosted monitoring tool like "Uptime Robot", but it is hard to find a suitable one. One of the close ones is statping. Unfortunately, it is not stable and no longer maintained.
|
||||
- Want to build a fancy UI.
|
||||
- Learn Vue 3 and vite.js.
|
||||
- Show the power of Bootstrap 5.
|
||||
- Try to use WebSocket with SPA instead of REST API.
|
||||
- Deploy my first Docker image to Docker Hub.
|
||||
|
||||
If you love this project, please consider giving me a ⭐.
|
||||
|
||||
## 🗣️ Discussion / Ask for Help
|
||||
|
||||
⚠️ For any general or technical questions, please don't send me an email, as I am unable to provide support in that manner. I will not response if you asked such questions.
|
||||
⚠️ For any general or technical questions, please don't send me an email, as I am unable to provide support in that manner. I will not respond if you asked such questions.
|
||||
|
||||
I recommend using Google, GitHub Issues, or Uptime Kuma's Subreddit for finding answers to your question. If you cannot find the information you need, feel free to ask:
|
||||
|
||||
- [GitHub Issues](https://github.com/louislam/uptime-kuma/issues)
|
||||
- [Subreddit r/Uptime kuma](https://www.reddit.com/r/UptimeKuma/)
|
||||
|
||||
My Reddit account: [u/louislamlam](https://reddit.com/u/louislamlam).
|
||||
My Reddit account: [u/louislamlam](https://reddit.com/u/louislamlam).
|
||||
You can mention me if you ask a question on Reddit.
|
||||
|
||||
|
||||
## Contribute
|
||||
|
||||
### Test Pull Requests
|
||||
@ -179,15 +171,18 @@ https://github.com/louislam/uptime-kuma/wiki/Test-Pull-Requests
|
||||
Check out the latest beta release here: https://github.com/louislam/uptime-kuma/releases
|
||||
|
||||
### Bug Reports / Feature Requests
|
||||
|
||||
If you want to report a bug or request a new feature, feel free to open a [new issue](https://github.com/louislam/uptime-kuma/issues).
|
||||
|
||||
### Translations
|
||||
|
||||
If you want to translate Uptime Kuma into your language, please visit [Weblate Readme](https://github.com/louislam/uptime-kuma/blob/master/src/lang/README.md).
|
||||
|
||||
## Spelling & Grammar
|
||||
### Spelling & Grammar
|
||||
|
||||
Feel free to correct the grammar in the documentation or code.
|
||||
My mother language is not english and my grammar is not that great.
|
||||
|
||||
### Create Pull Requests
|
||||
|
||||
If you want to modify Uptime Kuma, please read this guide and follow the rules here: https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md
|
||||
|
@ -1,7 +0,0 @@
|
||||
const config = {};
|
||||
|
||||
if (process.env.TEST_FRONTEND) {
|
||||
config.presets = [ "@babel/preset-env" ];
|
||||
}
|
||||
|
||||
module.exports = config;
|
@ -1,4 +1,3 @@
|
||||
import legacy from "@vitejs/plugin-legacy";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import { defineConfig } from "vite";
|
||||
import visualizer from "rollup-plugin-visualizer";
|
||||
@ -24,9 +23,6 @@ export default defineConfig({
|
||||
plugins: [
|
||||
commonjs(),
|
||||
vue(),
|
||||
legacy({
|
||||
targets: [ "since 2015" ],
|
||||
}),
|
||||
visualizer({
|
||||
filename: "tmp/dist-stats.html"
|
||||
}),
|
||||
|
559
db/knex_init_db.js
Normal file
559
db/knex_init_db.js
Normal file
@ -0,0 +1,559 @@
|
||||
const { R } = require("redbean-node");
|
||||
const { log } = require("../src/util");
|
||||
|
||||
/**
|
||||
* ⚠️⚠️⚠️⚠️⚠️⚠️ DO NOT ADD ANYTHING HERE!
|
||||
* IF YOU NEED TO ADD FIELDS, ADD IT TO ./db/knex_migrations
|
||||
* See ./db/knex_migrations/README.md for more information
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function createTables() {
|
||||
log.info("mariadb", "Creating basic tables for MariaDB");
|
||||
const knex = R.knex;
|
||||
|
||||
// TODO: Should check later if it is really the final patch sql file.
|
||||
|
||||
// docker_host
|
||||
await knex.schema.createTable("docker_host", (table) => {
|
||||
table.increments("id");
|
||||
table.integer("user_id").unsigned().notNullable();
|
||||
table.string("docker_daemon", 255);
|
||||
table.string("docker_type", 255);
|
||||
table.string("name", 255);
|
||||
});
|
||||
|
||||
// group
|
||||
await knex.schema.createTable("group", (table) => {
|
||||
table.increments("id");
|
||||
table.string("name", 255).notNullable();
|
||||
table.datetime("created_date").notNullable().defaultTo(knex.fn.now());
|
||||
table.boolean("public").notNullable().defaultTo(false);
|
||||
table.boolean("active").notNullable().defaultTo(true);
|
||||
table.integer("weight").notNullable().defaultTo(1000);
|
||||
table.integer("status_page_id").unsigned();
|
||||
});
|
||||
|
||||
// proxy
|
||||
await knex.schema.createTable("proxy", (table) => {
|
||||
table.increments("id");
|
||||
table.integer("user_id").unsigned().notNullable();
|
||||
table.string("protocol", 10).notNullable();
|
||||
table.string("host", 255).notNullable();
|
||||
table.smallint("port").notNullable(); // TODO: Maybe a issue with MariaDB, need migration to int
|
||||
table.boolean("auth").notNullable();
|
||||
table.string("username", 255).nullable();
|
||||
table.string("password", 255).nullable();
|
||||
table.boolean("active").notNullable().defaultTo(true);
|
||||
table.boolean("default").notNullable().defaultTo(false);
|
||||
table.datetime("created_date").notNullable().defaultTo(knex.fn.now());
|
||||
|
||||
table.index("user_id", "proxy_user_id");
|
||||
});
|
||||
|
||||
// user
|
||||
await knex.schema.createTable("user", (table) => {
|
||||
table.increments("id");
|
||||
table.string("username", 255).notNullable().unique().collate("utf8_general_ci");
|
||||
table.string("password", 255);
|
||||
table.boolean("active").notNullable().defaultTo(true);
|
||||
table.string("timezone", 150);
|
||||
table.string("twofa_secret", 64);
|
||||
table.boolean("twofa_status").notNullable().defaultTo(false);
|
||||
table.string("twofa_last_token", 6);
|
||||
});
|
||||
|
||||
// monitor
|
||||
await knex.schema.createTable("monitor", (table) => {
|
||||
table.increments("id");
|
||||
table.string("name", 150);
|
||||
table.boolean("active").notNullable().defaultTo(true);
|
||||
table.integer("user_id").unsigned()
|
||||
.references("id").inTable("user")
|
||||
.onDelete("SET NULL")
|
||||
.onUpdate("CASCADE");
|
||||
table.integer("interval").notNullable().defaultTo(20);
|
||||
table.text("url");
|
||||
table.string("type", 20);
|
||||
table.integer("weight").defaultTo(2000);
|
||||
table.string("hostname", 255);
|
||||
table.integer("port");
|
||||
table.datetime("created_date").notNullable().defaultTo(knex.fn.now());
|
||||
table.string("keyword", 255);
|
||||
table.integer("maxretries").notNullable().defaultTo(0);
|
||||
table.boolean("ignore_tls").notNullable().defaultTo(false);
|
||||
table.boolean("upside_down").notNullable().defaultTo(false);
|
||||
table.integer("maxredirects").notNullable().defaultTo(10);
|
||||
table.text("accepted_statuscodes_json").notNullable().defaultTo("[\"200-299\"]");
|
||||
table.string("dns_resolve_type", 5);
|
||||
table.string("dns_resolve_server", 255);
|
||||
table.string("dns_last_result", 255);
|
||||
table.integer("retry_interval").notNullable().defaultTo(0);
|
||||
table.string("push_token", 20).defaultTo(null);
|
||||
table.text("method").notNullable().defaultTo("GET");
|
||||
table.text("body").defaultTo(null);
|
||||
table.text("headers").defaultTo(null);
|
||||
table.text("basic_auth_user").defaultTo(null);
|
||||
table.text("basic_auth_pass").defaultTo(null);
|
||||
table.integer("docker_host").unsigned()
|
||||
.references("id").inTable("docker_host");
|
||||
table.string("docker_container", 255);
|
||||
table.integer("proxy_id").unsigned()
|
||||
.references("id").inTable("proxy");
|
||||
table.boolean("expiry_notification").defaultTo(true);
|
||||
table.text("mqtt_topic");
|
||||
table.string("mqtt_success_message", 255);
|
||||
table.string("mqtt_username", 255);
|
||||
table.string("mqtt_password", 255);
|
||||
table.string("database_connection_string", 2000);
|
||||
table.text("database_query");
|
||||
table.string("auth_method", 250);
|
||||
table.text("auth_domain");
|
||||
table.text("auth_workstation");
|
||||
table.string("grpc_url", 255).defaultTo(null);
|
||||
table.text("grpc_protobuf").defaultTo(null);
|
||||
table.text("grpc_body").defaultTo(null);
|
||||
table.text("grpc_metadata").defaultTo(null);
|
||||
table.text("grpc_method").defaultTo(null);
|
||||
table.text("grpc_service_name").defaultTo(null);
|
||||
table.boolean("grpc_enable_tls").notNullable().defaultTo(false);
|
||||
table.string("radius_username", 255);
|
||||
table.string("radius_password", 255);
|
||||
table.string("radius_calling_station_id", 50);
|
||||
table.string("radius_called_station_id", 50);
|
||||
table.string("radius_secret", 255);
|
||||
table.integer("resend_interval").notNullable().defaultTo(0);
|
||||
table.integer("packet_size").notNullable().defaultTo(56);
|
||||
table.string("game", 255);
|
||||
});
|
||||
|
||||
// heartbeat
|
||||
await knex.schema.createTable("heartbeat", (table) => {
|
||||
table.increments("id");
|
||||
table.boolean("important").notNullable().defaultTo(false);
|
||||
table.integer("monitor_id").unsigned().notNullable()
|
||||
.references("id").inTable("monitor")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
table.smallint("status").notNullable();
|
||||
|
||||
table.text("msg");
|
||||
table.datetime("time").notNullable();
|
||||
table.integer("ping");
|
||||
table.integer("duration").notNullable().defaultTo(0);
|
||||
table.integer("down_count").notNullable().defaultTo(0);
|
||||
|
||||
table.index("important");
|
||||
table.index([ "monitor_id", "time" ], "monitor_time_index");
|
||||
table.index("monitor_id");
|
||||
table.index([ "monitor_id", "important", "time" ], "monitor_important_time_index");
|
||||
});
|
||||
|
||||
// incident
|
||||
await knex.schema.createTable("incident", (table) => {
|
||||
table.increments("id");
|
||||
table.string("title", 255).notNullable();
|
||||
table.text("content", 255).notNullable();
|
||||
table.string("style", 30).notNullable().defaultTo("warning");
|
||||
table.datetime("created_date").notNullable().defaultTo(knex.fn.now());
|
||||
table.datetime("last_updated_date");
|
||||
table.boolean("pin").notNullable().defaultTo(true);
|
||||
table.boolean("active").notNullable().defaultTo(true);
|
||||
table.integer("status_page_id").unsigned();
|
||||
});
|
||||
|
||||
// maintenance
|
||||
await knex.schema.createTable("maintenance", (table) => {
|
||||
table.increments("id");
|
||||
table.string("title", 150).notNullable();
|
||||
table.text("description").notNullable();
|
||||
table.integer("user_id").unsigned()
|
||||
.references("id").inTable("user")
|
||||
.onDelete("SET NULL")
|
||||
.onUpdate("CASCADE");
|
||||
table.boolean("active").notNullable().defaultTo(true);
|
||||
table.string("strategy", 50).notNullable().defaultTo("single");
|
||||
table.datetime("start_date");
|
||||
table.datetime("end_date");
|
||||
table.time("start_time");
|
||||
table.time("end_time");
|
||||
table.string("weekdays", 250).defaultTo("[]");
|
||||
table.text("days_of_month").defaultTo("[]");
|
||||
table.integer("interval_day");
|
||||
|
||||
table.index("active");
|
||||
table.index([ "strategy", "active" ], "manual_active");
|
||||
table.index("user_id", "maintenance_user_id");
|
||||
});
|
||||
|
||||
// status_page
|
||||
await knex.schema.createTable("status_page", (table) => {
|
||||
table.increments("id");
|
||||
table.string("slug", 255).notNullable().unique().collate("utf8_general_ci");
|
||||
table.string("title", 255).notNullable();
|
||||
table.text("description");
|
||||
table.string("icon", 255).notNullable();
|
||||
table.string("theme", 30).notNullable();
|
||||
table.boolean("published").notNullable().defaultTo(true);
|
||||
table.boolean("search_engine_index").notNullable().defaultTo(true);
|
||||
table.boolean("show_tags").notNullable().defaultTo(false);
|
||||
table.string("password");
|
||||
table.datetime("created_date").notNullable().defaultTo(knex.fn.now());
|
||||
table.datetime("modified_date").notNullable().defaultTo(knex.fn.now());
|
||||
table.text("footer_text");
|
||||
table.text("custom_css");
|
||||
table.boolean("show_powered_by").notNullable().defaultTo(true);
|
||||
table.string("google_analytics_tag_id");
|
||||
});
|
||||
|
||||
// maintenance_status_page
|
||||
await knex.schema.createTable("maintenance_status_page", (table) => {
|
||||
table.increments("id");
|
||||
|
||||
table.integer("status_page_id").unsigned().notNullable()
|
||||
.references("id").inTable("status_page")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
|
||||
table.integer("maintenance_id").unsigned().notNullable()
|
||||
.references("id").inTable("maintenance")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
});
|
||||
|
||||
// maintenance_timeslot
|
||||
await knex.schema.createTable("maintenance_timeslot", (table) => {
|
||||
table.increments("id");
|
||||
table.integer("maintenance_id").unsigned().notNullable()
|
||||
.references("id").inTable("maintenance")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
table.datetime("start_date").notNullable();
|
||||
table.datetime("end_date");
|
||||
table.boolean("generated_next").defaultTo(false);
|
||||
|
||||
table.index("maintenance_id");
|
||||
table.index([ "maintenance_id", "start_date", "end_date" ], "active_timeslot_index");
|
||||
table.index("generated_next", "generated_next_index");
|
||||
});
|
||||
|
||||
// monitor_group
|
||||
await knex.schema.createTable("monitor_group", (table) => {
|
||||
table.increments("id");
|
||||
table.integer("monitor_id").unsigned().notNullable()
|
||||
.references("id").inTable("monitor")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
table.integer("group_id").unsigned().notNullable()
|
||||
.references("id").inTable("group")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
table.integer("weight").notNullable().defaultTo(1000);
|
||||
table.boolean("send_url").notNullable().defaultTo(false);
|
||||
|
||||
table.index([ "monitor_id", "group_id" ], "fk");
|
||||
});
|
||||
// monitor_maintenance
|
||||
await knex.schema.createTable("monitor_maintenance", (table) => {
|
||||
table.increments("id");
|
||||
table.integer("monitor_id").unsigned().notNullable()
|
||||
.references("id").inTable("monitor")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
table.integer("maintenance_id").unsigned().notNullable()
|
||||
.references("id").inTable("maintenance")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
|
||||
table.index("maintenance_id", "maintenance_id_index2");
|
||||
table.index("monitor_id", "monitor_id_index");
|
||||
});
|
||||
|
||||
// notification
|
||||
await knex.schema.createTable("notification", (table) => {
|
||||
table.increments("id");
|
||||
table.string("name", 255);
|
||||
table.boolean("active").notNullable().defaultTo(true);
|
||||
table.integer("user_id").unsigned();
|
||||
table.boolean("is_default").notNullable().defaultTo(false);
|
||||
table.text("config", "longtext");
|
||||
});
|
||||
|
||||
// monitor_notification
|
||||
await knex.schema.createTable("monitor_notification", (table) => {
|
||||
table.increments("id").unsigned(); // TODO: no auto increment????
|
||||
table.integer("monitor_id").unsigned().notNullable()
|
||||
.references("id").inTable("monitor")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
table.integer("notification_id").unsigned().notNullable()
|
||||
.references("id").inTable("notification")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
|
||||
table.index([ "monitor_id", "notification_id" ], "monitor_notification_index");
|
||||
});
|
||||
|
||||
// tag
|
||||
await knex.schema.createTable("tag", (table) => {
|
||||
table.increments("id");
|
||||
table.string("name", 255).notNullable();
|
||||
table.string("color", 255).notNullable();
|
||||
table.datetime("created_date").notNullable().defaultTo(knex.fn.now());
|
||||
});
|
||||
|
||||
// monitor_tag
|
||||
await knex.schema.createTable("monitor_tag", (table) => {
|
||||
table.increments("id");
|
||||
table.integer("monitor_id").unsigned().notNullable()
|
||||
.references("id").inTable("monitor")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
table.integer("tag_id").unsigned().notNullable()
|
||||
.references("id").inTable("tag")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
table.text("value");
|
||||
});
|
||||
|
||||
// monitor_tls_info
|
||||
await knex.schema.createTable("monitor_tls_info", (table) => {
|
||||
table.increments("id");
|
||||
table.integer("monitor_id").unsigned().notNullable(); //TODO: no fk ?
|
||||
table.text("info_json");
|
||||
});
|
||||
|
||||
// notification_sent_history
|
||||
await knex.schema.createTable("notification_sent_history", (table) => {
|
||||
table.increments("id");
|
||||
table.string("type", 50).notNullable();
|
||||
table.integer("monitor_id").unsigned().notNullable();
|
||||
table.integer("days").notNullable();
|
||||
table.unique([ "type", "monitor_id", "days" ]);
|
||||
table.index([ "type", "monitor_id", "days" ], "good_index");
|
||||
});
|
||||
|
||||
// setting
|
||||
await knex.schema.createTable("setting", (table) => {
|
||||
table.increments("id");
|
||||
table.string("key", 200).notNullable().unique().collate("utf8_general_ci");
|
||||
table.text("value");
|
||||
table.string("type", 20);
|
||||
});
|
||||
|
||||
// status_page_cname
|
||||
await knex.schema.createTable("status_page_cname", (table) => {
|
||||
table.increments("id");
|
||||
table.integer("status_page_id").unsigned()
|
||||
.references("id").inTable("status_page")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
table.string("domain").notNullable().unique().collate("utf8_general_ci");
|
||||
});
|
||||
|
||||
/*********************
|
||||
* Converted Patch here
|
||||
*********************/
|
||||
|
||||
// 2023-06-30-1348-http-body-encoding.js
|
||||
// ALTER TABLE monitor ADD http_body_encoding VARCHAR(25);
|
||||
// UPDATE monitor SET http_body_encoding = 'json' WHERE (type = 'http' or type = 'keyword') AND http_body_encoding IS NULL;
|
||||
await knex.schema.table("monitor", function (table) {
|
||||
table.string("http_body_encoding", 25);
|
||||
});
|
||||
|
||||
await knex("monitor")
|
||||
.where(function () {
|
||||
this.where("type", "http").orWhere("type", "keyword");
|
||||
})
|
||||
.whereNull("http_body_encoding")
|
||||
.update({
|
||||
http_body_encoding: "json",
|
||||
});
|
||||
|
||||
// 2023-06-30-1354-add-description-monitor.js
|
||||
// ALTER TABLE monitor ADD description TEXT default null;
|
||||
await knex.schema.table("monitor", function (table) {
|
||||
table.text("description").defaultTo(null);
|
||||
});
|
||||
|
||||
// 2023-06-30-1357-api-key-table.js
|
||||
/*
|
||||
CREATE TABLE [api_key] (
|
||||
[id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
[key] VARCHAR(255) NOT NULL,
|
||||
[name] VARCHAR(255) NOT NULL,
|
||||
[user_id] INTEGER NOT NULL,
|
||||
[created_date] DATETIME DEFAULT (DATETIME('now')) NOT NULL,
|
||||
[active] BOOLEAN DEFAULT 1 NOT NULL,
|
||||
[expires] DATETIME DEFAULT NULL,
|
||||
CONSTRAINT FK_user FOREIGN KEY ([user_id]) REFERENCES [user]([id]) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
*/
|
||||
await knex.schema.createTable("api_key", function (table) {
|
||||
table.increments("id").primary();
|
||||
table.string("key", 255).notNullable();
|
||||
table.string("name", 255).notNullable();
|
||||
table.integer("user_id").unsigned().notNullable()
|
||||
.references("id").inTable("user")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
table.dateTime("created_date").defaultTo(knex.fn.now()).notNullable();
|
||||
table.boolean("active").defaultTo(1).notNullable();
|
||||
table.dateTime("expires").defaultTo(null);
|
||||
});
|
||||
|
||||
// 2023-06-30-1400-monitor-tls.js
|
||||
/*
|
||||
ALTER TABLE monitor
|
||||
ADD tls_ca TEXT default null;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD tls_cert TEXT default null;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD tls_key TEXT default null;
|
||||
*/
|
||||
await knex.schema.table("monitor", function (table) {
|
||||
table.text("tls_ca").defaultTo(null);
|
||||
table.text("tls_cert").defaultTo(null);
|
||||
table.text("tls_key").defaultTo(null);
|
||||
});
|
||||
|
||||
// 2023-06-30-1401-maintenance-cron.js
|
||||
/*
|
||||
-- 999 characters. https://stackoverflow.com/questions/46134830/maximum-length-for-cron-job
|
||||
DROP TABLE maintenance_timeslot;
|
||||
ALTER TABLE maintenance ADD cron TEXT;
|
||||
ALTER TABLE maintenance ADD timezone VARCHAR(255);
|
||||
ALTER TABLE maintenance ADD duration INTEGER;
|
||||
*/
|
||||
await knex.schema
|
||||
.dropTableIfExists("maintenance_timeslot")
|
||||
.table("maintenance", function (table) {
|
||||
table.text("cron");
|
||||
table.string("timezone", 255);
|
||||
table.integer("duration");
|
||||
});
|
||||
|
||||
// 2023-06-30-1413-add-parent-monitor.js.
|
||||
/*
|
||||
ALTER TABLE monitor
|
||||
ADD parent INTEGER REFERENCES [monitor] ([id]) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
*/
|
||||
await knex.schema.table("monitor", function (table) {
|
||||
table.integer("parent").unsigned()
|
||||
.references("id").inTable("monitor")
|
||||
.onDelete("SET NULL")
|
||||
.onUpdate("CASCADE");
|
||||
});
|
||||
|
||||
/*
|
||||
patch-add-invert-keyword.sql
|
||||
ALTER TABLE monitor
|
||||
ADD invert_keyword BOOLEAN default 0 not null;
|
||||
*/
|
||||
await knex.schema.table("monitor", function (table) {
|
||||
table.boolean("invert_keyword").defaultTo(0).notNullable();
|
||||
});
|
||||
|
||||
/*
|
||||
patch-added-json-query.sql
|
||||
ALTER TABLE monitor
|
||||
ADD json_path TEXT;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD expected_value VARCHAR(255);
|
||||
*/
|
||||
await knex.schema.table("monitor", function (table) {
|
||||
table.text("json_path");
|
||||
table.string("expected_value", 255);
|
||||
});
|
||||
|
||||
/*
|
||||
patch-added-kafka-producer.sql
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD kafka_producer_topic VARCHAR(255);
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD kafka_producer_brokers TEXT;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD kafka_producer_ssl INTEGER;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD kafka_producer_allow_auto_topic_creation VARCHAR(255);
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD kafka_producer_sasl_options TEXT;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD kafka_producer_message TEXT;
|
||||
*/
|
||||
await knex.schema.table("monitor", function (table) {
|
||||
table.string("kafka_producer_topic", 255);
|
||||
table.text("kafka_producer_brokers");
|
||||
table.integer("kafka_producer_ssl");
|
||||
table.string("kafka_producer_allow_auto_topic_creation", 255);
|
||||
table.text("kafka_producer_sasl_options");
|
||||
table.text("kafka_producer_message");
|
||||
});
|
||||
|
||||
/*
|
||||
patch-add-certificate-expiry-status-page.sql
|
||||
ALTER TABLE status_page
|
||||
ADD show_certificate_expiry BOOLEAN default 0 NOT NULL;
|
||||
*/
|
||||
await knex.schema.table("status_page", function (table) {
|
||||
table.boolean("show_certificate_expiry").defaultTo(0).notNullable();
|
||||
});
|
||||
|
||||
/*
|
||||
patch-monitor-oauth-cc.sql
|
||||
ALTER TABLE monitor
|
||||
ADD oauth_client_id TEXT default null;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD oauth_client_secret TEXT default null;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD oauth_token_url TEXT default null;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD oauth_scopes TEXT default null;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD oauth_auth_method TEXT default null;
|
||||
*/
|
||||
await knex.schema.table("monitor", function (table) {
|
||||
table.text("oauth_client_id").defaultTo(null);
|
||||
table.text("oauth_client_secret").defaultTo(null);
|
||||
table.text("oauth_token_url").defaultTo(null);
|
||||
table.text("oauth_scopes").defaultTo(null);
|
||||
table.text("oauth_auth_method").defaultTo(null);
|
||||
});
|
||||
|
||||
/*
|
||||
patch-add-timeout-monitor.sql
|
||||
ALTER TABLE monitor
|
||||
ADD timeout DOUBLE default 0 not null;
|
||||
*/
|
||||
await knex.schema.table("monitor", function (table) {
|
||||
table.double("timeout").defaultTo(0).notNullable();
|
||||
});
|
||||
|
||||
/*
|
||||
patch-add-gamedig-given-port.sql
|
||||
ALTER TABLE monitor
|
||||
ADD gamedig_given_port_only BOOLEAN default 1 not null;
|
||||
*/
|
||||
await knex.schema.table("monitor", function (table) {
|
||||
table.boolean("gamedig_given_port_only").defaultTo(1).notNullable();
|
||||
});
|
||||
|
||||
log.info("mariadb", "Created basic tables for MariaDB");
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createTables,
|
||||
};
|
41
db/knex_migrations/2023-08-16-0000-create-uptime.js
Normal file
41
db/knex_migrations/2023-08-16-0000-create-uptime.js
Normal file
@ -0,0 +1,41 @@
|
||||
exports.up = function (knex) {
|
||||
return knex.schema
|
||||
.createTable("stat_minutely", function (table) {
|
||||
table.increments("id");
|
||||
table.comment("This table contains the minutely aggregate statistics for each monitor");
|
||||
table.integer("monitor_id").unsigned().notNullable()
|
||||
.references("id").inTable("monitor")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
table.integer("timestamp")
|
||||
.notNullable()
|
||||
.comment("Unix timestamp rounded down to the nearest minute");
|
||||
table.float("ping").notNullable().comment("Average ping in milliseconds");
|
||||
table.smallint("up").notNullable();
|
||||
table.smallint("down").notNullable();
|
||||
|
||||
table.unique([ "monitor_id", "timestamp" ]);
|
||||
})
|
||||
.createTable("stat_daily", function (table) {
|
||||
table.increments("id");
|
||||
table.comment("This table contains the daily aggregate statistics for each monitor");
|
||||
table.integer("monitor_id").unsigned().notNullable()
|
||||
.references("id").inTable("monitor")
|
||||
.onDelete("CASCADE")
|
||||
.onUpdate("CASCADE");
|
||||
table.integer("timestamp")
|
||||
.notNullable()
|
||||
.comment("Unix timestamp rounded down to the nearest day");
|
||||
table.float("ping").notNullable().comment("Average ping in milliseconds");
|
||||
table.smallint("up").notNullable();
|
||||
table.smallint("down").notNullable();
|
||||
|
||||
table.unique([ "monitor_id", "timestamp" ]);
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function (knex) {
|
||||
return knex.schema
|
||||
.dropTable("stat_minutely")
|
||||
.dropTable("stat_daily");
|
||||
};
|
16
db/knex_migrations/2023-08-18-0301-heartbeat.js
Normal file
16
db/knex_migrations/2023-08-18-0301-heartbeat.js
Normal file
@ -0,0 +1,16 @@
|
||||
exports.up = function (knex) {
|
||||
// Add new column heartbeat.end_time
|
||||
return knex.schema
|
||||
.alterTable("heartbeat", function (table) {
|
||||
table.datetime("end_time").nullable().defaultTo(null);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
exports.down = function (knex) {
|
||||
// Rename heartbeat.start_time to heartbeat.time
|
||||
return knex.schema
|
||||
.alterTable("heartbeat", function (table) {
|
||||
table.dropColumn("end_time");
|
||||
});
|
||||
};
|
14
db/knex_migrations/2023-10-11-1915-push-token-to-32.js
Normal file
14
db/knex_migrations/2023-10-11-1915-push-token-to-32.js
Normal file
@ -0,0 +1,14 @@
|
||||
exports.up = function (knex) {
|
||||
// update monitor.push_token to 32 length
|
||||
return knex.schema
|
||||
.alterTable("monitor", function (table) {
|
||||
table.string("push_token", 32).alter();
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function (knex) {
|
||||
return knex.schema
|
||||
.alterTable("monitor", function (table) {
|
||||
table.string("push_token", 20).alter();
|
||||
});
|
||||
};
|
56
db/knex_migrations/README.md
Normal file
56
db/knex_migrations/README.md
Normal file
@ -0,0 +1,56 @@
|
||||
# Info
|
||||
|
||||
https://knexjs.org/guide/migrations.html#knexfile-in-other-languages
|
||||
|
||||
## Basic rules
|
||||
|
||||
- All tables must have a primary key named `id`
|
||||
- Filename format: `YYYY-MM-DD-HHMM-patch-name.js`
|
||||
- Avoid native SQL syntax, use knex methods, because Uptime Kuma supports SQLite and MariaDB.
|
||||
|
||||
## Template
|
||||
|
||||
```js
|
||||
exports.up = function(knex) {
|
||||
|
||||
};
|
||||
|
||||
exports.down = function(knex) {
|
||||
|
||||
};
|
||||
|
||||
// exports.config = { transaction: false };
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
Filename: 2023-06-30-1348-create-user-and-product.js
|
||||
|
||||
```js
|
||||
exports.up = function(knex) {
|
||||
return knex.schema
|
||||
.createTable('user', function (table) {
|
||||
table.increments('id');
|
||||
table.string('first_name', 255).notNullable();
|
||||
table.string('last_name', 255).notNullable();
|
||||
})
|
||||
.createTable('product', function (table) {
|
||||
table.increments('id');
|
||||
table.decimal('price').notNullable();
|
||||
table.string('name', 1000).notNullable();
|
||||
}).then(() => {
|
||||
knex("products").insert([
|
||||
{ price: 10, name: "Apple" },
|
||||
{ price: 20, name: "Orange" },
|
||||
]);
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function(knex) {
|
||||
return knex.schema
|
||||
.dropTable("product")
|
||||
.dropTable("user");
|
||||
};
|
||||
```
|
||||
|
||||
https://knexjs.org/guide/migrations.html#transactions-in-migrations
|
3
db/old_migrations/README.md
Normal file
3
db/old_migrations/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Don't create a new migration file here
|
||||
|
||||
Please go to ./db/knex_migrations/README.md
|
@ -1,5 +1,7 @@
|
||||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
ALTER TABLE monitor_group
|
||||
ADD send_url BOOLEAN DEFAULT 0 NOT NULL;
|
||||
|
||||
COMMIT;
|
@ -1,4 +1,7 @@
|
||||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
BEGIN TRANSACTION;
|
||||
ALTER TABLE status_page ADD google_analytics_tag_id VARCHAR;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD game VARCHAR(255);
|
||||
|
||||
COMMIT;
|
@ -0,0 +1,7 @@
|
||||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
ALTER TABLE status_page
|
||||
ADD google_analytics_tag_id VARCHAR;
|
||||
|
||||
COMMIT;
|
@ -1,6 +1,7 @@
|
||||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD parent INTEGER REFERENCES [monitor] ([id]) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
COMMIT
|
||||
COMMIT;
|
@ -1,3 +1,4 @@
|
||||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
ALTER TABLE monitor
|
||||
@ -15,4 +16,4 @@ ALTER TABLE monitor
|
||||
ALTER TABLE monitor
|
||||
ADD radius_secret VARCHAR(255);
|
||||
|
||||
COMMIT
|
||||
COMMIT;
|
@ -3,4 +3,5 @@ BEGIN TRANSACTION;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD timeout DOUBLE default 0 not null;
|
||||
COMMIT;
|
||||
|
||||
COMMIT;
|
@ -1,5 +1,6 @@
|
||||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
CREATE TABLE [api_key] (
|
||||
[id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
[key] VARCHAR(255) NOT NULL,
|
||||
@ -10,4 +11,5 @@ CREATE TABLE [api_key] (
|
||||
[expires] DATETIME DEFAULT NULL,
|
||||
CONSTRAINT FK_user FOREIGN KEY ([user_id]) REFERENCES [user]([id]) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
COMMIT;
|
@ -1,5 +1,7 @@
|
||||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD packet_size INTEGER DEFAULT 56 NOT NULL;
|
||||
|
||||
COMMIT;
|
@ -18,5 +18,4 @@ drop table setting;
|
||||
|
||||
alter table setting_dg_tmp rename to setting;
|
||||
|
||||
|
||||
COMMIT;
|
11
db/old_migrations/patch-status-page-footer-css.sql
Normal file
11
db/old_migrations/patch-status-page-footer-css.sql
Normal file
@ -0,0 +1,11 @@
|
||||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
ALTER TABLE status_page
|
||||
ADD footer_text TEXT;
|
||||
ALTER TABLE status_page
|
||||
ADD custom_css TEXT;
|
||||
ALTER TABLE status_page
|
||||
ADD show_powered_by BOOLEAN NOT NULL DEFAULT 1;
|
||||
|
||||
COMMIT;
|
@ -1,3 +1,4 @@
|
||||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
CREATE TABLE monitor_tls_info (
|
@ -1,5 +0,0 @@
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD game VARCHAR(255);
|
||||
COMMIT
|
@ -1,6 +0,0 @@
|
||||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
BEGIN TRANSACTION;
|
||||
ALTER TABLE status_page ADD footer_text TEXT;
|
||||
ALTER TABLE status_page ADD custom_css TEXT;
|
||||
ALTER TABLE status_page ADD show_powered_by BOOLEAN NOT NULL DEFAULT 1;
|
||||
COMMIT;
|
@ -1,8 +0,0 @@
|
||||
# DON'T UPDATE TO alpine3.13, 1.14, see #41.
|
||||
FROM node:16-alpine3.12
|
||||
WORKDIR /app
|
||||
|
||||
# Install apprise, iputils for non-root ping, setpriv
|
||||
RUN apk add --no-cache iputils setpriv dumb-init python3 py3-cryptography py3-pip py3-six py3-yaml py3-click py3-markdown py3-requests py3-requests-oauthlib git && \
|
||||
pip3 --no-cache-dir install apprise==1.4.0 && \
|
||||
rm -rf /root/.cache
|
@ -1,12 +1,9 @@
|
||||
# DON'T UPDATE TO bullseye-slim, see #372.
|
||||
# There is no 20-buster-slim for armv7 unfortunately, 18-buster-slim is the last one for Uptime Kuma v1.
|
||||
FROM node:18-buster-slim
|
||||
# If the image changed, the second stage image should be changed too
|
||||
FROM node:20-bookworm-slim AS base2-slim
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Specify --no-install-recommends to skip unused dependencies, make the base much smaller!
|
||||
# python3* = apprise's dependencies
|
||||
# apprise = for notifications (From testing repo)
|
||||
# sqlite3 = for debugging
|
||||
# iputils-ping = for ping
|
||||
# util-linux = for setpriv (Should be dropped in 2.0.0?)
|
||||
@ -15,29 +12,25 @@ WORKDIR /app
|
||||
# ca-certificates = keep the cert up-to-date
|
||||
# sudo = for start service nscd with non-root user
|
||||
# nscd = for better DNS caching
|
||||
# (pip) apprise = for notifications
|
||||
RUN apt-get update && \
|
||||
apt-get --yes --no-install-recommends install \
|
||||
python3 python3-pip python3-cryptography python3-six python3-yaml python3-click python3-markdown python3-requests python3-requests-oauthlib \
|
||||
sqlite3 \
|
||||
RUN echo "deb http://deb.debian.org/debian testing main" >> /etc/apt/sources.list && \
|
||||
apt update && \
|
||||
apt --yes --no-install-recommends -t testing install apprise sqlite3 ca-certificates && \
|
||||
apt --yes --no-install-recommends -t stable install \
|
||||
iputils-ping \
|
||||
util-linux \
|
||||
dumb-init \
|
||||
curl \
|
||||
ca-certificates \
|
||||
sudo \
|
||||
nscd && \
|
||||
pip3 --no-cache-dir install apprise==1.4.5 && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
apt --yes autoremove
|
||||
|
||||
|
||||
# Install cloudflared
|
||||
RUN set -eux && \
|
||||
mkdir -p --mode=0755 /usr/share/keyrings && \
|
||||
curl --fail --show-error --silent --location --insecure https://pkg.cloudflare.com/cloudflare-main.gpg --output /usr/share/keyrings/cloudflare-main.gpg && \
|
||||
echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared buster main' | tee /etc/apt/sources.list.d/cloudflared.list && \
|
||||
apt-get update && \
|
||||
apt-get install --yes --no-install-recommends cloudflared && \
|
||||
RUN curl https://pkg.cloudflare.com/cloudflare-main.gpg --output /usr/share/keyrings/cloudflare-main.gpg && \
|
||||
echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared bullseye main' | tee /etc/apt/sources.list.d/cloudflared.list && \
|
||||
apt update && \
|
||||
apt install --yes --no-install-recommends -t stable cloudflared && \
|
||||
cloudflared version && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
apt --yes autoremove
|
||||
@ -46,3 +39,13 @@ RUN set -eux && \
|
||||
COPY ./docker/etc/nscd.conf /etc/nscd.conf
|
||||
COPY ./docker/etc/sudoers /etc/sudoers
|
||||
|
||||
|
||||
# Full Base Image
|
||||
# MariaDB, Chromium and fonts
|
||||
FROM base2-slim AS base2
|
||||
ENV UPTIME_KUMA_ENABLE_EMBEDDED_MARIADB=1
|
||||
RUN apt update && \
|
||||
apt --yes --no-install-recommends install chromium fonts-indic fonts-noto fonts-noto-cjk mariadb-server && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
apt --yes autoremove && \
|
||||
chown -R node:node /var/lib/mysql
|
||||
|
14
docker/docker-compose-dev.yml
Normal file
14
docker/docker-compose-dev.yml
Normal file
@ -0,0 +1,14 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
uptime-kuma:
|
||||
container_name: uptime-kuma-dev
|
||||
image: louislam/uptime-kuma:nightly2
|
||||
volumes:
|
||||
#- ./data:/app/data
|
||||
- ../server:/app/server
|
||||
- ../db:/app/db
|
||||
ports:
|
||||
- "3001:3001" # <Host Port>:<Container Port>
|
||||
- "3307:3306"
|
||||
|
@ -1,14 +1,15 @@
|
||||
# Simple docker-compose.yml
|
||||
# You can change your port or volume location
|
||||
|
||||
version: '3.3'
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
uptime-kuma:
|
||||
image: louislam/uptime-kuma:1
|
||||
container_name: uptime-kuma
|
||||
volumes:
|
||||
- ./uptime-kuma-data:/app/data
|
||||
- uptime-kuma:/app/data
|
||||
ports:
|
||||
- 3001:3001 # <Host Port>:<Container Port>
|
||||
- "3001:3001" # <Host Port>:<Container Port>
|
||||
restart: always
|
||||
|
||||
volumes:
|
||||
uptime-kuma:
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
ARG BASE_IMAGE=louislam/uptime-kuma:base2
|
||||
|
||||
############################################
|
||||
# Build in Golang
|
||||
# Run npm run build-healthcheck-armv7 in the host first, another it will be super slow where it is building the armv7 healthcheck
|
||||
# Run npm run build-healthcheck-armv7 in the host first, otherwise it will be super slow where it is building the armv7 healthcheck
|
||||
# Check file: builder-go.dockerfile
|
||||
############################################
|
||||
FROM louislam/uptime-kuma:builder-go AS build_healthcheck
|
||||
@ -8,49 +10,50 @@ FROM louislam/uptime-kuma:builder-go AS build_healthcheck
|
||||
############################################
|
||||
# Build in Node.js
|
||||
############################################
|
||||
FROM louislam/uptime-kuma:base-debian AS build
|
||||
FROM louislam/uptime-kuma:base2 AS build
|
||||
USER node
|
||||
WORKDIR /app
|
||||
|
||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
|
||||
COPY .npmrc .npmrc
|
||||
COPY package.json package.json
|
||||
COPY package-lock.json package-lock.json
|
||||
COPY --chown=node:node .npmrc .npmrc
|
||||
COPY --chown=node:node package.json package.json
|
||||
COPY --chown=node:node package-lock.json package-lock.json
|
||||
RUN npm ci --omit=dev
|
||||
COPY . .
|
||||
COPY --from=build_healthcheck /app/extra/healthcheck /app/extra/healthcheck
|
||||
RUN chmod +x /app/extra/entrypoint.sh
|
||||
COPY --chown=node:node --from=build_healthcheck /app/extra/healthcheck /app/extra/healthcheck
|
||||
RUN mkdir ./data
|
||||
|
||||
############################################
|
||||
# ⭐ Main Image
|
||||
############################################
|
||||
FROM louislam/uptime-kuma:base-debian AS release
|
||||
FROM $BASE_IMAGE AS release
|
||||
USER node
|
||||
WORKDIR /app
|
||||
|
||||
LABEL org.opencontainers.image.source="https://github.com/louislam/uptime-kuma"
|
||||
|
||||
ENV UPTIME_KUMA_IS_CONTAINER=1
|
||||
|
||||
# Copy app files from build layer
|
||||
COPY --from=build /app /app
|
||||
|
||||
COPY --chown=node:node --from=build /app /app
|
||||
|
||||
EXPOSE 3001
|
||||
VOLUME ["/app/data"]
|
||||
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD extra/healthcheck
|
||||
ENTRYPOINT ["/usr/bin/dumb-init", "--", "extra/entrypoint.sh"]
|
||||
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
||||
CMD ["node", "server/server.js"]
|
||||
|
||||
############################################
|
||||
# Mark as Nightly
|
||||
############################################
|
||||
FROM release AS nightly
|
||||
USER node
|
||||
RUN npm run mark-as-nightly
|
||||
|
||||
############################################
|
||||
# Build an image for testing pr
|
||||
############################################
|
||||
FROM louislam/uptime-kuma:base-debian AS pr-test
|
||||
|
||||
FROM louislam/uptime-kuma:base2 AS pr-test2
|
||||
WORKDIR /app
|
||||
|
||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
|
||||
|
||||
## Install Git
|
||||
@ -78,7 +81,7 @@ CMD ["npm", "run", "start-pr-test"]
|
||||
############################################
|
||||
# Upload the artifact to Github
|
||||
############################################
|
||||
FROM louislam/uptime-kuma:base-debian AS upload-artifact
|
||||
FROM louislam/uptime-kuma:base2 AS upload-artifact
|
||||
WORKDIR /
|
||||
RUN apt update && \
|
||||
apt --yes install curl file
|
||||
|
@ -1,27 +0,0 @@
|
||||
FROM louislam/uptime-kuma:base-alpine AS build
|
||||
WORKDIR /app
|
||||
|
||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
|
||||
|
||||
COPY .npmrc .npmrc
|
||||
COPY package.json package.json
|
||||
COPY package-lock.json package-lock.json
|
||||
RUN npm ci --omit=dev
|
||||
COPY . .
|
||||
RUN chmod +x /app/extra/entrypoint.sh
|
||||
|
||||
FROM louislam/uptime-kuma:base-alpine AS release
|
||||
WORKDIR /app
|
||||
|
||||
# Copy app files from build layer
|
||||
COPY --from=build /app /app
|
||||
|
||||
EXPOSE 3001
|
||||
VOLUME ["/app/data"]
|
||||
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD node extra/healthcheck.js
|
||||
ENTRYPOINT ["/usr/bin/dumb-init", "--", "extra/entrypoint.sh"]
|
||||
CMD ["node", "server/server.js"]
|
||||
|
||||
|
||||
FROM release AS nightly
|
||||
RUN npm run mark-as-nightly
|
@ -36,6 +36,8 @@ if (! exists) {
|
||||
/**
|
||||
* Commit updated files
|
||||
* @param {string} version Version to update to
|
||||
* @returns {void}
|
||||
* @throws Error committing files
|
||||
*/
|
||||
function commit(version) {
|
||||
let msg = "Update to " + version;
|
||||
@ -55,6 +57,7 @@ function commit(version) {
|
||||
/**
|
||||
* Create a tag with the specified version
|
||||
* @param {string} version Tag to create
|
||||
* @returns {void}
|
||||
*/
|
||||
function tag(version) {
|
||||
let res = childProcess.spawnSync("git", [ "tag", version ]);
|
||||
@ -68,6 +71,7 @@ function tag(version) {
|
||||
* Check if a tag exists for the specified version
|
||||
* @param {string} version Version to check
|
||||
* @returns {boolean} Does the tag already exist
|
||||
* @throws Version is not valid
|
||||
*/
|
||||
function tagExists(version) {
|
||||
if (! version) {
|
||||
|
@ -15,6 +15,7 @@ download(url);
|
||||
/**
|
||||
* Downloads the latest version of the dist from a GitHub release.
|
||||
* @param {string} url The URL to download from.
|
||||
* @returns {void}
|
||||
*
|
||||
* Generated by Trelent
|
||||
*/
|
||||
|
@ -1,21 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# set -e Exit the script if an error happens
|
||||
set -e
|
||||
PUID=${PUID=0}
|
||||
PGID=${PGID=0}
|
||||
|
||||
files_ownership () {
|
||||
# -h Changes the ownership of an encountered symbolic link and not that of the file or directory pointed to by the symbolic link.
|
||||
# -R Recursively descends the specified directories
|
||||
# -c Like verbose but report only when a change is made
|
||||
chown -hRc "$PUID":"$PGID" /app/data
|
||||
}
|
||||
|
||||
echo "==> Performing startup jobs and maintenance tasks"
|
||||
files_ownership
|
||||
|
||||
echo "==> Starting application with user $PUID group $PGID"
|
||||
|
||||
# --clear-groups Clear supplementary groups.
|
||||
exec setpriv --reuid "$PUID" --regid "$PGID" --clear-groups "$@"
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
@ -28,9 +28,15 @@ namespace UptimeKuma {
|
||||
Environment.CurrentDirectory = cwd;
|
||||
}
|
||||
|
||||
bool isIntranet = args.Contains("--intranet");
|
||||
|
||||
if (isIntranet) {
|
||||
Console.WriteLine("The --intranet argument was provided, so we will not try to access the internet. The first time this application runs you'll need to run it without the --intranet param or copy the result from another machine to the intranet server.");
|
||||
}
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new UptimeKumaApplicationContext());
|
||||
Application.Run(new UptimeKumaApplicationContext(isIntranet));
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,8 +55,9 @@ namespace UptimeKuma {
|
||||
|
||||
private RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
|
||||
|
||||
private readonly bool intranetOnly;
|
||||
|
||||
public UptimeKumaApplicationContext() {
|
||||
public UptimeKumaApplicationContext(bool intranetOnly) {
|
||||
|
||||
// Single instance only
|
||||
bool createdNew;
|
||||
@ -59,6 +66,8 @@ namespace UptimeKuma {
|
||||
return;
|
||||
}
|
||||
|
||||
this.intranetOnly = intranetOnly;
|
||||
|
||||
var startingText = "Starting server...";
|
||||
trayIcon = new NotifyIcon();
|
||||
trayIcon.Text = startingText;
|
||||
@ -98,6 +107,10 @@ namespace UptimeKuma {
|
||||
}
|
||||
|
||||
void DownloadFiles() {
|
||||
if (intranetOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
var form = new DownloadForm();
|
||||
form.Closed += Exit;
|
||||
form.Show();
|
||||
@ -173,7 +186,9 @@ namespace UptimeKuma {
|
||||
}
|
||||
|
||||
void CheckForUpdate(object sender, EventArgs e) {
|
||||
var needUpdate = false;
|
||||
if (intranetOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check version.json exists
|
||||
if (File.Exists("version.json")) {
|
||||
@ -204,8 +219,12 @@ namespace UptimeKuma {
|
||||
|
||||
}
|
||||
|
||||
void VisitGitHub(object sender, EventArgs e)
|
||||
{
|
||||
void VisitGitHub(object sender, EventArgs e) {
|
||||
if (intranetOnly) {
|
||||
MessageBox.Show("You have parsed in --intranet so we will not try to access the internet or visit github.com, please go to https://github.com/louislam/uptime-kuma if you want to visit github.");
|
||||
return;
|
||||
}
|
||||
|
||||
Process.Start("https://github.com/louislam/uptime-kuma");
|
||||
}
|
||||
|
||||
|
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.1.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.1.0")]
|
||||
[assembly: AssemblyVersion("1.0.2.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.2.0")]
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="packages\Costura.Fody.5.7.0\build\Costura.Fody.props" Condition="Exists('packages\Costura.Fody.5.7.0\build\Costura.Fody.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
@ -39,107 +38,104 @@
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>COPY "$(SolutionDir)bin\Debug\uptime-kuma.exe" "%UserProfile%\Desktop\uptime-kuma-win64\"</PostBuildEvent>
|
||||
<PostBuildEvent>COPY "$(SolutionDir)bin\Debug\uptime-kuma.exe" "%UserProfile%\Desktop\uptime-kuma-win64\"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Costura, Version=5.7.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Costura.Fody.5.7.0\lib\netstandard1.0\Costura.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
|
||||
<HintPath>packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<HintPath>packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.AppContext, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll</HintPath>
|
||||
<HintPath>packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
<HintPath>packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Console, Version=4.0.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Console.4.3.1\lib\net46\System.Console.dll</HintPath>
|
||||
<HintPath>packages\System.Console.4.3.1\lib\net46\System.Console.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Diagnostics.DiagnosticSource, Version=7.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Diagnostics.DiagnosticSource.7.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||
<HintPath>packages\System.Diagnostics.DiagnosticSource.7.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Diagnostics.Tracing, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll</HintPath>
|
||||
<HintPath>packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Globalization.Calendars, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
|
||||
<HintPath>packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.IO.4.3.0\lib\net462\System.IO.dll</HintPath>
|
||||
<HintPath>packages\System.IO.4.3.0\lib\net462\System.IO.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
|
||||
<HintPath>packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.Compression.FileSystem" />
|
||||
<Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
|
||||
<HintPath>packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
|
||||
<HintPath>packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
|
||||
<HintPath>packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Linq.4.3.0\lib\net463\System.Linq.dll</HintPath>
|
||||
<HintPath>packages\System.Linq.4.3.0\lib\net463\System.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Linq.Expressions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll</HintPath>
|
||||
<HintPath>packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
|
||||
<HintPath>packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http, Version=4.1.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll</HintPath>
|
||||
<HintPath>packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
|
||||
<HintPath>packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
<HintPath>packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll</HintPath>
|
||||
<HintPath>packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime, Version=4.1.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll</HintPath>
|
||||
<HintPath>packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
<HintPath>packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Extensions, Version=4.1.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll</HintPath>
|
||||
<HintPath>packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll</HintPath>
|
||||
<HintPath>packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||
<HintPath>packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net463\System.Security.Cryptography.Algorithms.dll</HintPath>
|
||||
<HintPath>packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net463\System.Security.Cryptography.Algorithms.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
|
||||
<HintPath>packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
|
||||
<HintPath>packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||
<HintPath>packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.RegularExpressions, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Text.RegularExpressions.4.3.1\lib\net463\System.Text.RegularExpressions.dll</HintPath>
|
||||
<HintPath>packages\System.Text.RegularExpressions.4.3.1\lib\net463\System.Text.RegularExpressions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
@ -150,21 +146,21 @@
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Xml.ReaderWriter.4.3.1\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
|
||||
<HintPath>packages\System.Xml.ReaderWriter.4.3.1\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DownloadForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DownloadForm.Designer.cs">
|
||||
<DependentUpon>DownloadForm.cs</DependentUpon>
|
||||
<DependentUpon>DownloadForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Version.cs" />
|
||||
<EmbeddedResource Include="DownloadForm.resx">
|
||||
<DependentUpon>DownloadForm.cs</DependentUpon>
|
||||
<DependentUpon>DownloadForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
@ -176,7 +172,7 @@
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="..\..\public\favicon.ico">
|
||||
<Link>favicon.ico</Link>
|
||||
<Link>favicon.ico</Link>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
@ -193,20 +189,15 @@
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include=".gitignore" />
|
||||
<Content Include="app.manifest" />
|
||||
<Content Include=".gitignore" />
|
||||
<Content Include="app.manifest" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('packages\Costura.Fody.5.7.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.5.7.0\build\Costura.Fody.props'))" />
|
||||
<Error Condition="!Exists('packages\Costura.Fody.5.7.0\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.5.7.0\build\Costura.Fody.targets'))" />
|
||||
<Error Condition="!Exists('packages\Fody.6.6.4\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Fody.6.6.4\build\Fody.targets'))" />
|
||||
<Error Condition="!Exists('packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets'))" />
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets'))" />
|
||||
</Target>
|
||||
<Import Project="packages\Costura.Fody.5.7.0\build\Costura.Fody.targets" Condition="Exists('packages\Costura.Fody.5.7.0\build\Costura.Fody.targets')" />
|
||||
<Import Project="packages\Fody.6.6.4\build\Fody.targets" Condition="Exists('packages\Fody.6.6.4\build\Fody.targets')" />
|
||||
<Import Project="packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets')" />
|
||||
</Project>
|
@ -1,7 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Costura.Fody" version="5.7.0" targetFramework="net472" developmentDependency="true" />
|
||||
<package id="Fody" version="6.6.4" targetFramework="net472" developmentDependency="true" />
|
||||
<package id="Microsoft.NETCore.Platforms" version="7.0.0" targetFramework="net472" />
|
||||
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net472" />
|
||||
<package id="NETStandard.Library" version="2.0.3" targetFramework="net472" />
|
||||
@ -53,4 +51,4 @@
|
||||
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net472" />
|
||||
<package id="System.Threading.Timer" version="4.3.0" targetFramework="net472" />
|
||||
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net472" />
|
||||
</packages>
|
||||
</packages>
|
||||
|
@ -4,12 +4,12 @@ const fs = require("fs");
|
||||
* to avoid the runtime deprecation warning triggered for using `fs.rmdirSync` with `{ recursive: true }` in Node.js v16,
|
||||
* or the `recursive` property removing completely in the future Node.js version.
|
||||
* See the link below.
|
||||
*
|
||||
* @todo Once we drop the support for Node.js v14 (or at least versions before v14.14.0), we can safely replace this function with `fs.rmSync`, since `fs.rmSync` was add in Node.js v14.14.0 and currently we supports all the Node.js v14 versions that include the versions before the v14.14.0, and this function have almost the same signature with `fs.rmSync`.
|
||||
* @link https://nodejs.org/docs/latest-v16.x/api/deprecations.html#dep0147-fsrmdirpath--recursive-true- the deprecation infomation of `fs.rmdirSync`
|
||||
* @link https://nodejs.org/docs/latest-v16.x/api/fs.html#fsrmsyncpath-options the document of `fs.rmSync`
|
||||
* @param {fs.PathLike} path Valid types for path values in "fs".
|
||||
* @param {fs.RmDirOptions} [options] options for `fs.rmdirSync`, if `fs.rmSync` is available and property `recursive` is true, it will automatically have property `force` with value `true`.
|
||||
* @param {fs.RmDirOptions} options options for `fs.rmdirSync`, if `fs.rmSync` is available and property `recursive` is true, it will automatically have property `force` with value `true`.
|
||||
* @returns {void}
|
||||
*/
|
||||
const rmSync = (path, options) => {
|
||||
if (typeof fs.rmSync === "function") {
|
||||
|
3
extra/push-examples/.gitignore
vendored
Normal file
3
extra/push-examples/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
java/Index.class
|
||||
csharp/index.exe
|
||||
typescript-fetch/index.js
|
10
extra/push-examples/bash-curl/index.sh
Normal file
10
extra/push-examples/bash-curl/index.sh
Normal file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
# Filename: index.sh
|
||||
PUSH_URL="https://example.com/api/push/key?status=up&msg=OK&ping="
|
||||
INTERVAL=60
|
||||
|
||||
while true; do
|
||||
curl -s -o /dev/null $PUSH_URL
|
||||
echo "Pushed!"
|
||||
sleep $INTERVAL
|
||||
done
|
24
extra/push-examples/csharp/index.cs
Normal file
24
extra/push-examples/csharp/index.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
|
||||
/**
|
||||
* Compile: C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe index.cs
|
||||
* Run: index.exe
|
||||
*/
|
||||
class Index
|
||||
{
|
||||
const string PushURL = "https://example.com/api/push/key?status=up&msg=OK&ping=";
|
||||
const int Interval = 60;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
WebClient client = new WebClient();
|
||||
client.DownloadString(PushURL);
|
||||
Console.WriteLine("Pushed!");
|
||||
Thread.Sleep(Interval * 1000);
|
||||
}
|
||||
}
|
||||
}
|
1
extra/push-examples/docker/index.sh
Normal file
1
extra/push-examples/docker/index.sh
Normal file
@ -0,0 +1 @@
|
||||
docker run -d --restart=always --name uptime-kuma-push louislam/uptime-kuma:push "https://example.com/api/push/key?status=up&msg=OK&ping=" 60
|
20
extra/push-examples/go/index.go
Normal file
20
extra/push-examples/go/index.go
Normal file
@ -0,0 +1,20 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
const PushURL = "https://example.com/api/push/key?status=up&msg=OK&ping="
|
||||
const Interval = 60
|
||||
|
||||
for {
|
||||
_, err := http.Get(PushURL)
|
||||
if err == nil {
|
||||
fmt.Println("Pushed!")
|
||||
}
|
||||
time.Sleep(Interval * time.Second)
|
||||
}
|
||||
}
|
32
extra/push-examples/java/index.java
Normal file
32
extra/push-examples/java/index.java
Normal file
@ -0,0 +1,32 @@
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Compile: javac index.java
|
||||
* Run: java Index
|
||||
*/
|
||||
class Index {
|
||||
|
||||
public static final String PUSH_URL = "https://example.com/api/push/key?status=up&msg=OK&ping=";
|
||||
public static final int INTERVAL = 60;
|
||||
|
||||
public static void main(String[] args) {
|
||||
while (true) {
|
||||
try {
|
||||
URL url = new URL(PUSH_URL);
|
||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||
con.setRequestMethod("GET");
|
||||
con.getResponseCode();
|
||||
con.disconnect();
|
||||
System.out.println("Pushed!");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(INTERVAL * 1000);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
extra/push-examples/javascript-fetch/index.js
Normal file
11
extra/push-examples/javascript-fetch/index.js
Normal file
@ -0,0 +1,11 @@
|
||||
// Supports: Node.js >= 18, Deno, Bun
|
||||
const pushURL = "https://example.com/api/push/key?status=up&msg=OK&ping=";
|
||||
const interval = 60;
|
||||
|
||||
const push = async () => {
|
||||
await fetch(pushURL);
|
||||
console.log("Pushed!");
|
||||
};
|
||||
|
||||
push();
|
||||
setInterval(push, interval * 1000);
|
5
extra/push-examples/javascript-fetch/package.json
Normal file
5
extra/push-examples/javascript-fetch/package.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
}
|
||||
}
|
13
extra/push-examples/php/index.php
Normal file
13
extra/push-examples/php/index.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
const PUSH_URL = "https://example.com/api/push/key?status=up&msg=OK&ping=";
|
||||
const interval = 60;
|
||||
|
||||
while (true) {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, PUSH_URL);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
echo "Pushed!\n";
|
||||
sleep(interval);
|
||||
}
|
9
extra/push-examples/powershell/index.ps1
Normal file
9
extra/push-examples/powershell/index.ps1
Normal file
@ -0,0 +1,9 @@
|
||||
# Filename: index.ps1
|
||||
$pushURL = "https://example.com/api/push/key?status=up&msg=OK&ping="
|
||||
$interval = 60
|
||||
|
||||
while ($true) {
|
||||
$res = Invoke-WebRequest -Uri $pushURL
|
||||
Write-Host "Pushed!"
|
||||
Start-Sleep -Seconds $interval
|
||||
}
|
10
extra/push-examples/python/index.py
Normal file
10
extra/push-examples/python/index.py
Normal file
@ -0,0 +1,10 @@
|
||||
import urllib.request
|
||||
import time
|
||||
|
||||
push_url = "https://example.com/api/push/key?status=up&msg=OK&ping="
|
||||
interval = 60
|
||||
|
||||
while True:
|
||||
urllib.request.urlopen(push_url)
|
||||
print("Pushed!\n")
|
||||
time.sleep(interval)
|
19
extra/push-examples/typescript-fetch/README.md
Normal file
19
extra/push-examples/typescript-fetch/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# How to run
|
||||
|
||||
Node.js (ts-node)
|
||||
|
||||
```bash
|
||||
ts-node index.ts
|
||||
```
|
||||
|
||||
Deno
|
||||
|
||||
```bash
|
||||
deno run --allow-net index.ts
|
||||
```
|
||||
|
||||
Bun.js
|
||||
|
||||
```bash
|
||||
bun index.ts
|
||||
```
|
11
extra/push-examples/typescript-fetch/index.ts
Normal file
11
extra/push-examples/typescript-fetch/index.ts
Normal file
@ -0,0 +1,11 @@
|
||||
// Supports: Deno, Bun, Node.js >= 18 (ts-node)
|
||||
const pushURL : string = "https://example.com/api/push/key?status=up&msg=OK&ping=";
|
||||
const interval : number = 60;
|
||||
|
||||
const push = async () => {
|
||||
await fetch(pushURL);
|
||||
console.log("Pushed!");
|
||||
};
|
||||
|
||||
push();
|
||||
setInterval(push, interval * 1000);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user