From 063991770a438fc6a7dcda7ed51a9138e5074ff5 Mon Sep 17 00:00:00 2001 From: Jose Selesan Date: Thu, 9 Apr 2026 10:43:19 -0300 Subject: [PATCH] Changed Dockerfile --- apps/backend/Dockerfile | 12 +++ apps/backend/src/register-routes.ts | 21 ++++ apps/frontend/Dockerfile | 37 ------- apps/frontend/src/lib/api-client.ts | 4 +- packages/api-contract/src/index.ts | 2 +- packages/api-contract/src/register-routes.ts | 102 ++++--------------- 6 files changed, 57 insertions(+), 121 deletions(-) delete mode 100644 apps/frontend/Dockerfile diff --git a/apps/backend/Dockerfile b/apps/backend/Dockerfile index 574f8ff..bcc4483 100644 --- a/apps/backend/Dockerfile +++ b/apps/backend/Dockerfile @@ -6,6 +6,7 @@ WORKDIR /app # Workspace manifests first for better layer caching. COPY package.json bun.lock ./ COPY apps/backend/package.json apps/backend/package.json +COPY apps/frontend/package.json apps/frontend/package.json COPY packages/api-contract/package.json packages/api-contract/package.json RUN bun install --frozen-lockfile @@ -14,12 +15,23 @@ FROM deps AS build WORKDIR /app COPY apps/backend apps/backend +COPY apps/frontend apps/frontend COPY packages/api-contract packages/api-contract +# Build-time variables for Vite. +ARG VITE_API_BASE_URL +ARG VITE_SUPABASE_URL +ARG VITE_SUPABASE_ANON_KEY +ENV VITE_API_BASE_URL=${VITE_API_BASE_URL} +ENV VITE_SUPABASE_URL=${VITE_SUPABASE_URL} +ENV VITE_SUPABASE_ANON_KEY=${VITE_SUPABASE_ANON_KEY} + # Prisma 7 config resolves DATABASE_URL at generate time. ARG DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres ENV DATABASE_URL=${DATABASE_URL} +RUN bun --filter frontend build +RUN mkdir -p apps/backend/public && cp -R apps/frontend/dist/. apps/backend/public/ RUN bun --cwd apps/backend run prisma:generate FROM oven/bun:1.3-slim AS runner diff --git a/apps/backend/src/register-routes.ts b/apps/backend/src/register-routes.ts index de34b57..a3b8b76 100644 --- a/apps/backend/src/register-routes.ts +++ b/apps/backend/src/register-routes.ts @@ -1,5 +1,7 @@ import { registerApiRoutes } from '@repo/api-contract' import type { Hono } from 'hono' +import { serveStatic } from 'hono/bun' +import path from 'node:path' import { complexRoutes } from '@/modules/complex/complex.routes' import { courtRoutes } from '@/modules/court/court.routes' import { onboardingRoutes } from '@/modules/onboarding/onboarding.routes' @@ -20,4 +22,23 @@ export function registerRoutes(app: Hono) { }) app.route('/api/public-bookings', publicBookingRoutes) + + app.use('*', serveStatic({ root: './public' })) + app.get('*', async (c) => { + if (c.req.path === '/api' || c.req.path.startsWith('/api/')) { + return c.notFound() + } + + // Keep real asset URLs as 404s if the file does not exist. + if (path.extname(c.req.path)) { + return c.notFound() + } + + const indexFile = Bun.file('./public/index.html') + if (!(await indexFile.exists())) { + return c.notFound() + } + + return c.html(await indexFile.text()) + }) } diff --git a/apps/frontend/Dockerfile b/apps/frontend/Dockerfile deleted file mode 100644 index f34259a..0000000 --- a/apps/frontend/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -# syntax=docker/dockerfile:1.7 - -FROM oven/bun:1.3 AS deps -WORKDIR /app - -# Workspace manifests first for better layer caching. -COPY package.json bun.lock ./ -COPY apps/frontend/package.json apps/frontend/package.json -COPY packages/api-contract/package.json packages/api-contract/package.json - -RUN bun install --frozen-lockfile - -FROM deps AS build -WORKDIR /app - -COPY apps/frontend apps/frontend -COPY packages/api-contract packages/api-contract - -# Build-time variables for Vite. -ARG VITE_API_BASE_URL=http://localhost:3000 -ARG VITE_SUPABASE_URL= -ARG VITE_SUPABASE_ANON_KEY= -ENV VITE_API_BASE_URL=${VITE_API_BASE_URL} -ENV VITE_SUPABASE_URL=${VITE_SUPABASE_URL} -ENV VITE_SUPABASE_ANON_KEY=${VITE_SUPABASE_ANON_KEY} - -RUN bun --filter frontend build - -FROM nginx:1.27-alpine AS runner -WORKDIR /usr/share/nginx/html - -COPY apps/frontend/nginx.conf /etc/nginx/conf.d/default.conf -COPY --from=build /app/apps/frontend/dist ./ - -EXPOSE 80 - -CMD ["nginx", "-g", "daemon off;"] diff --git a/apps/frontend/src/lib/api-client.ts b/apps/frontend/src/lib/api-client.ts index ad9ed04..a8b770a 100644 --- a/apps/frontend/src/lib/api-client.ts +++ b/apps/frontend/src/lib/api-client.ts @@ -27,7 +27,9 @@ import type { UserProfileResponse, } from '@repo/api-contract' -const apiBaseUrl = import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:3000' +const apiBaseUrl = + import.meta.env.VITE_API_BASE_URL?.trim() || + (import.meta.env.DEV ? 'http://localhost:3000' : window.location.origin) let accessToken: string | null = null export class ApiClientError extends Error { diff --git a/packages/api-contract/src/index.ts b/packages/api-contract/src/index.ts index e2133cd..2c88e43 100644 --- a/packages/api-contract/src/index.ts +++ b/packages/api-contract/src/index.ts @@ -1,4 +1,4 @@ -export { API_ROUTE_PATHS, registerApiRoutes } from './register-routes' +export { API_ROUTES, API_ROUTE_PATHS, registerApiRoutes } from './register-routes' export { planFeatureFlagsSchema, planRulesSchema, diff --git a/packages/api-contract/src/register-routes.ts b/packages/api-contract/src/register-routes.ts index d72cc0b..f2da9e7 100644 --- a/packages/api-contract/src/register-routes.ts +++ b/packages/api-contract/src/register-routes.ts @@ -1,37 +1,15 @@ -import type { Env, Hono, Schema } from 'hono' +import type { Hono } from 'hono' -type HonoLike = - Hono - -type ApiRouteModules< - UE extends Env = Env, - US extends Schema = Schema, - UB extends string = string, - PLE extends Env = Env, - PLS extends Schema = Schema, - PLB extends string = string, - OE extends Env = Env, - OS extends Schema = Schema, - OB extends string = string, - CE extends Env = Env, - CS extends Schema = Schema, - CB extends string = string, - SPE extends Env = Env, - SPS extends Schema = Schema, - SPB extends string = string, - COE extends Env = Env, - COS extends Schema = Schema, - COB extends string = string, -> = { - user: HonoLike - plans: HonoLike - onboarding: HonoLike - complexes: HonoLike - sports: HonoLike - courts: HonoLike +type ApiRouteModules = { + user: Hono + plans: Hono + onboarding: Hono + complexes: Hono + sports: Hono + courts: Hono } -export const API_ROUTE_PATHS = { +export const API_ROUTES = { user: '/api/user', plans: '/api/plans', onboarding: '/api/onboarding', @@ -40,56 +18,16 @@ export const API_ROUTE_PATHS = { courts: '/api/courts', } as const -export function registerApiRoutes< - E extends Env, - S extends Schema, - B extends string, - UE extends Env, - US extends Schema, - UB extends string, - PLE extends Env, - PLS extends Schema, - PLB extends string, - OE extends Env, - OS extends Schema, - OB extends string, - CE extends Env, - CS extends Schema, - CB extends string, - SPE extends Env, - SPS extends Schema, - SPB extends string, - COE extends Env, - COS extends Schema, - COB extends string, ->( - app: HonoLike, - modules: ApiRouteModules< - UE, - US, - UB, - PLE, - PLS, - PLB, - OE, - OS, - OB, - CE, - CS, - CB, - SPE, - SPS, - SPB, - COE, - COS, - COB - >, -) { +// Backward-compatible alias for previous name. +export const API_ROUTE_PATHS = API_ROUTES + +// Registers all backend API route modules under their `/api/*` prefixes. +export function registerApiRoutes(app: Hono, modules: ApiRouteModules) { return app - .route(API_ROUTE_PATHS.user, modules.user) - .route(API_ROUTE_PATHS.plans, modules.plans) - .route(API_ROUTE_PATHS.onboarding, modules.onboarding) - .route(API_ROUTE_PATHS.complexes, modules.complexes) - .route(API_ROUTE_PATHS.sports, modules.sports) - .route(API_ROUTE_PATHS.courts, modules.courts) + .route(API_ROUTES.user, modules.user) + .route(API_ROUTES.plans, modules.plans) + .route(API_ROUTES.onboarding, modules.onboarding) + .route(API_ROUTES.complexes, modules.complexes) + .route(API_ROUTES.sports, modules.sports) + .route(API_ROUTES.courts, modules.courts) }