refactor: simplify Docker environment detection for file storage paths (#77)

This commit is contained in:
Daniel Luiz Alves
2025-06-19 03:02:31 -03:00
committed by GitHub
3 changed files with 54 additions and 46 deletions

View File

@@ -1,5 +1,6 @@
import { env } from "../env";
import { StorageProvider } from "../types/storage";
import { IS_RUNNING_IN_CONTAINER } from "../utils/container-detection";
import * as crypto from "crypto";
import * as fsSync from "fs";
import * as fs from "fs/promises";
@@ -15,25 +16,12 @@ export class FilesystemStorageProvider implements StorageProvider {
private downloadTokens = new Map<string, { objectName: string; expiresAt: number; fileName?: string }>();
private constructor() {
this.uploadsDir = this.isDocker() ? "/app/server/uploads" : path.join(process.cwd(), "uploads");
this.uploadsDir = IS_RUNNING_IN_CONTAINER ? "/app/server/uploads" : path.join(process.cwd(), "uploads");
this.ensureUploadsDir();
setInterval(() => this.cleanExpiredTokens(), 5 * 60 * 1000);
}
private isDocker(): boolean {
try {
fsSync.statSync("/.dockerenv");
return true;
} catch {
try {
return fsSync.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
} catch {
return false;
}
}
}
public static getInstance(): FilesystemStorageProvider {
if (!FilesystemStorageProvider.instance) {
FilesystemStorageProvider.instance = new FilesystemStorageProvider();
@@ -229,8 +217,10 @@ export class FilesystemStorageProvider implements StorageProvider {
if (encryptedBuffer.length > 16) {
try {
return this.decryptFileBuffer(encryptedBuffer);
} catch (error) {
console.warn("Failed to decrypt with new method, trying legacy format");
} catch (error: unknown) {
if (error instanceof Error) {
console.warn("Failed to decrypt with new method, trying legacy format", error.message);
}
return this.decryptFileLegacy(encryptedBuffer);
}
}

View File

@@ -11,9 +11,9 @@ import { reverseShareRoutes } from "./modules/reverse-share/routes";
import { shareRoutes } from "./modules/share/routes";
import { storageRoutes } from "./modules/storage/routes";
import { userRoutes } from "./modules/user/routes";
import { IS_RUNNING_IN_CONTAINER } from "./utils/container-detection";
import fastifyMultipart from "@fastify/multipart";
import fastifyStatic from "@fastify/static";
import * as fsSync from "fs";
import * as fs from "fs/promises";
import crypto from "node:crypto";
import path from "path";
@@ -27,21 +27,7 @@ if (typeof global.crypto === "undefined") {
}
async function ensureDirectories() {
// Use /app/server paths in Docker, current directory for local development
const isDocker = (() => {
try {
fsSync.statSync("/.dockerenv");
return true;
} catch {
try {
return fsSync.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
} catch {
return false;
}
}
})();
const baseDir = isDocker ? "/app/server" : process.cwd();
const baseDir = IS_RUNNING_IN_CONTAINER ? "/app/server" : process.cwd();
const uploadsDir = path.join(baseDir, "uploads");
const tempChunksDir = path.join(baseDir, "temp-chunks");
@@ -78,20 +64,7 @@ async function startServer() {
});
if (env.ENABLE_S3 !== "true") {
const isDocker = (() => {
try {
fsSync.statSync("/.dockerenv");
return true;
} catch {
try {
return fsSync.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
} catch {
return false;
}
}
})();
const baseDir = isDocker ? "/app/server" : process.cwd();
const baseDir = IS_RUNNING_IN_CONTAINER ? "/app/server" : process.cwd();
const uploadsPath = path.join(baseDir, "uploads");
await app.register(fastifyStatic, {

View File

@@ -0,0 +1,45 @@
import * as fsSync from "fs";
/**
* Determines if the application is running inside a container environment.
* Checks common container indicators like /.dockerenv and cgroup file patterns.
*
* This function caches its result after the first call for performance.
*
* @returns {boolean} True if running in a container, false otherwise.
*/
function isRunningInContainer(): boolean {
try {
if (fsSync.existsSync("/.dockerenv")) {
return true;
}
const cgroupContent = fsSync.readFileSync("/proc/self/cgroup", "utf8");
const containerPatterns = [
"docker",
"containerd",
"lxc",
"kubepods",
"pod",
"/containers/",
"system.slice/container-",
];
for (const pattern of containerPatterns) {
if (cgroupContent.includes(pattern)) {
return true;
}
}
if (fsSync.existsSync("/.well-known/container")) {
return true;
}
} catch (e: unknown) {
if (e instanceof Error) {
console.warn("Could not perform full container detection:", e.message);
}
}
return false;
}
export const IS_RUNNING_IN_CONTAINER = isRunningInContainer();