chore: initial hub repo structure
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
# build stage
|
||||
FROM oven/bun:1-alpine AS builder
|
||||
WORKDIR /app
|
||||
|
||||
# install dependencies with cache mounts
|
||||
COPY apps/elysia/package.json apps/elysia/bun.lock ./
|
||||
RUN --mount=type=cache,target=/root/.bun/install/cache \
|
||||
bun install --frozen-lockfile
|
||||
|
||||
# build the application
|
||||
COPY apps/elysia ./
|
||||
RUN bun run build
|
||||
|
||||
# runtime stage
|
||||
FROM oven/bun:1-distroless
|
||||
WORKDIR /app
|
||||
|
||||
# copy build artifacts
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/package.json ./
|
||||
|
||||
# distroless uses nonroot user (UID 65532) by default, or we can use it
|
||||
USER nonroot
|
||||
|
||||
EXPOSE 4092
|
||||
CMD ["run", "dist/index.js"]
|
||||
Vendored
+75
@@ -0,0 +1,75 @@
|
||||
import { existsSync, readFileSync } from "node:fs"
|
||||
import { resolve, sep } from "node:path"
|
||||
|
||||
const distDir = resolve("./dist")
|
||||
const indexPath = resolve(distDir, "index.html")
|
||||
|
||||
const contentTypes = {
|
||||
html: "text/html; charset=utf-8",
|
||||
css: "text/css; charset=utf-8",
|
||||
js: "application/javascript; charset=utf-8",
|
||||
json: "application/json; charset=utf-8",
|
||||
svg: "image/svg+xml",
|
||||
png: "image/png",
|
||||
jpg: "image/jpeg",
|
||||
jpeg: "image/jpeg",
|
||||
gif: "image/gif",
|
||||
webp: "image/webp",
|
||||
ico: "image/x-icon",
|
||||
woff: "font/woff",
|
||||
woff2: "font/woff2",
|
||||
ttf: "font/ttf",
|
||||
}
|
||||
|
||||
function responseFromFile(filePath, headers) {
|
||||
try {
|
||||
return new Response(readFileSync(filePath), { headers })
|
||||
} catch (error) {
|
||||
if (error?.code === "ENOENT") {
|
||||
return new Response("Not Found", { status: 404 })
|
||||
}
|
||||
|
||||
console.error("File read error:", error)
|
||||
return new Response("Internal Server Error", { status: 500 })
|
||||
}
|
||||
}
|
||||
|
||||
function serveIndex() {
|
||||
return responseFromFile(indexPath, {
|
||||
"Content-Type": contentTypes.html,
|
||||
"Cache-Control": "no-cache",
|
||||
})
|
||||
}
|
||||
|
||||
function serveFile(filePath, pathname) {
|
||||
const ext = filePath.split(".").pop() || ""
|
||||
return responseFromFile(filePath, {
|
||||
"Content-Type": contentTypes[ext] || "application/octet-stream",
|
||||
"Cache-Control": pathname.startsWith("/assets/") ? "public, max-age=31536000, immutable" : "no-cache",
|
||||
})
|
||||
}
|
||||
|
||||
Bun.serve({
|
||||
port: 80,
|
||||
hostname: "0.0.0.0",
|
||||
fetch(req) {
|
||||
const url = new URL(req.url)
|
||||
const pathname = url.pathname
|
||||
const filePath = resolve(distDir, pathname.slice(1))
|
||||
const insideDist = filePath === distDir || filePath.startsWith(`${distDir}${sep}`)
|
||||
|
||||
if (!insideDist) {
|
||||
return new Response("Forbidden", { status: 403 })
|
||||
}
|
||||
|
||||
if (pathname !== "/" && existsSync(filePath)) {
|
||||
return serveFile(filePath, pathname)
|
||||
}
|
||||
|
||||
if (!pathname.includes(".") && existsSync(indexPath)) {
|
||||
return serveIndex()
|
||||
}
|
||||
|
||||
return new Response("Not Found", { status: 404 })
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,16 @@
|
||||
# ─── Stage 1: Build ─────────────────────────────────────────────────────────
|
||||
FROM oven/bun:1 AS builder
|
||||
WORKDIR /app
|
||||
COPY apps/react/package.json apps/react/bun.lock ./
|
||||
RUN bun install --frozen-lockfile
|
||||
COPY apps/react .
|
||||
RUN bun run build
|
||||
|
||||
# ─── Stage 2: Runtime (Bun static server) ──────────────────────────────────
|
||||
FROM oven/bun:1-alpine
|
||||
WORKDIR /app
|
||||
COPY infra/docker/react-server.js ./server.js
|
||||
COPY --from=builder /app/dist ./dist
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["bun", "server.js"]
|
||||
@@ -0,0 +1,42 @@
|
||||
# Use cargo-chef for dependency caching
|
||||
FROM lukemathwalker/cargo-chef:latest-rust-1.89.0 AS chef
|
||||
WORKDIR /app
|
||||
|
||||
FROM chef AS planner
|
||||
COPY apps/rust-auth .
|
||||
RUN cargo chef prepare --recipe-path recipe.json
|
||||
|
||||
FROM chef AS builder
|
||||
COPY --from=planner /app/recipe.json recipe.json
|
||||
# Utilize buildkit cache mounts for cargo
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/app/target \
|
||||
cargo chef cook --release --recipe-path recipe.json
|
||||
|
||||
# Build application
|
||||
COPY apps/rust-auth .
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/app/target \
|
||||
cargo build --release && \
|
||||
cp target/release/rust-auth /app/rust-auth
|
||||
|
||||
# Final runtime image
|
||||
FROM debian:bookworm-slim AS runtime
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
libssl3 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Add non-root user
|
||||
RUN groupadd -g 1001 appgroup && \
|
||||
useradd -u 1001 -g appgroup -s /bin/sh appuser
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/rust-auth /app/rust-auth
|
||||
|
||||
# Run as non-root
|
||||
USER appuser
|
||||
|
||||
EXPOSE 3000
|
||||
CMD ["./rust-auth"]
|
||||
@@ -0,0 +1,50 @@
|
||||
# Use cargo-chef for dependency caching
|
||||
FROM lukemathwalker/cargo-chef:latest-rust-1.89.0 AS chef
|
||||
WORKDIR /app
|
||||
|
||||
# Install Node.js if needed for build scripts
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
FROM chef AS planner
|
||||
COPY apps/scraper .
|
||||
RUN cargo chef prepare --recipe-path recipe.json
|
||||
|
||||
FROM chef AS builder
|
||||
COPY --from=planner /app/recipe.json recipe.json
|
||||
# Utilize buildkit cache mounts for cargo
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/app/target \
|
||||
cargo chef cook --release --recipe-path recipe.json
|
||||
|
||||
# Build application
|
||||
COPY apps/scraper .
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/app/target \
|
||||
cargo build --release && \
|
||||
cp target/release/scraper /app/scraper
|
||||
|
||||
# Final runtime image
|
||||
FROM debian:bookworm-slim AS runtime
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
libssl3 \
|
||||
chromium \
|
||||
fonts-liberation \
|
||||
fonts-noto-color-emoji \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Add non-root user
|
||||
RUN groupadd -g 1001 appgroup && \
|
||||
useradd -u 1001 -g appgroup -s /bin/sh appuser
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/scraper /app/scraper
|
||||
|
||||
# Run as non-root
|
||||
USER appuser
|
||||
|
||||
EXPOSE 4091
|
||||
CMD ["./scraper"]
|
||||
Reference in New Issue
Block a user