Dockge Removal
CI / ci (push) Canceled after 0s

Removed dockge from the app as it is not required due to the manager page picking up most of its abilities.
This commit is contained in:
Stefan Lazic committed 2026-09-06 18:33:01 +01:00
1 parent 973cb9efc6
commit 4763b50e62
10 files changed
+74 -76

No files matched your search

-12
View File
@@ -22,15 +22,3 @@ ACME_EMAIL="you@example.com"
# testing on a machine already using those ports for something else.
CADDY_HTTP_PORT=80
CADDY_HTTPS_PORT=443
# ── Dockge (stack management UI — http://<vps>:5001) ───────────────────
# This repo's absolute path on the VPS, e.g. "/opt/nextchair/stacks" — NOT
# a relative path. Dockge (and the management UI in manager/) shell
# `docker compose` out to the HOST's dockerd via the mounted Docker
# socket, so a compose-file path only resolves to the same file on both
# sides if the bind-mount doesn't change it — meaning this must be
# mounted at the identical path inside the container too (see
# stacks/infra/compose.yaml's dockge service). Get this wrong and Dockge
# will either fail to find your stacks or manage the wrong path entirely.
STACKS_DIR="/opt/nextchair/stacks"
DOCKGE_HOST_PORT=5001
+6 -5
View File
@@ -27,11 +27,12 @@ dist/
# per-deployment production env files (multi-business VPS setup — see
# stacks/infra/compose.yaml / stacks/<business>/compose.yaml). Every real
# stack's .env lives at stacks/<name>/.env (Dockge's own directory
# convention) — this one wildcard rule covers every current and future
# stack without another .gitignore edit. .env.infra.example and
# .env.business.example (the templates you copy into each stacks/<name>/
# directory) stay tracked, same as .env.local.example above.
# stack's .env lives at stacks/<name>/.env (one directory per stack,
# same convention NextChair Manager's provisioning uses) — this one
# wildcard rule covers every current and future stack without another
# .gitignore edit. .env.infra.example and .env.business.example (the
# templates you copy into each stacks/<name>/ directory) stay tracked,
# same as .env.local.example above.
stacks/*/.env
# Real per-business Caddy site files (deployment-specific domains, not
+44 -2
View File
@@ -48,7 +48,7 @@ docker run --rm node:22-alpine sh -c \
node -e \"const h=require('/tmp/gen/node_modules/bcryptjs').hashSync('your-password',12); console.log('MANAGER_PASSWORD_HASH=\\\"'+h.replace(/\\$/g,'\\$\\$')+'\\\"')\""
```
### 1. Shared infrastructure — network, MySQL, Caddy, Dockge
### 1. Shared infrastructure — network, MySQL and Caddy
```bash
docker network create next-chair-edge
@@ -60,7 +60,6 @@ Edit `stacks/infra/.env`:
- `MYSQL_ROOT_PASSWORD` — the first secret you generated above.
- `MYSQL_HOST_PORT` — set this to `127.0.0.1:3306` so MySQL is only exposed on the VPS loopback interface, not publicly. You can still connect to it remotely through an SSH tunnel.
- `ACME_EMAIL` — a real address you check (Let's Encrypt renewal notices).
- `STACKS_DIR` — the absolute clone path, e.g. `/opt/nextchair/stacks`.
```bash
docker compose -f stacks/infra/compose.yaml --env-file stacks/infra/.env up -d
@@ -189,3 +188,46 @@ docker compose -f stacks/manager/compose.yaml --env-file stacks/manager/.env up
```
If both the business app and Manager changed, do both update steps.
## Upgrading from a version that included Dockge (one-time)
Dockge used to run alongside NextChair Manager as a separate stack
management UI. It's no longer part of the shared infrastructure stack —
Manager is the only tool needed to provision and manage business stacks,
so the two were redundant. If your server was set up before this change,
existing tenant databases, tenant containers, business Compose files, and
the global SMTP/VAPID settings are all unaffected — this only removes the
old Dockge container.
Pull the change, then re-apply the infra stack with `--remove-orphans` so
Docker removes the container that's no longer defined in
`stacks/infra/compose.yaml`:
```bash
cd /opt/nextchair
git pull
docker compose \
-f stacks/infra/compose.yaml \
--env-file stacks/infra/.env \
up -d --remove-orphans
```
`--remove-orphans` only removes containers Compose no longer recognizes
(the old `next-chair-dockge` container) — it does not touch Caddy, MySQL,
or their volumes.
This does **not** delete Dockge's own data volume
(`next-chair-dockge-data`) — Docker never removes volumes on its own, and
this command has no reason to either. Once you've confirmed Caddy, MySQL
and every business are still healthy, you can remove that now-unused
volume by hand:
```bash
docker volume rm next-chair-dockge-data
```
Finally, `STACKS_DIR` and `DOCKGE_HOST_PORT` in `stacks/infra/.env` were
only ever used by Dockge and are safe to delete from that file — nothing
else in the infra stack reads them. (Manager keeps its own separate
`STACKS_DIR` in `stacks/manager/.env`; leave that one alone.)
+6 -6
View File
@@ -29,8 +29,12 @@ MYSQL_PORT="3306"
MYSQL_ROOT_PASSWORD="replace-me"
# ── Docker / stacks ──────────────────────────────────────────────────────
# Must be the identical absolute path as stacks/infra/.env's STACKS_DIR —
# see that file's comment for why.
# This repo's absolute path on the VPS, e.g. "/opt/nextchair/stacks" — NOT
# a relative path. This container shells `docker compose` out to the
# HOST's dockerd via the mounted Docker socket (see src/lib/docker.ts), so
# a compose-file path only resolves to the same file on both sides if the
# bind-mount doesn't change it — meaning this must be mounted at the
# identical path inside the container too (see stacks/manager/compose.yaml).
STACKS_DIR="/opt/nextchair/stacks"
# Every business's compose.yaml (see src/lib/compose-template.ts) uses
# this image tag — rebuild with `docker build -t nextchair-app:latest .`
@@ -38,7 +42,3 @@ STACKS_DIR="/opt/nextchair/stacks"
# "Update" button (or `docker compose up -d --force-recreate`) to pick it
# up.
NEXTCHAIR_IMAGE="nextchair-app:latest"
# ── Optional ─────────────────────────────────────────────────────────────
# Shown as a link in the dashboard header if set.
DOCKGE_URL="http://your-vps-ip:5001"
+1 -2
View File
@@ -58,8 +58,7 @@ effectively means root on the host. Consequences:
both host and container (see `.env.example`) — a `docker compose -f
<path>` command run from inside this container is executed by the
*host's* dockerd, so the path only means the same file on both sides if
the mount doesn't change it. This is the same constraint Dockge itself
has.
the mount doesn't change it.
## Setup
-7
View File
@@ -2,8 +2,6 @@ import Link from "next/link";
import { logoutAction } from "./logout-action";
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
const dockgeUrl = process.env.DOCKGE_URL;
return (
<div className="min-h-screen">
<header className="flex items-center justify-between border-b border-line bg-surface px-6 py-4">
@@ -14,11 +12,6 @@ export default function DashboardLayout({ children }: { children: React.ReactNod
<Link href="/dashboard/settings" className="text-muted hover:text-ink">
Settings
</Link>
{dockgeUrl && (
<a href={dockgeUrl} target="_blank" rel="noreferrer" className="text-muted hover:text-ink">
Dockge ↗
</a>
)}
<form action={logoutAction}>
<button type="submit" className="text-muted hover:text-ink">
Sign out
+2 -3
View File
@@ -7,9 +7,8 @@ const execFileAsync = promisify(execFile);
* Every call here runs `docker compose` with `cwd` set to a stack's own
* directory (stacks/<slug>/) rather than passing explicit -f/--env-file
* flags — compose already auto-loads `compose.yaml` and `.env` from the
* current directory, and this is the same convention Dockge itself uses,
* so a stack behaves identically whether it's started by this app, by
* Dockge, or by hand from the command line.
* current directory, so a stack behaves identically whether it's started
* by this app or by hand from the command line.
*
* This app's own container needs the Docker socket mounted and the
* `docker compose` CLI installed (see manager/Dockerfile) — these calls
+2 -2
View File
@@ -1,8 +1,8 @@
name: next-chair-blake-heritage
# One business's app container on the shared multi-business VPS setup —
# see stacks/infra/compose.yaml for the shared MySQL/Caddy/Dockge this
# attaches to, and that file's header for the exact one-time setup steps
# see stacks/infra/compose.yaml for the shared MySQL/Caddy this attaches
# to, and that file's header for the exact one-time setup steps
# (create this business's database, copy .env.business.example, add a
# Caddy site file) needed before this file can start.
#
+11 -35
View File
@@ -1,24 +1,24 @@
name: next-chair-infra
# Shared infrastructure for the multi-business VPS deployment: Caddy
# (reverse proxy + automatic TLS via Let's Encrypt), one MySQL server
# (reverse proxy + automatic TLS via Let's Encrypt) and one MySQL server
# shared by every business (a separate database + user per business, NOT
# one shared schema — see step 1 below), and Dockge (a web UI for
# starting/stopping/inspecting these compose stacks by hand).
# one shared schema — see step 1 below).
#
# Lives in stacks/infra/ so Dockge (which expects one directory per
# stack, each with its own compose.yaml) can manage this stack too —
# see stacks/blake-heritage/, stacks/marios/ for the same shape per
# business. Deliberately separate from docker-compose.local.yaml at the
# Lives in stacks/infra/, one directory per stack (each with its own
# compose.yaml) — see stacks/blake-heritage/, stacks/marios/ for the same
# shape per business, and stacks/manager/ for the management UI's own
# stack. Deliberately separate from docker-compose.local.yaml at the
# repo root, which is the single-business local/Docker-Desktop setup and
# stays untouched by any of this.
#
# Stack management/provisioning is handled by NextChair Manager (see
# manager/ at the repo root) — there is no separate stack-management UI
# alongside it.
#
# ── One-time setup ───────────────────────────────────────────────────────
# docker network create next-chair-edge
# cp .env.infra.example stacks/infra/.env (then fill in real values —
# in particular STACKS_DIR must be this repo's absolute path on the
# VPS, e.g. /opt/nextchair/stacks — see the STACKS_DIR comment in that
# file for why it can't just be a relative path here)
# cp .env.infra.example stacks/infra/.env (then fill in real values)
# docker compose -f stacks/infra/compose.yaml --env-file stacks/infra/.env up -d
#
# ── Per business ──────────────────────────────────────────────────────
@@ -98,28 +98,6 @@ services:
networks:
- next-chair-edge
dockge:
image: louislam/dockge:1
container_name: next-chair-dockge
restart: unless-stopped
env_file:
- .env
environment:
DOCKGE_STACKS_DIR: "${STACKS_DIR}"
ports:
- "${DOCKGE_HOST_PORT:-5001}:5001"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- next-chair-dockge-data:/app/data
# MUST be mounted at the identical absolute path on both host and
# container — see the STACKS_DIR comment in .env.infra.example for
# why (Dockge shells `docker compose` out to the HOST's dockerd via
# the socket above, so a compose-file path only means the same
# thing on both sides if the bind-mount doesn't change it).
- "${STACKS_DIR}:${STACKS_DIR}"
networks:
- next-chair-edge
volumes:
next-chair-mysql-data:
name: next-chair-mysql-data
@@ -127,8 +105,6 @@ volumes:
name: next-chair-caddy-data
next-chair-caddy-config:
name: next-chair-caddy-config
next-chair-dockge-data:
name: next-chair-dockge-data
networks:
next-chair-edge:
+2 -2
View File
@@ -4,8 +4,8 @@ name: next-chair-manager
# explains why it's a fully separate app). Its own stack, separate from
# stacks/infra/compose.yaml, since this is real application code that
# gets rebuilt/updated far more often than the off-the-shelf infra
# images (MySQL, Caddy, Dockge) — a code change here shouldn't require
# touching the infra stack at all.
# images (MySQL, Caddy) — a code change here shouldn't require touching
# the infra stack at all.
#
# cp manager/.env.example stacks/manager/.env (then fill in real values)
# docker compose -f stacks/manager/compose.yaml --env-file stacks/manager/.env up -d --build