diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5bc5613 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,46 @@ +# ========================================= +# Stage 1: Build the TanStack Start Application +# ========================================= +ARG NODE_VERSION=24.12.0-alpine + +# Use a lightweight Node.js image for building (customizable via ARG) +FROM node:${NODE_VERSION} AS builder + +# Set the working directory inside the container +WORKDIR /app + +# Copy package-related files first to leverage Docker's caching mechanism +COPY package.json package-lock.json* ./ + +# Install project dependencies using npm ci (ensures a clean, reproducible install) +RUN npm ci + +# Copy the rest of the application source code into the container +COPY . . + +# Build the TanStack Start application (outputs to /app/.output) +RUN npm run build + +# ========================================= +# Stage 2: Run the TanStack Start Server +# ========================================= +FROM node:${NODE_VERSION} AS runner + +# Set the working directory +WORKDIR /app + +# Set environment variable for production +ENV NODE_ENV=production +ENV PORT=3000 +ENV HOST=0.0.0.0 + +# Copy the built server and client assets from the builder stage +COPY --from=builder /app/.output ./ + +# Switch to the non-root user +USER node + +# Expose the application port +EXPOSE 3000 + +ENTRYPOINT ["node", "server/index.mjs"] \ No newline at end of file diff --git a/package.json b/package.json index 3143a3e..fbe67d9 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "test": "vitest run", "lint": "eslint", "format": "prettier", - "check": "prettier --write . && eslint --fix" + "check": "prettier --write . && eslint --fix", + "start": "node .output/server/index.mjs" }, "dependencies": { "@tailwindcss/vite": "^4.0.6", @@ -42,4 +43,4 @@ "vitest": "^3.0.5", "web-vitals": "^5.1.0" } -} \ No newline at end of file +} diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts new file mode 100644 index 0000000..b13c274 --- /dev/null +++ b/src/routeTree.gen.ts @@ -0,0 +1,219 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { Route as rootRouteImport } from './routes/__root' +import { Route as IndexRouteImport } from './routes/index' +import { Route as DemoStartServerFuncsRouteImport } from './routes/demo/start.server-funcs' +import { Route as DemoStartApiRequestRouteImport } from './routes/demo/start.api-request' +import { Route as DemoApiNamesRouteImport } from './routes/demo/api.names' +import { Route as DemoStartSsrIndexRouteImport } from './routes/demo/start.ssr.index' +import { Route as DemoStartSsrSpaModeRouteImport } from './routes/demo/start.ssr.spa-mode' +import { Route as DemoStartSsrFullSsrRouteImport } from './routes/demo/start.ssr.full-ssr' +import { Route as DemoStartSsrDataOnlyRouteImport } from './routes/demo/start.ssr.data-only' + +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) +const DemoStartServerFuncsRoute = DemoStartServerFuncsRouteImport.update({ + id: '/demo/start/server-funcs', + path: '/demo/start/server-funcs', + getParentRoute: () => rootRouteImport, +} as any) +const DemoStartApiRequestRoute = DemoStartApiRequestRouteImport.update({ + id: '/demo/start/api-request', + path: '/demo/start/api-request', + getParentRoute: () => rootRouteImport, +} as any) +const DemoApiNamesRoute = DemoApiNamesRouteImport.update({ + id: '/demo/api/names', + path: '/demo/api/names', + getParentRoute: () => rootRouteImport, +} as any) +const DemoStartSsrIndexRoute = DemoStartSsrIndexRouteImport.update({ + id: '/demo/start/ssr/', + path: '/demo/start/ssr/', + getParentRoute: () => rootRouteImport, +} as any) +const DemoStartSsrSpaModeRoute = DemoStartSsrSpaModeRouteImport.update({ + id: '/demo/start/ssr/spa-mode', + path: '/demo/start/ssr/spa-mode', + getParentRoute: () => rootRouteImport, +} as any) +const DemoStartSsrFullSsrRoute = DemoStartSsrFullSsrRouteImport.update({ + id: '/demo/start/ssr/full-ssr', + path: '/demo/start/ssr/full-ssr', + getParentRoute: () => rootRouteImport, +} as any) +const DemoStartSsrDataOnlyRoute = DemoStartSsrDataOnlyRouteImport.update({ + id: '/demo/start/ssr/data-only', + path: '/demo/start/ssr/data-only', + getParentRoute: () => rootRouteImport, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute + '/demo/api/names': typeof DemoApiNamesRoute + '/demo/start/api-request': typeof DemoStartApiRequestRoute + '/demo/start/server-funcs': typeof DemoStartServerFuncsRoute + '/demo/start/ssr/data-only': typeof DemoStartSsrDataOnlyRoute + '/demo/start/ssr/full-ssr': typeof DemoStartSsrFullSsrRoute + '/demo/start/ssr/spa-mode': typeof DemoStartSsrSpaModeRoute + '/demo/start/ssr/': typeof DemoStartSsrIndexRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute + '/demo/api/names': typeof DemoApiNamesRoute + '/demo/start/api-request': typeof DemoStartApiRequestRoute + '/demo/start/server-funcs': typeof DemoStartServerFuncsRoute + '/demo/start/ssr/data-only': typeof DemoStartSsrDataOnlyRoute + '/demo/start/ssr/full-ssr': typeof DemoStartSsrFullSsrRoute + '/demo/start/ssr/spa-mode': typeof DemoStartSsrSpaModeRoute + '/demo/start/ssr': typeof DemoStartSsrIndexRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute + '/demo/api/names': typeof DemoApiNamesRoute + '/demo/start/api-request': typeof DemoStartApiRequestRoute + '/demo/start/server-funcs': typeof DemoStartServerFuncsRoute + '/demo/start/ssr/data-only': typeof DemoStartSsrDataOnlyRoute + '/demo/start/ssr/full-ssr': typeof DemoStartSsrFullSsrRoute + '/demo/start/ssr/spa-mode': typeof DemoStartSsrSpaModeRoute + '/demo/start/ssr/': typeof DemoStartSsrIndexRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: + | '/' + | '/demo/api/names' + | '/demo/start/api-request' + | '/demo/start/server-funcs' + | '/demo/start/ssr/data-only' + | '/demo/start/ssr/full-ssr' + | '/demo/start/ssr/spa-mode' + | '/demo/start/ssr/' + fileRoutesByTo: FileRoutesByTo + to: + | '/' + | '/demo/api/names' + | '/demo/start/api-request' + | '/demo/start/server-funcs' + | '/demo/start/ssr/data-only' + | '/demo/start/ssr/full-ssr' + | '/demo/start/ssr/spa-mode' + | '/demo/start/ssr' + id: + | '__root__' + | '/' + | '/demo/api/names' + | '/demo/start/api-request' + | '/demo/start/server-funcs' + | '/demo/start/ssr/data-only' + | '/demo/start/ssr/full-ssr' + | '/demo/start/ssr/spa-mode' + | '/demo/start/ssr/' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute + DemoApiNamesRoute: typeof DemoApiNamesRoute + DemoStartApiRequestRoute: typeof DemoStartApiRequestRoute + DemoStartServerFuncsRoute: typeof DemoStartServerFuncsRoute + DemoStartSsrDataOnlyRoute: typeof DemoStartSsrDataOnlyRoute + DemoStartSsrFullSsrRoute: typeof DemoStartSsrFullSsrRoute + DemoStartSsrSpaModeRoute: typeof DemoStartSsrSpaModeRoute + DemoStartSsrIndexRoute: typeof DemoStartSsrIndexRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + '/demo/start/server-funcs': { + id: '/demo/start/server-funcs' + path: '/demo/start/server-funcs' + fullPath: '/demo/start/server-funcs' + preLoaderRoute: typeof DemoStartServerFuncsRouteImport + parentRoute: typeof rootRouteImport + } + '/demo/start/api-request': { + id: '/demo/start/api-request' + path: '/demo/start/api-request' + fullPath: '/demo/start/api-request' + preLoaderRoute: typeof DemoStartApiRequestRouteImport + parentRoute: typeof rootRouteImport + } + '/demo/api/names': { + id: '/demo/api/names' + path: '/demo/api/names' + fullPath: '/demo/api/names' + preLoaderRoute: typeof DemoApiNamesRouteImport + parentRoute: typeof rootRouteImport + } + '/demo/start/ssr/': { + id: '/demo/start/ssr/' + path: '/demo/start/ssr' + fullPath: '/demo/start/ssr/' + preLoaderRoute: typeof DemoStartSsrIndexRouteImport + parentRoute: typeof rootRouteImport + } + '/demo/start/ssr/spa-mode': { + id: '/demo/start/ssr/spa-mode' + path: '/demo/start/ssr/spa-mode' + fullPath: '/demo/start/ssr/spa-mode' + preLoaderRoute: typeof DemoStartSsrSpaModeRouteImport + parentRoute: typeof rootRouteImport + } + '/demo/start/ssr/full-ssr': { + id: '/demo/start/ssr/full-ssr' + path: '/demo/start/ssr/full-ssr' + fullPath: '/demo/start/ssr/full-ssr' + preLoaderRoute: typeof DemoStartSsrFullSsrRouteImport + parentRoute: typeof rootRouteImport + } + '/demo/start/ssr/data-only': { + id: '/demo/start/ssr/data-only' + path: '/demo/start/ssr/data-only' + fullPath: '/demo/start/ssr/data-only' + preLoaderRoute: typeof DemoStartSsrDataOnlyRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, + DemoApiNamesRoute: DemoApiNamesRoute, + DemoStartApiRequestRoute: DemoStartApiRequestRoute, + DemoStartServerFuncsRoute: DemoStartServerFuncsRoute, + DemoStartSsrDataOnlyRoute: DemoStartSsrDataOnlyRoute, + DemoStartSsrFullSsrRoute: DemoStartSsrFullSsrRoute, + DemoStartSsrSpaModeRoute: DemoStartSsrSpaModeRoute, + DemoStartSsrIndexRoute: DemoStartSsrIndexRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() + +import type { getRouter } from './router.tsx' +import type { createStart } from '@tanstack/react-start' +declare module '@tanstack/react-start' { + interface Register { + ssr: true + router: Awaited> + } +}