chore: remove unused configuration files and submodules
This commit is contained in:
+1
-8
@@ -9,10 +9,7 @@ infra/
|
||||
├── compose/ # One compose file per stack/service
|
||||
│ ├── traefik.yml # Public reverse proxy
|
||||
│ ├── shared.yml # Shared Redis
|
||||
│ ├── react.yml # React SPA
|
||||
│ ├── scraper.yml # Scraper API
|
||||
│ ├── elysia.yml # Elysia API
|
||||
│ └── rust-auth.yml # Rust auth API
|
||||
│ └── scraper.yml # Scraper API
|
||||
├── docker/ # Dockerfiles and image runtime helpers
|
||||
├── traefik/ # Static and dynamic Traefik configuration
|
||||
│ ├── dynamic/ # Routers, services, middlewares, TLS certs
|
||||
@@ -41,10 +38,7 @@ docker compose -f infra/compose/shared.yml up -d
|
||||
docker compose -f infra/compose/traefik.yml up -d
|
||||
|
||||
docker compose \
|
||||
-f infra/compose/react.yml \
|
||||
-f infra/compose/scraper.yml \
|
||||
-f infra/compose/elysia.yml \
|
||||
-f infra/compose/rust-auth.yml \
|
||||
up -d
|
||||
```
|
||||
|
||||
@@ -55,7 +49,6 @@ Common variables used by infra compose files:
|
||||
```env
|
||||
DATABASE_URL=
|
||||
GITHUB_TOKEN=
|
||||
JWT_SECRET=
|
||||
SHARED_REDIS_EXPOSE=127.0.0.1:6379:6379
|
||||
```
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
services:
|
||||
elysia-api:
|
||||
container_name: elysia-api
|
||||
image: ghcr.io/asepharyana/asepharyana-hub/elysia-api:sha-fe998aa
|
||||
restart: always
|
||||
networks:
|
||||
app-shared-net:
|
||||
aliases:
|
||||
- elysia-api
|
||||
env_file:
|
||||
- ../../.env
|
||||
environment:
|
||||
- REDIS_URL=redis://redis:6379
|
||||
- JWT_SECRET=${JWT_SECRET:?JWT_SECRET is required}
|
||||
- DATABASE_URL=${DATABASE_URL}
|
||||
- GITHUB_TOKEN=${GITHUB_TOKEN}
|
||||
- PORT=4092
|
||||
- OTEL_EXPORTER_OTLP_ENDPOINT=http://otlp-metrics-backend:4317
|
||||
- OTEL_SERVICE_NAME=elysia-api
|
||||
|
||||
networks:
|
||||
app-shared-net:
|
||||
name: app-shared-net
|
||||
external: true
|
||||
@@ -1,13 +0,0 @@
|
||||
services:
|
||||
react-web:
|
||||
container_name: react-web
|
||||
image: ghcr.io/asepharyana/asepharyana-hub/react-web:sha-124223c
|
||||
restart: always
|
||||
networks: [app-shared-net]
|
||||
environment:
|
||||
- VITE_API_URL=https://scraper.asepharyana.my.id/api
|
||||
- VITE_ELYSIA_URL=https://elysia.asepharyana.my.id
|
||||
networks:
|
||||
app-shared-net:
|
||||
name: app-shared-net
|
||||
external: true
|
||||
@@ -1,20 +0,0 @@
|
||||
services:
|
||||
rust-auth:
|
||||
container_name: rust-auth-api
|
||||
image: ghcr.io/asepharyana/asepharyana-hub/rust-auth:sha-b199f8c
|
||||
restart: always
|
||||
networks:
|
||||
app-shared-net:
|
||||
aliases:
|
||||
- rust-auth
|
||||
env_file:
|
||||
- ../../.env
|
||||
environment:
|
||||
- PORT=3000
|
||||
- OTEL_EXPORTER_OTLP_ENDPOINT=http://otlp-metrics-backend:4317
|
||||
- OTEL_SERVICE_NAME=rust-auth
|
||||
|
||||
networks:
|
||||
app-shared-net:
|
||||
name: app-shared-net
|
||||
external: true
|
||||
@@ -1,26 +0,0 @@
|
||||
# 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
-77
@@ -1,77 +0,0 @@
|
||||
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 });
|
||||
},
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
# ─── 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"]
|
||||
@@ -1,42 +0,0 @@
|
||||
# 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"]
|
||||
@@ -1,13 +1,5 @@
|
||||
http:
|
||||
routers:
|
||||
# ── React SPA (domain root) ──
|
||||
react:
|
||||
rule: 'Host(`asepharyana.my.id`) || Host(`asepharyana.web.id`)'
|
||||
entryPoints:
|
||||
- websecure
|
||||
tls: {}
|
||||
service: react-service
|
||||
|
||||
# ── Scraper API ──
|
||||
scraper:
|
||||
rule: 'Host(`scraper.asepharyana.my.id`) || Host(`api.asepharyana.my.id`) || Host(`scraper.asepharyana.web.id`) || Host(`api.asepharyana.web.id`)'
|
||||
@@ -18,40 +10,8 @@ http:
|
||||
- common-chain@file
|
||||
service: scraper-service
|
||||
|
||||
# ── Elysia API ──
|
||||
elysia:
|
||||
rule: 'Host(`elysia.asepharyana.my.id`) || Host(`elysia.asepharyana.web.id`)'
|
||||
entryPoints:
|
||||
- websecure
|
||||
tls: {}
|
||||
middlewares:
|
||||
- common-chain@file
|
||||
service: elysia-service
|
||||
|
||||
# ── Rust Auth API ──
|
||||
rust-auth:
|
||||
rule: 'Host(`auth.asepharyana.my.id`) || Host(`auth.asepharyana.web.id`)'
|
||||
entryPoints:
|
||||
- websecure
|
||||
tls: {}
|
||||
middlewares:
|
||||
- common-chain@file
|
||||
service: rust-auth-service
|
||||
|
||||
services:
|
||||
react-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: 'http://react-web:80'
|
||||
scraper-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: 'http://scraper-api:4091'
|
||||
elysia-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: 'http://elysia-api:4092'
|
||||
rust-auth-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: 'http://rust-auth:3000'
|
||||
|
||||
Reference in New Issue
Block a user