Skip to content

Commit

Permalink
Init (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
louislam authored Nov 11, 2023
1 parent 205bff2 commit 6749e34
Show file tree
Hide file tree
Showing 88 changed files with 14,443 additions and 0 deletions.
17 changes: 17 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Should be identical to .gitignore
.env
node_modules
.idea
data
stacks
tmp
/private

# Docker extra
docker
frontend
.editorconfig
.eslintrc.cjs
.git
.gitignore
README.md
24 changes: 24 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false

[*.yaml]
indent_size = 2

[*.yml]
indent_size = 2

[*.vue]
trim_trailing_whitespace = false

[*.go]
indent_style = tab
97 changes: 97 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
module.exports = {
root: true,
env: {
browser: true,
node: true,
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:vue/vue3-recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
"parser": "@typescript-eslint/parser",
},
plugins: [
"@typescript-eslint",
"jsdoc"
],
rules: {
"yoda": "error",
"linebreak-style": [ "error", "unix" ],
"camelcase": [ "warn", {
"properties": "never",
"ignoreImports": true
}],
"no-unused-vars": [ "warn", {
"args": "none"
}],
indent: [
"error",
4,
{
ignoredNodes: [ "TemplateLiteral" ],
SwitchCase: 1,
},
],
quotes: [ "error", "double" ],
semi: "error",
"vue/html-indent": [ "error", 4 ], // default: 2
"vue/max-attributes-per-line": "off",
"vue/singleline-html-element-content-newline": "off",
"vue/html-self-closing": "off",
"vue/require-component-is": "off", // not allow is="style" https://github.com/vuejs/eslint-plugin-vue/issues/462#issuecomment-430234675
"vue/attribute-hyphenation": "off", // This change noNL to "no-n-l" unexpectedly
"vue/multi-word-component-names": "off",
"no-multi-spaces": [ "error", {
ignoreEOLComments: true,
}],
"array-bracket-spacing": [ "warn", "always", {
"singleValue": true,
"objectsInArrays": false,
"arraysInArrays": false
}],
"space-before-function-paren": [ "error", {
"anonymous": "always",
"named": "never",
"asyncArrow": "always"
}],
"curly": "error",
"object-curly-spacing": [ "error", "always" ],
"object-curly-newline": "off",
"object-property-newline": "error",
"comma-spacing": "error",
"brace-style": "error",
"no-var": "error",
"key-spacing": "warn",
"keyword-spacing": "warn",
"space-infix-ops": "error",
"arrow-spacing": "warn",
"no-trailing-spaces": "error",
"no-constant-condition": [ "error", {
"checkLoops": false,
}],
"space-before-blocks": "warn",
"no-extra-boolean-cast": "off",
"no-multiple-empty-lines": [ "warn", {
"max": 1,
"maxBOF": 0,
}],
"lines-between-class-members": [ "warn", "always", {
exceptAfterSingleLine: true,
}],
"no-unneeded-ternary": "error",
"array-bracket-newline": [ "error", "consistent" ],
"eol-last": [ "error", "always" ],
"comma-dangle": [ "warn", "only-multiline" ],
"no-empty": [ "error", {
"allowEmptyCatch": true
}],
"no-control-regex": "off",
"one-var": [ "error", "never" ],
"max-statements-per-line": [ "error", { "max": 1 }],
"@typescript-eslint/ban-ts-comment": "off",
"prefer-const" : "off",
},
};
12 changes: 12 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# These are supported funding model platforms

github: louislam # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
#patreon: # Replace with a single Patreon username
open_collective: uptime-kuma # Replace with a single Open Collective username
#ko_fi: # Replace with a single Ko-fi username
#tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
#community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
#liberapay: # Replace with a single Liberapay username
#issuehunt: # Replace with a single IssueHunt username
#otechie: # Replace with a single Otechie username
#custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Should update .dockerignore as well
.env
node_modules
.idea
data
stacks
tmp
/private

# Git only
frontend-dist

21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 Louis Lam

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
130 changes: 130 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,131 @@
<div align="center" width="100%">
<img src="./frontend/public/icon.svg" width="128" alt="" />
</div>

# Dockge

A fancy, easy-to-use and reactive docker `compose.yaml` stack-oriented manager.

<img src="https://github.com/louislam/dockge/assets/1336778/26a583e1-ecb1-4a8d-aedf-76157d714ad7" width="900" alt="" />

## ⭐ Features

- Manage `compose.yaml`
- Interactive Editor for `compose.yaml`
- Interactive Web Terminal
- Reactive
- Everything is just responsive. Progress (Pull/Up/Down) and terminal output are in real-time
- Easy-to-use & fancy UI
- If you love Uptime Kuma's UI/UX, you will love this too
- Convert `docker run ...` commands into `compose.yaml`

## 🔧 How to Install

Requirements:
- [Docker CE](https://docs.docker.com/engine/install/) 20+ is recommended
- [Docker Compose V2](https://docs.docker.com/compose/install/linux/)
- OS:
- As long as you can run Docker CE, it should be fine, but:
- Debian/Raspbian Buster or lower is not supported, please upgrade to Bullseye
- Arch: armv7, arm64, amd64 (a.k.a x86_64)

### Basic

Default stacks directory is `/opt/stacks`.

```
# Create a directory that stores your stacks and stores dockge's compose.yaml
mkdir -p /opt/stacks /opt/dockge
cd /opt/dockge
# Download the compose.yaml
curl https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml --output compose.yaml
# Start Server
docker compose up -d
# If you are using docker-compose V1
# docker-compose up -d
```

### Advanced

If you want to store your stacks in another directory, you can change the `DOCKGE_STACKS_DIR` environment variable and volumes.

For exmaples, if you want to store your stacks in `/my-stacks`:

```yaml
version: "3.8"
services:
dockge:
image: louislam/dockge:1
restart: unless-stopped
ports:
- 5001:5001
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/app/data

# Your stacks directory in the host
# (The paths inside container must be the same as the host)
- /my-stacks:/my-stacks
environment:
# Tell Dockge where is your stacks directory
- DOCKGE_STACKS_DIR=/my-stacks
```
## How to Update
```bash
cd /opt/stacks
docker compose pull
docker compose up -d
```

## Motivations

- I have been using Portainer for some time, but for the stack management, I am sometimes not satisfied with it. For example, sometimes when I try to deploy a stack, the loading icon keeps spinning for a few minutes without progress. And sometimes error messages are not clear.
- Try to develop with ES Module + TypeScript (Originally, I planned to use Deno or Bun.js, but they do not support for arm64, so I stepped back to Node.js)

If you love this project, please consider giving this project a ⭐.


## FAQ

#### "Dockge"?

"Dockge" is a coinage word which is created by myself. I hope it sounds like `Badge` but replacing with `Dock` - `Dock-ge`.

The naming idea was coming from Twitch emotes like `sadge`, `bedge` or `wokege`. They are all ending with `-ge`.

If you are not comfortable with the pronunciation, you can call it `Dockage`

#### Can I manage a single container without `compose.yaml`?

The main objective of Dockge is that try to use docker `compose.yaml` for everything. If you want to manage a single container, you can just use Portainer or Docker CLI.

#### Can I manage existing stacks?

Yes, you can. However, you need to move your compose file into the stacks directory:

1. Stop your stack
2. Move your compose file into `/opt/stacks/<stackName>/compose.yaml`
3. In Dockge, click the " Scan Stacks Folder" button in the top-right corner's dropdown menu
4. Now you should see your stack in the list

## More Ideas?

- Stats
- File manager
- App store for yaml templates
- Get app icons
- Switch Docker context
- Support Dockerfile and build
- Support Docker swarm


# Others

Dockge is built on top of [Compose V2](https://docs.docker.com/compose/migrate/). `compose.yaml` is also known as `docker-compose.yml`.


71 changes: 71 additions & 0 deletions backend/check-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { log } from "./log";
import compareVersions from "compare-versions";
import packageJSON from "../package.json";
import { Settings } from "./settings";

export const obj = {
version: packageJSON.version,
latestVersion: null,
};
export default obj;

// How much time in ms to wait between update checks
const UPDATE_CHECKER_INTERVAL_MS = 1000 * 60 * 60 * 48;
const CHECK_URL = "https://dockge.kuma.pet/version";

let interval : NodeJS.Timeout;

export function startInterval() {
const check = async () => {
if (await Settings.get("checkUpdate") === false) {
return;
}

log.debug("update-checker", "Retrieving latest versions");

try {
const res = await fetch(CHECK_URL);
const data = await res.json();

// For debug
if (process.env.TEST_CHECK_VERSION === "1") {
data.slow = "1000.0.0";
}

const checkBeta = await Settings.get("checkBeta");

if (checkBeta && data.beta) {
if (compareVersions.compare(data.beta, data.slow, ">")) {
obj.latestVersion = data.beta;
return;
}
}

if (data.slow) {
obj.latestVersion = data.slow;
}

} catch (_) {
log.info("update-checker", "Failed to check for new versions");
}

};

check();
interval = setInterval(check, UPDATE_CHECKER_INTERVAL_MS);
}

/**
* Enable the check update feature
* @param value Should the check update feature be enabled?
* @returns
*/
export async function enableCheckUpdate(value : boolean) {
await Settings.set("checkUpdate", value);

clearInterval(interval);

if (value) {
startInterval();
}
}
Loading

0 comments on commit 6749e34

Please sign in to comment.