Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
76 changes: 76 additions & 0 deletions packages/local-docker/docker-compose.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { readFile } from "node:fs/promises";
import { fileURLToPath } from "node:url";
import { describe, expect, it } from "vitest";
import { parse } from "yaml";

type ComposeService = {
container_name?: string;
image?: string;
build?: {
context?: string;
dockerfile?: string;
};
ports?: Array<number | string>;
volumes?: string[];
depends_on?: string[];
environment?: Record<string, string | number>;
};

type ComposeFile = {
name?: string;
services?: Record<string, ComposeService>;
volumes?: Record<string, unknown>;
};

const composePath = fileURLToPath(
new URL("./docker-compose.yml", import.meta.url),
);

async function readCompose() {
const source = await readFile(composePath, "utf8");
return parse(source) as ComposeFile;
}

describe("local Docker compose file", () => {
it("keeps the expected local development services wired", async () => {
const compose = await readCompose();

expect(compose.name).toBe("cap-so-dev");
expect(Object.keys(compose.services ?? {}).sort()).toEqual([
"cap-media-server",
"createbuckets",
"minio",
"ps-mysql",
]);

expect(compose.services?.["ps-mysql"]).toMatchObject({
image: "mysql:8.0",
container_name: "mysql-primary-db",
});
expect(compose.services?.["cap-media-server"]?.build).toEqual({
context: "../..",
dockerfile: "apps/media-server/Dockerfile",
});
expect(compose.services?.minio?.ports).toEqual(["9000:9000", "9001:9001"]);
expect(compose.services?.createbuckets?.depends_on).toEqual(["minio"]);
});

it("does not declare stale named volumes", async () => {
const compose = await readCompose();
const declaredVolumes = new Set(Object.keys(compose.volumes ?? {}));
const usedNamedVolumes = new Set(
Object.values(compose.services ?? {})
.flatMap((service) => service.volumes ?? [])
.map((volume) => volume.split(":")[0])
.filter(
(source) =>
source &&
!source.startsWith(".") &&
!source.startsWith("/") &&
!source.startsWith("~"),
),
);

expect([...declaredVolumes].sort()).toEqual([...usedNamedVolumes].sort());
});
});
4 changes: 1 addition & 3 deletions packages/local-docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ services:
PORT: 3456
MEDIA_SERVER_WEBHOOK_SECRET: ${MEDIA_SERVER_WEBHOOK_SECRET:-local-media-server-secret}

# Local S3 Strorage
# Local S3 Storage
minio:
container_name: minio-storage
image: "minio/minio:latest"
Expand Down Expand Up @@ -62,5 +62,3 @@ services:
"
volumes:
ps-mysql:
minio-data:
minio-certs:
7 changes: 6 additions & 1 deletion packages/local-docker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@
"dev": "pnpm docker:up",
"docker:up": "docker compose up -d --wait",
"docker:stop": "docker compose stop",
"docker:clean": "docker compose down -v"
"docker:clean": "docker compose down -v",
"test": "vitest run"
},
"engines": {
"node": ">=20"
},
"devDependencies": {
"vitest": "~2.1.9",
"yaml": "^2.8.1"
}
}
8 changes: 8 additions & 0 deletions packages/local-docker/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
environment: "node",
include: ["**/*.test.ts"],
},
});
9 changes: 8 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.