Changed Dockerfile
This commit is contained in:
@@ -6,6 +6,7 @@ WORKDIR /app
|
|||||||
# Workspace manifests first for better layer caching.
|
# Workspace manifests first for better layer caching.
|
||||||
COPY package.json bun.lock ./
|
COPY package.json bun.lock ./
|
||||||
COPY apps/backend/package.json apps/backend/package.json
|
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
|
COPY packages/api-contract/package.json packages/api-contract/package.json
|
||||||
|
|
||||||
RUN bun install --frozen-lockfile
|
RUN bun install --frozen-lockfile
|
||||||
@@ -14,12 +15,23 @@ FROM deps AS build
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY apps/backend apps/backend
|
COPY apps/backend apps/backend
|
||||||
|
COPY apps/frontend apps/frontend
|
||||||
COPY packages/api-contract packages/api-contract
|
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.
|
# Prisma 7 config resolves DATABASE_URL at generate time.
|
||||||
ARG DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres
|
ARG DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres
|
||||||
ENV DATABASE_URL=${DATABASE_URL}
|
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
|
RUN bun --cwd apps/backend run prisma:generate
|
||||||
|
|
||||||
FROM oven/bun:1.3-slim AS runner
|
FROM oven/bun:1.3-slim AS runner
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { registerApiRoutes } from '@repo/api-contract'
|
import { registerApiRoutes } from '@repo/api-contract'
|
||||||
import type { Hono } from 'hono'
|
import type { Hono } from 'hono'
|
||||||
|
import { serveStatic } from 'hono/bun'
|
||||||
|
import path from 'node:path'
|
||||||
import { complexRoutes } from '@/modules/complex/complex.routes'
|
import { complexRoutes } from '@/modules/complex/complex.routes'
|
||||||
import { courtRoutes } from '@/modules/court/court.routes'
|
import { courtRoutes } from '@/modules/court/court.routes'
|
||||||
import { onboardingRoutes } from '@/modules/onboarding/onboarding.routes'
|
import { onboardingRoutes } from '@/modules/onboarding/onboarding.routes'
|
||||||
@@ -20,4 +22,23 @@ export function registerRoutes(app: Hono<AppEnv>) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
app.route('/api/public-bookings', publicBookingRoutes)
|
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())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;"]
|
|
||||||
@@ -27,7 +27,9 @@ import type {
|
|||||||
UserProfileResponse,
|
UserProfileResponse,
|
||||||
} from '@repo/api-contract'
|
} 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
|
let accessToken: string | null = null
|
||||||
|
|
||||||
export class ApiClientError extends Error {
|
export class ApiClientError extends Error {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export { API_ROUTE_PATHS, registerApiRoutes } from './register-routes'
|
export { API_ROUTES, API_ROUTE_PATHS, registerApiRoutes } from './register-routes'
|
||||||
export {
|
export {
|
||||||
planFeatureFlagsSchema,
|
planFeatureFlagsSchema,
|
||||||
planRulesSchema,
|
planRulesSchema,
|
||||||
|
|||||||
@@ -1,37 +1,15 @@
|
|||||||
import type { Env, Hono, Schema } from 'hono'
|
import type { Hono } from 'hono'
|
||||||
|
|
||||||
type HonoLike<E extends Env = Env, S extends Schema = Schema, B extends string = string> =
|
type ApiRouteModules = {
|
||||||
Hono<E, S, B>
|
user: Hono<any>
|
||||||
|
plans: Hono<any>
|
||||||
type ApiRouteModules<
|
onboarding: Hono<any>
|
||||||
UE extends Env = Env,
|
complexes: Hono<any>
|
||||||
US extends Schema = Schema,
|
sports: Hono<any>
|
||||||
UB extends string = string,
|
courts: Hono<any>
|
||||||
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<UE, US, UB>
|
|
||||||
plans: HonoLike<PLE, PLS, PLB>
|
|
||||||
onboarding: HonoLike<OE, OS, OB>
|
|
||||||
complexes: HonoLike<CE, CS, CB>
|
|
||||||
sports: HonoLike<SPE, SPS, SPB>
|
|
||||||
courts: HonoLike<COE, COS, COB>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const API_ROUTE_PATHS = {
|
export const API_ROUTES = {
|
||||||
user: '/api/user',
|
user: '/api/user',
|
||||||
plans: '/api/plans',
|
plans: '/api/plans',
|
||||||
onboarding: '/api/onboarding',
|
onboarding: '/api/onboarding',
|
||||||
@@ -40,56 +18,16 @@ export const API_ROUTE_PATHS = {
|
|||||||
courts: '/api/courts',
|
courts: '/api/courts',
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export function registerApiRoutes<
|
// Backward-compatible alias for previous name.
|
||||||
E extends Env,
|
export const API_ROUTE_PATHS = API_ROUTES
|
||||||
S extends Schema,
|
|
||||||
B extends string,
|
// Registers all backend API route modules under their `/api/*` prefixes.
|
||||||
UE extends Env,
|
export function registerApiRoutes(app: Hono<any>, modules: ApiRouteModules) {
|
||||||
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<E, S, B>,
|
|
||||||
modules: ApiRouteModules<
|
|
||||||
UE,
|
|
||||||
US,
|
|
||||||
UB,
|
|
||||||
PLE,
|
|
||||||
PLS,
|
|
||||||
PLB,
|
|
||||||
OE,
|
|
||||||
OS,
|
|
||||||
OB,
|
|
||||||
CE,
|
|
||||||
CS,
|
|
||||||
CB,
|
|
||||||
SPE,
|
|
||||||
SPS,
|
|
||||||
SPB,
|
|
||||||
COE,
|
|
||||||
COS,
|
|
||||||
COB
|
|
||||||
>,
|
|
||||||
) {
|
|
||||||
return app
|
return app
|
||||||
.route(API_ROUTE_PATHS.user, modules.user)
|
.route(API_ROUTES.user, modules.user)
|
||||||
.route(API_ROUTE_PATHS.plans, modules.plans)
|
.route(API_ROUTES.plans, modules.plans)
|
||||||
.route(API_ROUTE_PATHS.onboarding, modules.onboarding)
|
.route(API_ROUTES.onboarding, modules.onboarding)
|
||||||
.route(API_ROUTE_PATHS.complexes, modules.complexes)
|
.route(API_ROUTES.complexes, modules.complexes)
|
||||||
.route(API_ROUTE_PATHS.sports, modules.sports)
|
.route(API_ROUTES.sports, modules.sports)
|
||||||
.route(API_ROUTE_PATHS.courts, modules.courts)
|
.route(API_ROUTES.courts, modules.courts)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user