Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f6eeccf
feat: installer hardening flags and one source for pinned versions
agentHits Oct 8, 2026
8a78f36
docs: describe the panel machine generically in the hardening runbook
agentHits Oct 8, 2026
0f75632
feat(db): default Railpack version for new applications to 0.40.1
agentHits Oct 8, 2026
f274ba5
docs: update the hardening runbook to the current Traefik pin
agentHits Oct 8, 2026
5afd651
test: give the subprocess settings tests a 30s timeout
agentHits Oct 8, 2026
20216c0
fix(update): roll back a failed panel self-update
agentHits Oct 8, 2026
1974a46
feat(update): pre-download components before the update changes anything
agentHits Oct 8, 2026
0a4a72a
feat(update): read the panel update outcome from swarm
agentHits Oct 8, 2026
228da6c
feat(update): update the panel host stack in dependency order
agentHits Oct 8, 2026
a364baa
docs: describe the update order, rollback and backups
agentHits Oct 8, 2026
ca366f3
refactor(update): name the new operator settings after the panel
agentHits Oct 8, 2026
1c67146
fix(update): keep the Postgres backup readable by root only
agentHits Oct 8, 2026
5f99a67
fix(update): refuse a Postgres major version change before anything runs
agentHits Oct 8, 2026
f0084e8
fix(update): set the backup directory mode with an explicit chmod
agentHits Oct 8, 2026
e442554
fix(update): pin Docker in update.sh to the shared version
agentHits Oct 8, 2026
b73097e
feat(update): roll back the panel host Docker engine upgrade
agentHits Oct 8, 2026
97320df
feat(servers): install the pinned Docker from apt with rollback
agentHits Oct 8, 2026
2b92166
feat(servers): make the Docker Engine upgrade opt-in in the Component…
agentHits Oct 8, 2026
2d57262
docs: document Docker engine upgrade and rollback
agentHits Oct 8, 2026
422f343
fix(update): set the Traefik restart policy before the swap stops the…
agentHits Oct 8, 2026
c0b76c9
fix(servers): skip only the Docker step on Docker-specific pre-downlo…
agentHits Oct 8, 2026
2e8a971
fix(update): pass the same settings through the WSL launcher as throu…
agentHits Oct 8, 2026
009b6bd
fix(servers): leave the host as it was when a later Docker step fails
agentHits Oct 8, 2026
9f37d61
fix(update): remove the saved-packages directory when Docker is skipp…
agentHits Oct 8, 2026
d86d18b
fix(update): replace the Traefik swap that renamed the running container
agentHits Oct 8, 2026
c517f61
fix(servers): fail the Nixpacks and Railpack updates when their insta…
agentHits Oct 8, 2026
f7fa0c3
docs: describe the Traefik replacement without renaming
agentHits Oct 8, 2026
65da65a
fix(servers): fail the server setup when the Nixpacks or Railpack ins…
agentHits Oct 8, 2026
e84c654
fix(update): fail the installer when the Nixpacks or Railpack install…
agentHits Oct 8, 2026
2ea6bf6
test(servers): check that failed Buildpacks and RClone downloads fail…
agentHits Oct 8, 2026
6adc198
fix(update): reset Traefik's restart policy before the Docker rollbac…
agentHits Oct 8, 2026
d08ed84
fix(update): verify Docker within its own window, 30 s on remote serv…
agentHits Oct 8, 2026
9da23cc
fix(update): poll the new Traefik during the settle time and stop at …
agentHits Oct 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dokploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ jobs:

- uses: actions/setup-node@v7
with:
node-version: 24.4.0
node-version: 24.21.0
cache: pnpm

- name: Generate OpenAPI specification
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- uses: actions/setup-node@v7
if: ${{ !cancelled() }}
with:
node-version: 24.4.0
node-version: 24.21.0
- run: bun install --frozen-lockfile
if: ${{ !cancelled() }}
- run: bun run server:build
Expand All @@ -54,7 +54,7 @@ jobs:
bun-version: 1.4.2
- uses: actions/setup-node@v7
with:
node-version: 24.4.0
node-version: 24.21.0

- name: Install Nixpacks
if: matrix.job == 'test' && runner.environment == 'github-hosted'
Expand All @@ -66,7 +66,7 @@ jobs:
- name: Install Railpack
if: matrix.job == 'test' && runner.environment == 'github-hosted'
run: |
export RAILPACK_VERSION=0.15.4
export RAILPACK_VERSION=0.40.1
curl -sSL https://railpack.com/install.sh | bash
echo "Railpack installed $RAILPACK_VERSION"

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sync-openapi-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
bun-version: 1.4.2
- uses: actions/setup-node@v7
with:
node-version: 24.4.0
node-version: 24.21.0

- name: Install dependencies
run: bun install --frozen-lockfile
Expand Down
18 changes: 14 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1
FROM node:24.4.0-slim AS base
FROM node:24.21.0-slim AS base
ENV BUN_INSTALL="/root/.bun"
ENV PATH="$BUN_INSTALL/bin:$PATH"
RUN apt-get update \
Expand Down Expand Up @@ -79,7 +79,17 @@ COPY --from=build /usr/src/app/packages/server/dist ./packages/server/dist


# Install docker
RUN curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh --version 28.5.2 && rm get-docker.sh && curl https://rclone.org/install.sh | bash
ARG DOCKER_VERSION=29.8.2
RUN curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh --version "$DOCKER_VERSION" && rm get-docker.sh

# Install rclone
ARG RCLONE_VERSION=1.75.1
RUN apt-get update \
&& apt-get install -y --no-install-recommends unzip \
&& curl -fsSL "https://downloads.rclone.org/v${RCLONE_VERSION}/rclone-v${RCLONE_VERSION}-linux-amd64.zip" -o /tmp/rclone.zip \
&& unzip -q /tmp/rclone.zip -d /tmp \
&& install -m 0755 "/tmp/rclone-v${RCLONE_VERSION}-linux-amd64/rclone" /usr/bin/rclone \
&& rm -rf /tmp/rclone.zip "/tmp/rclone-v${RCLONE_VERSION}-linux-amd64" /var/lib/apt/lists/*

# Install Nixpacks and tsx
# | VERBOSE=1 VERSION=1.21.0 bash
Expand All @@ -92,12 +102,12 @@ RUN curl -sSL https://nixpacks.com/install.sh -o install.sh \
&& bun install -g tsx

# Install Railpack
ARG RAILPACK_VERSION=0.15.4
ARG RAILPACK_VERSION=0.40.1
RUN curl -sSL https://railpack.com/install.sh \
| RAILPACK_VERSION="$RAILPACK_VERSION" bash -s -- --yes --bin-dir /usr/local/bin

# Install buildpacks
COPY --from=buildpacksio/pack:0.39.1 /usr/local/bin/pack /usr/local/bin/pack
COPY --from=buildpacksio/pack:0.40.9 /usr/local/bin/pack /usr/local/bin/pack

EXPOSE 3000

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.cloud
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1
FROM node:24.4.0-slim AS base
FROM node:24.21.0-slim AS base
ENV BUN_INSTALL="/root/.bun"
ENV PATH="$BUN_INSTALL/bin:$PATH"
RUN apt-get update \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.schedule
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1
FROM node:24.4.0-slim AS base
FROM node:24.21.0-slim AS base
ENV BUN_INSTALL="/root/.bun"
ENV PATH="$BUN_INSTALL/bin:$PATH"
RUN apt-get update \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.server
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1
FROM node:24.4.0-slim AS base
FROM node:24.21.0-slim AS base
ENV BUN_INSTALL="/root/.bun"
ENV PATH="$BUN_INSTALL/bin:$PATH"
RUN apt-get update \
Expand Down
175 changes: 175 additions & 0 deletions apps/dokploy/__test__/server/component-versions-sync.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { readFileSync } from "node:fs";
import path from "node:path";
import { PINNED_VERSIONS } from "@dokploy/server/setup/component-versions";
import { TRAEFIK_VERSION } from "@dokploy/server/setup/traefik-setup";
import { describe, expect, it } from "vitest";

const repoRoot = path.resolve(process.cwd(), "../..");
const read = (file: string) => readFileSync(path.join(repoRoot, file), "utf8");

const pinIn = (text: string, pattern: RegExp) => {
const match = text.match(pattern);
if (!match?.[1]) {
throw new Error(`pin not found: ${pattern}`);
}
return match[1];
};

describe("install-agenthits.sh defaults", () => {
const installer = read("install-agenthits.sh");

it("pins Docker", () => {
expect(
pinIn(installer, /DOCKER_VERSION="\$\{DOCKER_VERSION:-([^}]+)\}"/),
).toBe(PINNED_VERSIONS.docker);
});
it("pins Traefik", () => {
expect(
pinIn(installer, /TRAEFIK_IMAGE="\$\{TRAEFIK_IMAGE:-traefik:v([^}]+)\}"/),
).toBe(PINNED_VERSIONS.traefik);
});
it("pins Postgres", () => {
expect(
pinIn(
installer,
/POSTGRES_IMAGE="\$\{POSTGRES_IMAGE:-postgres:([^}]+)\}"/,
),
).toBe(PINNED_VERSIONS.postgres);
});
it("pins Redis", () => {
expect(
pinIn(installer, /REDIS_IMAGE="\$\{REDIS_IMAGE:-redis:([^}]+)\}"/),
).toBe(PINNED_VERSIONS.redis);
});
it("pins Nixpacks", () => {
expect(
pinIn(installer, /NIXPACKS_VERSION="\$\{NIXPACKS_VERSION:-([^}]+)\}"/),
).toBe(PINNED_VERSIONS.nixpacks);
});
it("pins Railpack", () => {
expect(
pinIn(installer, /RAILPACK_VERSION="\$\{RAILPACK_VERSION:-([^}]+)\}"/),
).toBe(PINNED_VERSIONS.railpack);
});
it("pins Buildpacks", () => {
expect(
pinIn(
installer,
/BUILDPACKS_VERSION="\$\{BUILDPACKS_VERSION:-([^}]+)\}"/,
),
).toBe(PINNED_VERSIONS.buildpacks);
});
it("pins RClone", () => {
expect(
pinIn(installer, /RCLONE_VERSION="\$\{RCLONE_VERSION:-([^}]+)\}"/),
).toBe(PINNED_VERSIONS.rclone);
});
});

describe("update.sh defaults", () => {
const updateScript = read("update.sh");

it("pins Docker", () => {
expect(
pinIn(updateScript, /DOCKER_VERSION="\$\{DOCKER_VERSION:-([^}]+)\}"/),
).toBe(PINNED_VERSIONS.docker);
});
});

describe("Dockerfile", () => {
const dockerfile = read("Dockerfile");

it("pins Docker", () => {
expect(pinIn(dockerfile, /ARG DOCKER_VERSION=(\S+)/)).toBe(
PINNED_VERSIONS.docker,
);
});
it("pins RClone", () => {
expect(pinIn(dockerfile, /ARG RCLONE_VERSION=(\S+)/)).toBe(
PINNED_VERSIONS.rclone,
);
});
it("pins Nixpacks", () => {
expect(pinIn(dockerfile, /ARG NIXPACKS_VERSION=(\S+)/)).toBe(
PINNED_VERSIONS.nixpacks,
);
});
it("pins Railpack", () => {
expect(pinIn(dockerfile, /ARG RAILPACK_VERSION=(\S+)/)).toBe(
PINNED_VERSIONS.railpack,
);
});
it("pins pack", () => {
expect(pinIn(dockerfile, /buildpacksio\/pack:(\S+) /)).toBe(
PINNED_VERSIONS.buildpacks,
);
});
});

describe("CI workflow", () => {
const ci = read(".github/workflows/pull-request.yml");

it("pins Nixpacks", () => {
expect(pinIn(ci, /export NIXPACKS_VERSION=(\S+)/)).toBe(
PINNED_VERSIONS.nixpacks,
);
});
it("pins Railpack", () => {
expect(pinIn(ci, /export RAILPACK_VERSION=(\S+)/)).toBe(
PINNED_VERSIONS.railpack,
);
});
});

describe("application Railpack picker", () => {
const picker = read(
"apps/dokploy/components/dashboard/application/build/show.tsx",
);

it("defaults new applications to the pinned Railpack", () => {
expect(
pinIn(
picker,
/railpackVersion: z\.string\(\)\.nullable\(\)\.default\("([^"]+)"\)/,
),
).toBe(PINNED_VERSIONS.railpack);
});
it("offers the pinned Railpack in the version list", () => {
expect(picker).toContain(`\t"${PINNED_VERSIONS.railpack}",`);
});
});

describe("panel Traefik default", () => {
it("matches the pin", () => {
expect(TRAEFIK_VERSION).toBe(PINNED_VERSIONS.traefik);
});
});

describe("Node.js image and CI version", () => {
const dockerfiles = [
"Dockerfile",
"Dockerfile.cloud",
"Dockerfile.schedule",
"Dockerfile.server",
];

it.each(dockerfiles)("%s builds on the pinned Node image", (file) => {
expect(pinIn(read(file), /FROM node:(\S+)-slim AS base/)).toBe(
PINNED_VERSIONS.node,
);
});

it.each([
".github/workflows/dokploy.yml",
".github/workflows/pull-request.yml",
".github/workflows/sync-openapi-docs.yml",
])("%s runs on the pinned Node version", (file) => {
const versions = [...read(file).matchAll(/node-version: (\S+)/g)].map(
(match) => match[1],
);
expect(versions.length).toBeGreaterThan(0);
expect(versions.every((version) => version === PINNED_VERSIONS.node)).toBe(
true,
);
});
});
Loading