mirror of
https://github.com/louislam/dockge.git
synced 2025-08-13 19:27:20 +02:00
Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
d8d25563ba | |||
83d58cd363 | |||
caa82bbad5 | |||
2530cac989 | |||
06307956ca | |||
9b9234434e | |||
a12c6dc033 | |||
eb6db8b31e | |||
015e4c21f9 | |||
7a63d59ef8 | |||
ecbbdae7ab | |||
e7abbcbefa | |||
59adcc148c | |||
5e9065a4d6 | |||
35a79ea8a6 | |||
0c9fc4ead2 | |||
1c5ff7914b | |||
f7c66a476c | |||
5daa6fd788 | |||
c2ec9ac7f4 | |||
21e736459e | |||
d7f4873405 | |||
2ed739b1b9 | |||
314630724b | |||
e67d08b7b3 | |||
7d1da2ad99 | |||
5f70fa6baf |
43
README.md
43
README.md
@ -4,17 +4,13 @@
|
|||||||
|
|
||||||
# Dockge
|
# Dockge
|
||||||
|
|
||||||
A fancy, easy-to-use and reactive self-hosted docker compose.yaml stack-oriented manager.
|
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="" />
|
<img src="https://github.com/louislam/dockge/assets/1336778/26a583e1-ecb1-4a8d-aedf-76157d714ad7" width="900" alt="" />
|
||||||
|
|
||||||
View Video: https://youtu.be/AWAlOQeNpgU?t=48
|
|
||||||
|
|
||||||
## ⭐ Features
|
## ⭐ Features
|
||||||
|
|
||||||
- Manage `compose.yaml`
|
- Manage `compose.yaml`
|
||||||
- Create/Edit/Start/Stop/Restart/Delete
|
|
||||||
- Update Docker Images
|
|
||||||
- Interactive Editor for `compose.yaml`
|
- Interactive Editor for `compose.yaml`
|
||||||
- Interactive Web Terminal
|
- Interactive Web Terminal
|
||||||
- Reactive
|
- Reactive
|
||||||
@ -22,12 +18,6 @@ View Video: https://youtu.be/AWAlOQeNpgU?t=48
|
|||||||
- Easy-to-use & fancy UI
|
- Easy-to-use & fancy UI
|
||||||
- If you love Uptime Kuma's UI/UX, you will love this too
|
- If you love Uptime Kuma's UI/UX, you will love this too
|
||||||
- Convert `docker run ...` commands into `compose.yaml`
|
- Convert `docker run ...` commands into `compose.yaml`
|
||||||
- File based structure
|
|
||||||
- Dockge won't kidnap your compose files, they stored on your drive as usual. You can interact with them using normal `docker compose` commands
|
|
||||||
<img src="https://github.com/louislam/dockge/assets/1336778/cc071864-592e-4909-b73a-343a57494002" width=300 />
|
|
||||||
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 🔧 How to Install
|
## 🔧 How to Install
|
||||||
|
|
||||||
@ -41,8 +31,7 @@ Requirements:
|
|||||||
|
|
||||||
### Basic
|
### Basic
|
||||||
|
|
||||||
- Default Stacks Directory: `/opt/stacks`
|
Default stacks directory is `/opt/stacks`.
|
||||||
- Default Port: 5001
|
|
||||||
|
|
||||||
```
|
```
|
||||||
# Create a directory that stores your stacks and stores dockge's compose.yaml
|
# Create a directory that stores your stacks and stores dockge's compose.yaml
|
||||||
@ -59,13 +48,11 @@ docker compose up -d
|
|||||||
# docker-compose up -d
|
# docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
Dockge is now running on http://localhost:5001
|
|
||||||
|
|
||||||
### Advanced
|
### Advanced
|
||||||
|
|
||||||
If you want to store your stacks in another directory, you can change the `DOCKGE_STACKS_DIR` environment variable and volumes.
|
If you want to store your stacks in another directory, you can change the `DOCKGE_STACKS_DIR` environment variable and volumes.
|
||||||
|
|
||||||
For example, if you want to store your stacks in `/my-stacks`:
|
For exmaples, if you want to store your stacks in `/my-stacks`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: "3.8"
|
version: "3.8"
|
||||||
@ -74,14 +61,10 @@ services:
|
|||||||
image: louislam/dockge:1
|
image: louislam/dockge:1
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
# Host Port:Container Port
|
|
||||||
- 5001:5001
|
- 5001:5001
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
- ./data:/app/data
|
- ./data:/app/data
|
||||||
|
|
||||||
# If you want to use private registries, you need to share the auth file with Dockge:
|
|
||||||
# - /root/.docker/:/root/.docker
|
|
||||||
|
|
||||||
# Your stacks directory in the host
|
# Your stacks directory in the host
|
||||||
# (The paths inside container must be the same as the host)
|
# (The paths inside container must be the same as the host)
|
||||||
@ -94,23 +77,11 @@ services:
|
|||||||
## How to Update
|
## How to Update
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/dockge
|
cd /opt/stacks
|
||||||
docker compose pull
|
docker compose pull
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
## Screenshots
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
## Motivations
|
## 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.
|
- 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.
|
||||||
@ -119,10 +90,6 @@ docker compose up -d
|
|||||||
If you love this project, please consider giving this project a ⭐.
|
If you love this project, please consider giving this project a ⭐.
|
||||||
|
|
||||||
|
|
||||||
## 🗣️ Discussion / Ask for Help
|
|
||||||
|
|
||||||
Please go to https://github.com/louislam/dockge/discussions
|
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
#### "Dockge"?
|
#### "Dockge"?
|
||||||
@ -131,7 +98,7 @@ Please go to https://github.com/louislam/dockge/discussions
|
|||||||
|
|
||||||
The naming idea was coming from Twitch emotes like `sadge`, `bedge` or `wokege`. They are all ending with `-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`.
|
If you are not comfortable with the pronunciation, you can call it `Dockage`
|
||||||
|
|
||||||
#### Can I manage a single container without `compose.yaml`?
|
#### Can I manage a single container without `compose.yaml`?
|
||||||
|
|
||||||
|
@ -177,11 +177,6 @@ export class Stack {
|
|||||||
|
|
||||||
for (let filename of filenameList) {
|
for (let filename of filenameList) {
|
||||||
try {
|
try {
|
||||||
// Check if it is a directory
|
|
||||||
let stat = fs.statSync(path.join(stacksDir, filename));
|
|
||||||
if (!stat.isDirectory()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let stack = this.getStack(server, filename);
|
let stack = this.getStack(server, filename);
|
||||||
stack._status = CREATED_FILE;
|
stack._status = CREATED_FILE;
|
||||||
stackList.set(filename, stack);
|
stackList.set(filename, stack);
|
||||||
|
@ -86,8 +86,8 @@ export const TERMINAL_COLS = 105;
|
|||||||
export const TERMINAL_ROWS = 10;
|
export const TERMINAL_ROWS = 10;
|
||||||
export const PROGRESS_TERMINAL_ROWS = 8;
|
export const PROGRESS_TERMINAL_ROWS = 8;
|
||||||
|
|
||||||
export const COMBINED_TERMINAL_COLS = 58;
|
export const COMBINED_TERMINAL_COLS = 56;
|
||||||
export const COMBINED_TERMINAL_ROWS = 20;
|
export const COMBINED_TERMINAL_ROWS = 15;
|
||||||
|
|
||||||
export const ERROR_TYPE_VALIDATION = 1;
|
export const ERROR_TYPE_VALIDATION = 1;
|
||||||
|
|
||||||
|
@ -7,9 +7,6 @@ services:
|
|||||||
# Host Port : Container Port
|
# Host Port : Container Port
|
||||||
- 5001:5001
|
- 5001:5001
|
||||||
volumes:
|
volumes:
|
||||||
# If you want to use private registries, you need to share the auth file with Dockge:
|
|
||||||
# - /root/.docker/:/root/.docker
|
|
||||||
|
|
||||||
# Docker Socket
|
# Docker Socket
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
# Dockge Config
|
# Dockge Config
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
import childProcess from "child_process";
|
|
||||||
|
|
||||||
let env = process.env;
|
|
||||||
|
|
||||||
let cmd = process.argv[2];
|
|
||||||
let args = process.argv.slice(3);
|
|
||||||
let replacedArgs = [];
|
|
||||||
|
|
||||||
for (let arg of args) {
|
|
||||||
for (let key in env) {
|
|
||||||
arg = arg.replaceAll(`$${key}`, env[key]);
|
|
||||||
}
|
|
||||||
replacedArgs.push(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
let child = childProcess.spawn(cmd, replacedArgs);
|
|
||||||
child.stdout.pipe(process.stdout);
|
|
||||||
child.stderr.pipe(process.stderr);
|
|
@ -1,9 +0,0 @@
|
|||||||
// Check if docker is running
|
|
||||||
import { exec } from "child_process";
|
|
||||||
|
|
||||||
exec("docker ps", (err, stdout, stderr) => {
|
|
||||||
if (err) {
|
|
||||||
console.error("Docker is not running. Please start docker and try again.");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,64 +0,0 @@
|
|||||||
import pkg from "../package.json";
|
|
||||||
import childProcess from "child_process";
|
|
||||||
import fs from "fs";
|
|
||||||
|
|
||||||
const newVersion = process.env.VERSION;
|
|
||||||
|
|
||||||
console.log("New Version: " + newVersion);
|
|
||||||
|
|
||||||
if (! newVersion) {
|
|
||||||
console.error("invalid version");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const exists = tagExists(newVersion);
|
|
||||||
|
|
||||||
if (! exists) {
|
|
||||||
// Process package.json
|
|
||||||
pkg.version = newVersion;
|
|
||||||
fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n");
|
|
||||||
commit(newVersion);
|
|
||||||
tag(newVersion);
|
|
||||||
} else {
|
|
||||||
console.log("version exists");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Commit updated files
|
|
||||||
* @param {string} version Version to update to
|
|
||||||
*/
|
|
||||||
function commit(version) {
|
|
||||||
let msg = "Update to " + version;
|
|
||||||
|
|
||||||
let res = childProcess.spawnSync("git", [ "commit", "-m", msg, "-a" ]);
|
|
||||||
let stdout = res.stdout.toString().trim();
|
|
||||||
console.log(stdout);
|
|
||||||
|
|
||||||
if (stdout.includes("no changes added to commit")) {
|
|
||||||
throw new Error("commit error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a tag with the specified version
|
|
||||||
* @param {string} version Tag to create
|
|
||||||
*/
|
|
||||||
function tag(version) {
|
|
||||||
let res = childProcess.spawnSync("git", [ "tag", version ]);
|
|
||||||
console.log(res.stdout.toString().trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a tag exists for the specified version
|
|
||||||
* @param {string} version Version to check
|
|
||||||
* @returns {boolean} Does the tag already exist
|
|
||||||
*/
|
|
||||||
function tagExists(version) {
|
|
||||||
if (! version) {
|
|
||||||
throw new Error("invalid version");
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = childProcess.spawnSync("git", [ "tag", "-l", version ]);
|
|
||||||
|
|
||||||
return res.stdout.toString().trim() === version;
|
|
||||||
}
|
|
@ -115,7 +115,7 @@
|
|||||||
{{ $tc("network", 2) }}
|
{{ $tc("network", 2) }}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div v-if="networkList.length === 0 && service.networks && service.networks.length > 0" class="text-warning mb-3">
|
<div v-if="networkList.length === 0 && service.networks.length > 0" class="text-warning mb-3">
|
||||||
No networks available. You need to add internal networks or enable external networks in the right side first.
|
No networks available. You need to add internal networks or enable external networks in the right side first.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -77,8 +77,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.terminal = new Terminal({
|
this.terminal = new Terminal({
|
||||||
fontSize: 14,
|
fontSize: 16,
|
||||||
fontFamily: "'JetBrains Mono', monospace",
|
fontFamily: "monospace",
|
||||||
cursorBlink,
|
cursorBlink,
|
||||||
cols: this.cols,
|
cols: this.cols,
|
||||||
rows: this.rows,
|
rows: this.rows,
|
||||||
|
@ -13,7 +13,6 @@ import Toast, { POSITION, useToast } from "vue-toastification";
|
|||||||
import "xterm/lib/xterm.js";
|
import "xterm/lib/xterm.js";
|
||||||
|
|
||||||
// CSS
|
// CSS
|
||||||
import "@fontsource/jetbrains-mono";
|
|
||||||
import "vue-toastification/dist/index.css";
|
import "vue-toastification/dist/index.css";
|
||||||
import "xterm/css/xterm.css";
|
import "xterm/css/xterm.css";
|
||||||
import "./styles/main.scss";
|
import "./styles/main.scss";
|
||||||
@ -23,9 +22,6 @@ import socket from "./mixins/socket";
|
|||||||
import lang from "./mixins/lang";
|
import lang from "./mixins/lang";
|
||||||
import theme from "./mixins/theme";
|
import theme from "./mixins/theme";
|
||||||
|
|
||||||
// Set Title
|
|
||||||
document.title = document.title + " - " + location.host;
|
|
||||||
|
|
||||||
const app = createApp(rootApp());
|
const app = createApp(rootApp());
|
||||||
|
|
||||||
app.use(Toast, {
|
app.use(Toast, {
|
||||||
|
@ -592,8 +592,6 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.editor-box {
|
.editor-box {
|
||||||
font-family: 'JetBrains Mono', monospace;
|
|
||||||
font-size: 14px;
|
|
||||||
&.edit-mode {
|
&.edit-mode {
|
||||||
background-color: #2c2f38 !important;
|
background-color: #2c2f38 !important;
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,5 @@ table {
|
|||||||
.docker-run {
|
.docker-run {
|
||||||
background-color: $dark-bg !important;
|
background-color: $dark-bg !important;
|
||||||
border: none;
|
border: none;
|
||||||
font-family: 'JetBrains Mono', monospace;
|
|
||||||
font-size: 15px;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dockge",
|
"name": "dockge",
|
||||||
"version": "1.0.2",
|
"version": "1.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"fmt": "eslint \"**/*.{ts,vue}\" --fix",
|
"fmt": "eslint \"**/*.{ts,vue}\" --fix",
|
||||||
@ -8,16 +8,14 @@
|
|||||||
"start": "tsx ./backend/index.ts",
|
"start": "tsx ./backend/index.ts",
|
||||||
"dev:backend": "cross-env NODE_ENV=development tsx watch ./backend/index.ts",
|
"dev:backend": "cross-env NODE_ENV=development tsx watch ./backend/index.ts",
|
||||||
"dev:frontend": "cross-env NODE_ENV=development vite --host --config ./frontend/vite.config.ts",
|
"dev:frontend": "cross-env NODE_ENV=development vite --host --config ./frontend/vite.config.ts",
|
||||||
"release-final": "tsx ./extra/test-docker.ts && tsx extra/update-version.ts && pnpm run build:frontend && npm run build:docker",
|
|
||||||
"build:frontend": "vite build --config ./frontend/vite.config.ts",
|
"build:frontend": "vite build --config ./frontend/vite.config.ts",
|
||||||
"build:docker-base": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/dockge:base -f ./docker/Base.Dockerfile . --push",
|
"build:docker-base": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/dockge:base -f ./docker/Base.Dockerfile . --push",
|
||||||
"build:docker": "node ./extra/env2arg.js docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/dockge:latest -t louislam/dockge:1 -t louislam/dockge:$VERSION --target release -f ./docker/Dockerfile . --push",
|
"build:docker": "pnpm run build:frontend && docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/dockge:latest -t louislam/dockge:1 -t louislam/dockge:1.0.0 -f ./docker/Dockerfile . --push",
|
||||||
"build:docker-nightly": "pnpm run build:frontend && docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/dockge:nightly --target nightly -f ./docker/Dockerfile . --push",
|
"build:docker-nightly": "pnpm run build:frontend && docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/dockge:nightly --target nightly -f ./docker/Dockerfile . --push",
|
||||||
"start-docker": "docker run --rm -p 5001:5001 --name dockge louislam/dockge:latest",
|
"start-docker": "docker run --rm -p 5001:5001 --name dockge louislam/dockge:latest",
|
||||||
"mark-as-nightly": "tsx ./extra/mark-as-nightly.ts"
|
"mark-as-nightly": "tsx ./extra/mark-as-nightly.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/jetbrains-mono": "^5.0.17",
|
|
||||||
"@homebridge/node-pty-prebuilt-multiarch": "~0.11.10",
|
"@homebridge/node-pty-prebuilt-multiarch": "~0.11.10",
|
||||||
"@louislam/sqlite3": "~15.1.6",
|
"@louislam/sqlite3": "~15.1.6",
|
||||||
"bcryptjs": "~2.4.3",
|
"bcryptjs": "~2.4.3",
|
||||||
|
7
pnpm-lock.yaml
generated
7
pnpm-lock.yaml
generated
@ -5,9 +5,6 @@ settings:
|
|||||||
excludeLinksFromLockfile: false
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@fontsource/jetbrains-mono':
|
|
||||||
specifier: ^5.0.17
|
|
||||||
version: 5.0.17
|
|
||||||
'@homebridge/node-pty-prebuilt-multiarch':
|
'@homebridge/node-pty-prebuilt-multiarch':
|
||||||
specifier: ~0.11.10
|
specifier: ~0.11.10
|
||||||
version: 0.11.10
|
version: 0.11.10
|
||||||
@ -469,10 +466,6 @@ packages:
|
|||||||
- vue
|
- vue
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@fontsource/jetbrains-mono@5.0.17:
|
|
||||||
resolution: {integrity: sha512-Y/EtdbwKwNQTGpnMrexX8SVW6Jqlh0nX2bNHI9Z9m6FsyjbocZIFNJqwSY9bDUoi7irGtz8nuidAN7FF8wYuJA==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@fortawesome/fontawesome-common-types@6.4.2:
|
/@fortawesome/fontawesome-common-types@6.4.2:
|
||||||
resolution: {integrity: sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==}
|
resolution: {integrity: sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
Reference in New Issue
Block a user