More work on fixing Docker build

This commit is contained in:
Jesse Wierzbinski 2024-04-06 22:56:15 -10:00
parent 015177e3a2
commit ea1d7b1510
No known key found for this signature in database
9 changed files with 163 additions and 145 deletions

View file

@ -1,6 +1,6 @@
# Use the official Bun image (Bun doesn't run well on Musl but this seems to work)
# See all versions at https://hub.docker.com/r/oven/bun/tags
FROM oven/bun:1.1.2-alpine as base
FROM imbios/bun-node:1.1.2-current-alpine as base
# Install dependencies into temp directory
# This will cache them and speed up future builds
@ -14,9 +14,6 @@ RUN bun install --frozen-lockfile
FROM base as build
# Required for Prisma to work
# COPY --from=node:18-alpine /usr/local/bin/node /usr/local/bin/node
# Copy the project
RUN mkdir -p /temp
COPY . /temp
@ -24,10 +21,11 @@ COPY . /temp
COPY --from=install /temp/node_modules /temp/node_modules
# Build the project
WORKDIR /temp
RUN bunx --bun prisma generate
RUN bun run prod-build
# copy production dependencies and source code into final image
FROM base AS release
FROM oven/bun:1.1.2-alpine
# Create app directory
RUN mkdir -p /app
@ -44,5 +42,6 @@ LABEL org.opencontainers.image.description "Lysand Server docker image"
# CD to app
WORKDIR /app
ENV NODE_ENV=production
ENTRYPOINT [ "/bin/sh", "entrypoint.sh" ]
# Run migrations and start the server
CMD [ "./entrypoint.sh" "start" ]
CMD [ "start" ]

View file

@ -1,4 +1,5 @@
// Delete dist directory
import { $ } from "bun";
import { cp, exists, mkdir, rm } from "node:fs/promises";
import { rawRoutes } from "~routes";
@ -13,7 +14,6 @@ await rm("./dist", { recursive: true });
await mkdir(`${process.cwd()}/dist`);
//bun build --entrypoints ./index.ts ./prisma.ts ./cli.ts --outdir dist --target bun --splitting --minify --external bullmq,@prisma/client
await Bun.build({
entrypoints: [
`${process.cwd()}/index.ts`,
@ -25,7 +25,7 @@ await Bun.build({
outdir: `${process.cwd()}/dist`,
target: "bun",
splitting: true,
minify: true,
minify: false,
external: ["bullmq"],
}).then((output) => {
if (!output.success) {
@ -33,6 +33,10 @@ await Bun.build({
}
});
// Fix for wrong Bun file resolution, replaces node_modules with ./node_modules inside all dynamic imports
// I apologize for this
await $`sed -i 's|import("node_modules/|import("./node_modules/|g' dist/*.js`;
// Create pages directory
// mkdir ./dist/pages
await mkdir(`${process.cwd()}/dist/pages`);

BIN
bun.lockb

Binary file not shown.

View file

@ -9,23 +9,25 @@
# Exit immediately if a command exits with a non-zero status.
set -e
cd ./dist
# Parse first argument
case "$1" in
"start")
# Start the server
exec bun run ./dist/index.js --prod
exec bun run ./index.js --prod
;;
"cli")
# Start the CLI
shift 1
exec bun run ./dist/cli.js "$@"
exec bun run ./cli.js "$@"
;;
"prisma")
# Proxy all Prisma commands
# Use output of dist/prisma.js to get the env variable
shift 1
# Set DATABASE_URL env variable to the output of bun run ./dist/prisma.js
export DATABASE_URL=$(bun run ./dist/prisma.js)
export DATABASE_URL=$(bun run ./prisma.js)
# Execute the Prisma binary
exec bunx prisma "$@"
;;

View file

@ -1,4 +1,5 @@
import { exists, mkdir } from "node:fs/promises";
import { exists, mkdir, writeFile } from "node:fs/promises";
import { dirname } from "node:path";
import { connectMeili } from "@meilisearch";
import { moduleIsEntry } from "@module";
import type { PrismaClientInitializationError } from "@prisma/client/runtime/library";
@ -10,7 +11,18 @@ import { createServer } from "~server";
const timeAtStart = performance.now();
const requests_log = Bun.file(`${process.cwd()}/logs/requests.log`);
// Create requests file if it doesnt exist
if (
!(await exists(
`${process.cwd()}/${dirname(config.logging.storage.requests)}`,
))
) {
await mkdir(`${process.cwd()}/${dirname(config.logging.storage.requests)}`);
await writeFile(`${process.cwd()}/${config.logging.storage.requests}`, "");
}
const requests_log = Bun.file(
`${process.cwd()}/${config.logging.storage.requests}`,
);
const isEntry = moduleIsEntry(import.meta.url);
// If imported as a module, redirect logs to /dev/null to not pollute console (e.g. in tests)
const logger = new LogManager(isEntry ? requests_log : Bun.file("/dev/null"));
@ -19,16 +31,6 @@ const consoleLogger = new LogManager(
);
const dualLogger = new MultiLogManager([logger, consoleLogger]);
if (!(await exists(config.logging.storage.requests))) {
await consoleLogger.log(
LogLevel.WARNING,
"Lysand",
`Creating logs directory at ${process.cwd()}/logs/`,
);
await mkdir(`${process.cwd()}/logs/`);
}
await dualLogger.log(LogLevel.INFO, "Lysand", "Starting Lysand...");
// NODE_ENV seems to be broken and output `development` even when set to production, so use the flag instead

View file

@ -1,118 +1,118 @@
{
"name": "lysand",
"module": "index.ts",
"type": "module",
"version": "0.3.0",
"description": "A project to build a federated social network",
"author": {
"email": "contact@cpluspatch.com",
"name": "CPlusPatch",
"url": "https://cpluspatch.com"
},
"bugs": {
"url": "https://github.com/lysand-org/lysand/issues"
},
"icon": "https://github.com/lysand-org/lysand",
"license": "AGPL-3.0",
"keywords": ["federated", "activitypub", "bun"],
"workspaces": ["packages/*"],
"maintainers": [
{
"email": "contact@cpluspatch.com",
"name": "CPlusPatch",
"url": "https://cpluspatch.com"
"name": "lysand",
"module": "index.ts",
"type": "module",
"version": "0.3.0",
"description": "A project to build a federated social network",
"author": {
"email": "contact@cpluspatch.com",
"name": "CPlusPatch",
"url": "https://cpluspatch.com"
},
"bugs": {
"url": "https://github.com/lysand-org/lysand/issues"
},
"icon": "https://github.com/lysand-org/lysand",
"license": "AGPL-3.0",
"keywords": ["federated", "activitypub", "bun"],
"workspaces": ["packages/*"],
"maintainers": [
{
"email": "contact@cpluspatch.com",
"name": "CPlusPatch",
"url": "https://cpluspatch.com"
}
],
"repository": {
"type": "git",
"url": "git+https://github.com/lysand-org/lysand.git"
},
"private": true,
"scripts": {
"dev": "bun run --watch index.ts",
"vite:dev": "bunx --bun vite pages",
"vite:build": "bunx --bun vite build pages",
"start": "NODE_ENV=production bun run dist/index.js --prod",
"migrate-dev": "bun prisma migrate dev",
"migrate": "bun prisma migrate deploy",
"lint": "bunx --bun eslint --config .eslintrc.cjs --ext .ts .",
"prod-build": "bunx --bun vite build pages && bun run build.ts",
"prisma": "DATABASE_URL=$(bun run prisma.ts) bunx prisma",
"generate": "bun prisma generate",
"benchmark:timeline": "bun run benchmarks/timelines.ts",
"cloc": "cloc . --exclude-dir node_modules,dist",
"cli": "bun run cli.ts"
},
"trustedDependencies": [
"@biomejs/biome",
"@prisma/client",
"@prisma/engines",
"esbuild",
"prisma",
"sharp",
"msgpackr-extract"
],
"devDependencies": {
"@biomejs/biome": "1.6.4",
"@julr/unocss-preset-forms": "^0.1.0",
"@types/cli-table": "^0.3.4",
"@types/html-to-text": "^9.0.4",
"@types/ioredis": "^5.0.0",
"@types/jsonld": "^1.5.13",
"@typescript-eslint/eslint-plugin": "latest",
"@unocss/cli": "latest",
"@vitejs/plugin-vue": "latest",
"@vueuse/head": "^2.0.0",
"activitypub-types": "^1.0.3",
"bun-types": "latest",
"typescript": "latest",
"unocss": "latest",
"untyped": "^1.4.2",
"vite": "^5.2.8",
"vite-ssr": "^0.17.1",
"vue": "^3.3.9",
"vue-router": "^4.2.5",
"vue-tsc": "latest"
},
"peerDependencies": {
"typescript": "^5.3.2"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.461.0",
"@iarna/toml": "^2.2.5",
"@json2csv/plainjs": "^7.0.6",
"@prisma/client": "^5.6.0",
"blurhash": "^2.0.5",
"bullmq": "latest",
"chalk": "^5.3.0",
"cli-parser": "workspace:*",
"cli-table": "^0.3.11",
"config-manager": "workspace:*",
"eventemitter3": "^5.0.1",
"extract-zip": "^2.0.1",
"html-to-text": "^9.0.5",
"ioredis": "^5.3.2",
"ip-matching": "^2.1.2",
"iso-639-1": "^3.1.0",
"isomorphic-dompurify": "latest",
"jsonld": "^8.3.1",
"linkify-html": "^4.1.3",
"linkify-string": "^4.1.3",
"linkifyjs": "^4.1.3",
"log-manager": "workspace:*",
"marked": "latest",
"media-manager": "workspace:*",
"megalodon": "^10.0.0",
"meilisearch": "latest",
"merge-deep-ts": "^1.2.6",
"next-route-matcher": "^1.0.1",
"oauth4webapi": "^2.4.0",
"prisma": "^5.6.0",
"prisma-json-types-generator": "^3.0.4",
"prisma-redis-middleware": "^4.8.0",
"request-parser": "workspace:*",
"semver": "^7.5.4",
"sharp": "^0.33.0-rc.2",
"strip-ansi": "^7.1.0"
}
],
"repository": {
"type": "git",
"url": "git+https://github.com/lysand-org/lysand.git"
},
"private": true,
"scripts": {
"dev": "bun run --watch index.ts",
"vite:dev": "bunx --bun vite pages",
"vite:build": "bunx --bun vite build pages",
"start": "NODE_ENV=production bun run dist/index.js --prod",
"migrate-dev": "bun prisma migrate dev",
"migrate": "bun prisma migrate deploy",
"lint": "bunx --bun eslint --config .eslintrc.cjs --ext .ts .",
"prod-build": "bunx --bun vite build pages && bun run build.ts",
"prisma": "DATABASE_URL=$(bun run prisma.ts) bunx prisma",
"generate": "bun prisma generate",
"benchmark:timeline": "bun run benchmarks/timelines.ts",
"cloc": "cloc . --exclude-dir node_modules,dist",
"cli": "bun run cli.ts"
},
"trustedDependencies": [
"@biomejs/biome",
"@prisma/client",
"@prisma/engines",
"esbuild",
"prisma",
"sharp"
],
"devDependencies": {
"@biomejs/biome": "1.6.4",
"@julr/unocss-preset-forms": "^0.1.0",
"@types/cli-table": "^0.3.4",
"@types/html-to-text": "^9.0.4",
"@types/ioredis": "^5.0.0",
"@types/jsonld": "^1.5.13",
"@typescript-eslint/eslint-plugin": "latest",
"@unocss/cli": "latest",
"@vitejs/plugin-vue": "latest",
"@vueuse/head": "^2.0.0",
"activitypub-types": "^1.0.3",
"bun-types": "latest",
"typescript": "latest",
"unocss": "latest",
"untyped": "^1.4.2",
"vite": "^5.2.8",
"vite-ssr": "^0.17.1",
"vue": "^3.3.9",
"vue-router": "^4.2.5",
"vue-tsc": "latest"
},
"peerDependencies": {
"typescript": "^5.3.2"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.461.0",
"@iarna/toml": "^2.2.5",
"@json2csv/plainjs": "^7.0.6",
"@prisma/client": "^5.6.0",
"blurhash": "^2.0.5",
"bullmq": "latest",
"c12": "^1.10.0",
"chalk": "^5.3.0",
"cli-parser": "workspace:*",
"cli-table": "^0.3.11",
"config-manager": "workspace:*",
"eventemitter3": "^5.0.1",
"extract-zip": "^2.0.1",
"html-to-text": "^9.0.5",
"ioredis": "^5.3.2",
"ip-matching": "^2.1.2",
"iso-639-1": "^3.1.0",
"isomorphic-dompurify": "latest",
"jsonld": "^8.3.1",
"linkify-html": "^4.1.3",
"linkify-string": "^4.1.3",
"linkifyjs": "^4.1.3",
"log-manager": "workspace:*",
"marked": "latest",
"media-manager": "workspace:*",
"megalodon": "^10.0.0",
"meilisearch": "latest",
"merge-deep-ts": "^1.2.6",
"next-route-matcher": "^1.0.1",
"oauth4webapi": "^2.4.0",
"prisma": "^5.6.0",
"prisma-json-types-generator": "^3.0.4",
"prisma-redis-middleware": "^4.8.0",
"request-parser": "workspace:*",
"semver": "^7.5.4",
"sharp": "^0.33.0-rc.2",
"strip-ansi": "^7.1.0"
}
}

View file

@ -2,5 +2,9 @@
"name": "config-manager",
"version": "0.0.0",
"main": "index.ts",
"dependencies": { "@iarna/toml": "^2.2.5", "merge-deep-ts": "^1.2.6" }
"dependencies": {
"@iarna/toml": "^2.2.5",
"c12": "^1.10.0",
"merge-deep-ts": "^1.2.6"
}
}

View file

@ -1,4 +1,5 @@
import { appendFile } from "node:fs/promises";
import { appendFile, writeFile, mkdir, exists } from "node:fs/promises";
import { dirname } from "node:path";
import type { BunFile } from "bun";
export enum LogLevel {
@ -44,11 +45,17 @@ export class LogManager {
if (this.output === Bun.stdout) {
await Bun.write(Bun.stdout, `${text}\n`);
} else {
if (!(await this.output.exists())) {
if (!(await exists(this.output.name ?? ""))) {
// Create file if it doesn't exist
await Bun.write(this.output, "", {
createPath: true,
});
try {
await mkdir(dirname(this.output.name ?? ""), {
recursive: true,
});
await writeFile(this.output.name ?? "", "");
this.output = Bun.file(this.output.name ?? "");
} catch {
//
}
}
await appendFile(this.output.name ?? "", `${text}\n`);
}

View file

@ -1,7 +1,7 @@
generator client {
provider = "prisma-client-js"
previewFeatures = ["postgresqlExtensions"]
binaryTargets = ["native", "debian-openssl-3.0.x"]
binaryTargets = ["native"]
}
generator json {