mirror of
https://github.com/yamadashy/repomix.git
synced 2025-06-11 00:25:54 +03:00
Merge pull request #640 from yamadashy/feat/docker-slim
feat(website): Optimize Docker infrastructure and reduce resource usage
This commit is contained in:
3
website/client/package-lock.json
generated
3
website/client/package-lock.json
generated
@@ -1,9 +1,10 @@
|
||||
{
|
||||
"name": "app",
|
||||
"name": "repomix-website-client",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "repomix-website-client",
|
||||
"dependencies": {
|
||||
"jszip": "^3.10.1",
|
||||
"lucide-vue-next": "^0.474.0",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"name": "repomix-website-client",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
# ==============================================================================
|
||||
# Base image
|
||||
# ==============================================================================
|
||||
FROM node:23-alpine AS builder
|
||||
|
||||
# Install git and other dependencies
|
||||
RUN apk add --no-cache \
|
||||
git \
|
||||
ca-certificates
|
||||
FROM node:24-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm i
|
||||
# Install all dependencies (including dev dependencies for build)
|
||||
RUN npm ci
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
@@ -21,33 +16,46 @@ COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# ==============================================================================
|
||||
# Production image
|
||||
# Production dependencies
|
||||
# ==============================================================================
|
||||
FROM node:23-alpine
|
||||
FROM node:24-alpine AS deps
|
||||
|
||||
# Install git and other dependencies
|
||||
RUN apk add --no-cache \
|
||||
git \
|
||||
ca-certificates \
|
||||
curl
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
|
||||
# Install only production dependencies
|
||||
RUN npm ci --only=production --ignore-scripts && \
|
||||
npm cache clean --force
|
||||
|
||||
# ==============================================================================
|
||||
# Runtime image
|
||||
# ==============================================================================
|
||||
FROM node:24-alpine
|
||||
|
||||
# Install git and ca-certificates (required by repomix for remote repository processing)
|
||||
RUN apk add --no-cache git ca-certificates
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1001 -S nodejs && \
|
||||
adduser -S nodejs -u 1001
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy only necessary files
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/package*.json ./
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
# Copy built application
|
||||
COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
|
||||
|
||||
# Copy production dependencies
|
||||
COPY --from=deps --chown=nodejs:nodejs /app/node_modules ./node_modules
|
||||
|
||||
# Set environment variables
|
||||
ENV NODE_ENV=production \
|
||||
PORT=8080
|
||||
|
||||
# Switch to non-root user
|
||||
USER nodejs
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8080
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost:8080/health || exit 1
|
||||
|
||||
# Start the server
|
||||
CMD ["npm", "start"]
|
||||
# Start the server directly
|
||||
CMD ["node", "dist/index.js"]
|
||||
|
||||
@@ -38,13 +38,13 @@ steps:
|
||||
- '--memory'
|
||||
- '2048Mi'
|
||||
- '--cpu'
|
||||
- '4'
|
||||
- '2'
|
||||
- '--min-instances'
|
||||
- '0'
|
||||
- '--max-instances'
|
||||
- '10'
|
||||
- '--timeout'
|
||||
- '35s'
|
||||
- '31s'
|
||||
- '--ingress'
|
||||
- 'all'
|
||||
- '--allow-unauthenticated'
|
||||
|
||||
24
website/server/package-lock.json
generated
24
website/server/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "app",
|
||||
"name": "repomix-website-server",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "repomix-website-server",
|
||||
"dependencies": {
|
||||
"@google-cloud/logging-winston": "^6.0.0",
|
||||
"@hono/node-server": "^1.13.8",
|
||||
"adm-zip": "^0.5.16",
|
||||
"hono": "^4.6.20",
|
||||
"pako": "^2.1.0",
|
||||
"repomix": "^0.3.7",
|
||||
"winston": "^3.17.0",
|
||||
"zod": "^3.24.1"
|
||||
@@ -17,7 +17,6 @@
|
||||
"devDependencies": {
|
||||
"@types/adm-zip": "^0.5.7",
|
||||
"@types/node": "^22.13.0",
|
||||
"@types/pako": "^2.0.3",
|
||||
"rimraf": "^6.0.1",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.7.3"
|
||||
@@ -1183,13 +1182,6 @@
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/pako": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/pako/-/pako-2.0.3.tgz",
|
||||
"integrity": "sha512-bq0hMV9opAcrmE0Byyo0fY3Ew4tgOevJmQ9grUhpXQhYfyLJ1Kqg3P33JT5fdbT2AjeAjR51zqqVjAL/HMkx7Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/parse-path": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-path/-/parse-path-7.0.3.tgz",
|
||||
@@ -3427,12 +3419,6 @@
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0"
|
||||
},
|
||||
"node_modules/pako": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
|
||||
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==",
|
||||
"license": "(MIT AND Zlib)"
|
||||
},
|
||||
"node_modules/parse-path": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz",
|
||||
@@ -3706,9 +3692,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/repomix": {
|
||||
"version": "0.3.7",
|
||||
"resolved": "https://registry.npmjs.org/repomix/-/repomix-0.3.7.tgz",
|
||||
"integrity": "sha512-/b0DKC6MIVVsjcJTkTiWRwNwJwx0u+1Ph1LMEKkID5txN6mhHUFXuHdyF1ZDklyjlWzEEt6gOBWMzc3sJB+s/Q==",
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/repomix/-/repomix-0.3.9.tgz",
|
||||
"integrity": "sha512-Olo/vORZChL98HOC3tZaE5+kwSaoox8KoF9N+lfQRb7dWT4qNa/SLFHT40Xq54cbZ7l9qTIZhXWmU1d/AtwqGQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@clack/prompts": "^0.10.1",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"name": "repomix-website-server",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -15,7 +16,6 @@
|
||||
"@hono/node-server": "^1.13.8",
|
||||
"adm-zip": "^0.5.16",
|
||||
"hono": "^4.6.20",
|
||||
"pako": "^2.1.0",
|
||||
"repomix": "^0.3.7",
|
||||
"winston": "^3.17.0",
|
||||
"zod": "^3.24.1"
|
||||
@@ -23,7 +23,6 @@
|
||||
"devDependencies": {
|
||||
"@types/adm-zip": "^0.5.7",
|
||||
"@types/node": "^22.13.0",
|
||||
"@types/pako": "^2.0.3",
|
||||
"rimraf": "^6.0.1",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.7.3"
|
||||
|
||||
@@ -54,7 +54,7 @@ export async function processZipFile(
|
||||
);
|
||||
|
||||
// Check if the result is already cached
|
||||
const cachedResult = cache.get(cacheKey);
|
||||
const cachedResult = await cache.get(cacheKey);
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
@@ -123,7 +123,7 @@ export async function processZipFile(
|
||||
};
|
||||
|
||||
// Save the result to cache
|
||||
cache.set(cacheKey, packResultData);
|
||||
await cache.set(cacheKey, packResultData);
|
||||
|
||||
return packResultData;
|
||||
} catch (error) {
|
||||
|
||||
@@ -35,7 +35,7 @@ export async function processRemoteRepo(
|
||||
const cacheKey = generateCacheKey(validatedData.url, validatedData.format, validatedData.options, 'url');
|
||||
|
||||
// Check if the result is already cached
|
||||
const cachedResult = cache.get(cacheKey);
|
||||
const cachedResult = await cache.get(cacheKey);
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
@@ -100,7 +100,7 @@ export async function processRemoteRepo(
|
||||
};
|
||||
|
||||
// Save the result to cache
|
||||
cache.set(cacheKey, packResultData);
|
||||
await cache.set(cacheKey, packResultData);
|
||||
|
||||
return packResultData;
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import pako from 'pako';
|
||||
import { promisify } from 'node:util';
|
||||
import * as zlib from 'node:zlib';
|
||||
import type { PackOptions } from '../types.js';
|
||||
|
||||
interface CacheEntry<T> {
|
||||
const inflateAsync = promisify(zlib.inflate);
|
||||
const deflateAsync = promisify(zlib.deflate);
|
||||
|
||||
interface CacheEntry {
|
||||
value: Uint8Array; // Compressed data
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
export class RequestCache<T> {
|
||||
private cache: Map<string, CacheEntry<T>> = new Map();
|
||||
private cache: Map<string, CacheEntry> = new Map();
|
||||
private readonly ttl: number;
|
||||
|
||||
constructor(ttlInSeconds = 60) {
|
||||
@@ -17,7 +21,7 @@ export class RequestCache<T> {
|
||||
setInterval(() => this.cleanup(), ttlInSeconds * 1000);
|
||||
}
|
||||
|
||||
get(key: string): T | undefined {
|
||||
async get(key: string): Promise<T | undefined> {
|
||||
const entry = this.cache.get(key);
|
||||
if (!entry) {
|
||||
return undefined;
|
||||
@@ -31,8 +35,8 @@ export class RequestCache<T> {
|
||||
|
||||
try {
|
||||
// Decompress and return the data
|
||||
const decompressedData = pako.inflate(entry.value, { to: 'string' });
|
||||
return JSON.parse(decompressedData);
|
||||
const decompressedData = await inflateAsync(entry.value);
|
||||
return JSON.parse(decompressedData.toString('utf8'));
|
||||
} catch (error) {
|
||||
console.error('Error decompressing cache entry:', error);
|
||||
this.cache.delete(key);
|
||||
@@ -40,11 +44,11 @@ export class RequestCache<T> {
|
||||
}
|
||||
}
|
||||
|
||||
set(key: string, value: T): void {
|
||||
async set(key: string, value: T): Promise<void> {
|
||||
try {
|
||||
// Convert data to JSON string and compress
|
||||
const jsonString = JSON.stringify(value);
|
||||
const compressedData = pako.deflate(jsonString);
|
||||
const compressedData = await deflateAsync(Buffer.from(jsonString, 'utf8'));
|
||||
|
||||
this.cache.set(key, {
|
||||
value: compressedData,
|
||||
|
||||
Reference in New Issue
Block a user