From a118ec34d72146e809cbc21ab7036d37e0e65b0a Mon Sep 17 00:00:00 2001 From: Bapusaheb Patil Date: Sat, 9 Aug 2025 10:05:15 +0530 Subject: [PATCH 1/4] docs(start): improve cloudflare deployment options --- docs/start/framework/react/hosting.md | 75 ++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/docs/start/framework/react/hosting.md b/docs/start/framework/react/hosting.md index aff63011e7..331d0bbc3f 100644 --- a/docs/start/framework/react/hosting.md +++ b/docs/start/framework/react/hosting.md @@ -36,6 +36,7 @@ When a TanStack Start application is being deployed, the `target` value in the T - [`netlify`](#netlify): Deploy to Netlify - [`vercel`](#vercel): Deploy to Vercel - [`cloudflare-pages`](#cloudflare-pages): Deploy to Cloudflare Pages +- [`cloudflare-module`](#cloudflare-workers): Deploy to Cloudflare Workers - [`node-server`](#nodejs): Deploy to a Node.js server - [`bun`](#bun): Deploy to a Bun server - ... and more to come! @@ -92,13 +93,29 @@ export default defineConfig({ }) ``` -2. Add a `wrangler.toml` config file +2. Add a `wrangler.jsonc` config file (recommended) + +```jsonc +// wrangler.jsonc +{ + "name": "your-cloudflare-project-name", + "main": "./.output/server/index.mjs", + "compatibility_date": "2025-08-09", + "compatibility_flags": ["nodejs_compat"], + "assets": { + "binding": "ASSETS", + "directory": "./.output/public" + } +} +``` + +Or, if you prefer TOML, add a `wrangler.toml` config file instead: ```toml # wrangler.toml name = "your-cloudflare-project-name" main = "./.output/server/index.mjs" -compatibility_date = "2025-04-01" +compatibility_date = "2025-08-09" compatibility_flags = ["nodejs_compat"] [assets] @@ -108,6 +125,60 @@ directory = "./.output/public" Deploy your application to Cloudflare Workers using their one-click deployment process, and you're ready to go! +#### Deploy to Cloudflare button + +If you want others to deploy your TanStack Start app on Cloudflare Workers with a single click, you can embed Cloudflare’s Deploy button in your README or docs. Replace `` with your public GitHub/GitLab repository URL: + +```md +[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=) +``` + +- Note that the Deploy button currently supports Workers applications only, not Pages applications. +- Cloudflare will read your `wrangler.jsonc` (preferred) or `wrangler.toml` to automatically provision resources and bind them to your Worker. Ensure any required bindings (for example `vars`, KV/D1/R2, Durable Objects, Secrets Store) are declared with sensible defaults so deployments succeed. +- For more, see the official docs: [Deploy to Cloudflare buttons](https://developers.cloudflare.com/workers/platform/deploy-buttons/). + +### Cloudflare Pages + +When deploying to Cloudflare Pages, you'll need to complete a few extra steps before your users can start using your app. + +1. Update `vite.config.ts` + +Set the `target` value to `cloudflare-pages` in your `vite.config.ts` file. + +```ts +// vite.config.ts +import { tanstackStart } from '@tanstack/react-start/plugin/vite' +import { defineConfig } from 'vite' + +export default defineConfig({ + plugins: [tanstackStart({ target: 'cloudflare-pages' })], +}) +``` + +2. Add a `wrangler.jsonc` config file (preferred) + +```jsonc +// wrangler.jsonc +{ + "name": "your-cloudflare-project-name", + "pages_build_output_dir": "./.output/public", + "compatibility_flags": ["nodejs_compat"], + "compatibility_date": "2025-08-09" +} +``` + +Or, if you prefer TOML, add a `wrangler.toml` config file instead: + +```toml +# wrangler.toml +name = "your-cloudflare-project-name" +pages_build_output_dir = "./.output/public" +compatibility_flags = ["nodejs_compat"] +compatibility_date = "2025-08-09" +``` + +Deploy your application to Cloudflare Pages (connect your repo in the Pages dashboard and set the output directory to `./.output/public`) and you're ready to go! + ### Node.js Set the `target` value to `node-server` in your `vite.config.ts` file. From 27ecc62afd18f87171b6d67038f508d5cf510011 Mon Sep 17 00:00:00 2001 From: Bapusaheb Patil Date: Sat, 9 Aug 2025 10:23:48 +0530 Subject: [PATCH 2/4] docs(start): add docker for deployment --- docs/start/framework/react/hosting.md | 137 +++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 1 deletion(-) diff --git a/docs/start/framework/react/hosting.md b/docs/start/framework/react/hosting.md index 331d0bbc3f..2cf0af2d4a 100644 --- a/docs/start/framework/react/hosting.md +++ b/docs/start/framework/react/hosting.md @@ -35,10 +35,11 @@ When a TanStack Start application is being deployed, the `target` value in the T - [`netlify`](#netlify): Deploy to Netlify - [`vercel`](#vercel): Deploy to Vercel -- [`cloudflare-pages`](#cloudflare-pages): Deploy to Cloudflare Pages - [`cloudflare-module`](#cloudflare-workers): Deploy to Cloudflare Workers +- [`cloudflare-pages`](#cloudflare-pages): Deploy to Cloudflare Pages - [`node-server`](#nodejs): Deploy to a Node.js server - [`bun`](#bun): Deploy to a Bun server +- [`docker`](#docker): Deploy using Docker - ... and more to come! Once you've chosen a deployment target, you can follow the deployment guidelines below to deploy your TanStack Start application to the hosting provider of your choice. @@ -239,3 +240,137 @@ You're now ready to deploy your application to a Bun server. You can start your ```sh bun run .output/server/index.mjs ``` + +### Docker + +> [!NOTE] +> The examples below use Bun. You can use Node.js instead by setting `target: 'node-server'`, choosing a Node base image, and running the server with `node .output/server/index.mjs`. + +You can containerize a TanStack Start app with Bun using a small, production‑ready multi‑stage Docker build. This assumes you've configured `vite.config.ts` with `target: 'bun'` as shown above and that your app builds into `.output/`. + +1. Create a `Dockerfile` + +```dockerfile +# Use the official Bun image +# See tags at https://hub.docker.com/r/oven/bun/tags +FROM oven/bun:1.2.19 AS base +WORKDIR /usr/src/app + +# Install dependencies into a temp directory to leverage Docker layer caching +FROM base AS install +RUN mkdir -p /temp/dev +COPY package.json bun.lock* /temp/dev/ +RUN cd /temp/dev && bun install --frozen-lockfile + +# Install only production dependencies +RUN mkdir -p /temp/prod +COPY package.json bun.lock* /temp/prod/ +RUN cd /temp/prod && bun install --frozen-lockfile --production + +# Copy source and build +FROM base AS prerelease +COPY --from=install /temp/dev/node_modules node_modules +COPY . . + +ENV NODE_ENV=production +RUN bun run build --config vite.config.ts + +# Final, minimal runtime image +FROM oven/bun:1.2.19 AS release +WORKDIR /usr/src/app + +# Optional: curl for health checks +USER root +RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* + +COPY --from=install /temp/prod/node_modules node_modules +COPY --from=prerelease /usr/src/app/.output ./.output +COPY --from=prerelease /usr/src/app/package.json ./package.json + +# Non-root runtime +USER bun + +# Expose the app port inside the container +EXPOSE 5173/tcp + +# Ensure the server binds to all interfaces and the expected port +ENV HOST=0.0.0.0 +ENV PORT=5173 + +# Optional health check hitting the root route +HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ + CMD curl -fsS http://localhost:5173/ || exit 1 + +# Start the Bun server (SSR entry emitted by TanStack Start) +ENTRYPOINT ["bun", "run", ".output/server/index.mjs"] +``` + +2. Add a `.dockerignore` (recommended) + +```gitignore +node_modules +.git +.output +.env* +Dockerfile +docker-compose.yml +dist +.vite +``` + +3. Build and run + +```sh +docker build -t my-tanstack-start-app . +docker run --rm -p 8080:5173 \ + -e HOST=0.0.0.0 -e PORT=5173 \ + my-tanstack-start-app +``` + +Your app will be available at `http://localhost:8080`. + +#### Optional: docker-compose + +```yaml +services: + app: + build: + context: . + dockerfile: Dockerfile + ports: + - "8080:5173" + environment: + - NODE_ENV=production + - HOST=0.0.0.0 + - PORT=5173 + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:5173/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s +``` + +#### Deploying on Coolify + +> [!NOTE] +> The same Docker setup works on platforms like Railway, Fly.io, Render, and most container platforms that can build from a `Dockerfile` or run a pre-built image. Ensure `HOST`/`PORT` are set and map container port `5173`. + +You can deploy this Docker setup on Coolify either from your Git repository (Coolify builds the image from the `Dockerfile`) or from a pre-built image in a registry. + +- Create a new service → Docker → Build from Git. +- Connect your repo and select the branch; ensure `Dockerfile` path is correct (usually `./Dockerfile`). +- Set environment variables: + - `NODE_ENV=production` + - `HOST=0.0.0.0` + - `PORT=5173` +- Expose the container port `5173`. If assigning a domain, Coolify will proxy via 80/443 automatically. +- Optional: configure a health check with path `/` and internal port `5173`. +- Deploy. Coolify will build, run, and keep the service updated on new pushes if you enable auto-deploy. + +#### Notes +- The server listens on `PORT` (default `5173`). When running in Docker, map a host port (for example `8080`) to `5173`. +- Set `HOST=0.0.0.0` so the server binds to all interfaces inside the container. +- The build outputs `.output/server/index.mjs` (server) and `.output/public` (static assets). The Dockerfile copies these from the build stage into the final image. +- Use the `oven/bun` image tag that matches your Bun version. Pinning a minor series (for example `1.2.19`) balances stability and security updates. From 7340d2afa7d718c1297aca96189bda84a0bdea34 Mon Sep 17 00:00:00 2001 From: Bapusaheb Patil Date: Sat, 9 Aug 2025 10:37:17 +0530 Subject: [PATCH 3/4] docs(start): improve docker-compose.yaml and coolify for docker deployment --- docs/start/framework/react/hosting.md | 51 ++++++++++++++++++++------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/docs/start/framework/react/hosting.md b/docs/start/framework/react/hosting.md index 2cf0af2d4a..94c4a1b191 100644 --- a/docs/start/framework/react/hosting.md +++ b/docs/start/framework/react/hosting.md @@ -313,7 +313,7 @@ node_modules .output .env* Dockerfile -docker-compose.yml +docker-compose.yaml dist .vite ``` @@ -329,7 +329,13 @@ docker run --rm -p 8080:5173 \ Your app will be available at `http://localhost:8080`. -#### Optional: docker-compose +> [!NOTE] +> If you're also running a database or other services locally (for example Postgres on `5432`, Redis on `6379`, MySQL on `3306`), map those ports as needed (for example `-p 5432:5432`). In production, prefer internal networking between containers and avoid exposing databases publicly. + +#### Optional: docker-compose.yaml + +> [!NOTE] +> Use `docker-compose.yaml` when your TanStack Start app includes multiple services (for example Postgres, Redis, background workers) or you want to manage shared networks, health checks, and restart policies together. For a single-service app, a `Dockerfile` alone is usually sufficient. ```yaml services: @@ -350,6 +356,15 @@ services: timeout: 10s retries: 3 start_period: 30s + # Example: connect to Postgres in the same compose project + # services typically communicate over the default network using service names + # (for example DATABASE_URL=postgres://postgres:password@db:5432/postgres) + # db: + # image: postgres:16 + # environment: + # - POSTGRES_PASSWORD=password + # ports: + # - "5432:5432" # Only expose if you need host access; otherwise omit ``` #### Deploying on Coolify @@ -357,20 +372,30 @@ services: > [!NOTE] > The same Docker setup works on platforms like Railway, Fly.io, Render, and most container platforms that can build from a `Dockerfile` or run a pre-built image. Ensure `HOST`/`PORT` are set and map container port `5173`. -You can deploy this Docker setup on Coolify either from your Git repository (Coolify builds the image from the `Dockerfile`) or from a pre-built image in a registry. - -- Create a new service → Docker → Build from Git. -- Connect your repo and select the branch; ensure `Dockerfile` path is correct (usually `./Dockerfile`). -- Set environment variables: - - `NODE_ENV=production` - - `HOST=0.0.0.0` - - `PORT=5173` -- Expose the container port `5173`. If assigning a domain, Coolify will proxy via 80/443 automatically. -- Optional: configure a health check with path `/` and internal port `5173`. -- Deploy. Coolify will build, run, and keep the service updated on new pushes if you enable auto-deploy. +Choose one of the following based on your setup: + +##### Option A — Docker Compose (recommended for multi‑service apps) +- Create a new service → Docker Compose → Build from Git. +- Connect your repo and branch; ensure the `docker-compose.yaml` path is correct (usually `./docker-compose.yaml`). +- In Build Pack, select Docker Compose (Coolify defaults to Nixpacks). Set Base Directory if your compose lives in a subfolder (for example `/apps/web`). +- Keep databases (for example Postgres on `5432`) internal; reference them via service names (for example `db:5432`). +- Set environment variables on the `app` service: + - `NODE_ENV=production`, `HOST=0.0.0.0`, `PORT=5173` +- Network settings: set the internal application port to `5173` (Coolify defaults to `3000`). If you attach a domain, Coolify proxies via 80/443. +- Deploy. Enable auto‑deploy on pushes if desired. + +##### Option B — Dockerfile (recommended for single‑service apps) +- Create a new service → Docker → Build from Git (or use a pre‑built image from a registry). +- Connect your repo and branch; verify `Dockerfile` path (usually `./Dockerfile`). +- In Build Pack, select Dockerfile (Coolify defaults to Nixpacks). Set Base Directory if your app is in a subfolder. +- Set environment variables: `NODE_ENV=production`, `HOST=0.0.0.0`, `PORT=5173`. +- Network settings: set the internal application port to `5173` (Coolify defaults to `3000`). Optionally configure a health check `/` on port `5173`. +- Deploy. Coolify will build and run the service and can auto‑deploy on new pushes. #### Notes - The server listens on `PORT` (default `5173`). When running in Docker, map a host port (for example `8080`) to `5173`. - Set `HOST=0.0.0.0` so the server binds to all interfaces inside the container. - The build outputs `.output/server/index.mjs` (server) and `.output/public` (static assets). The Dockerfile copies these from the build stage into the final image. - Use the `oven/bun` image tag that matches your Bun version. Pinning a minor series (for example `1.2.19`) balances stability and security updates. + - Using a database? If Postgres is part of your deployment, ensure the app can reach port `5432` (prefer internal networking). Avoid exposing databases publicly; for local access map `5432:5432`. Apply the same guidance for other services (for example Redis `6379`, MySQL `3306`). + - If your database lives in a different Coolify stack, enable “Connect to Predefined Network” and reference the database service by its full stack-aware name. Otherwise, keep all services in the same compose stack to use the default internal network. From aab61d8b92a5e00d936f089684e8ef74ceed5c74 Mon Sep 17 00:00:00 2001 From: Bapusaheb Patil Date: Sat, 9 Aug 2025 10:55:42 +0530 Subject: [PATCH 4/4] docs(start): remove cloudflare pages --- docs/start/framework/react/hosting.md | 43 --------------------------- 1 file changed, 43 deletions(-) diff --git a/docs/start/framework/react/hosting.md b/docs/start/framework/react/hosting.md index 94c4a1b191..d6bf0131eb 100644 --- a/docs/start/framework/react/hosting.md +++ b/docs/start/framework/react/hosting.md @@ -36,7 +36,6 @@ When a TanStack Start application is being deployed, the `target` value in the T - [`netlify`](#netlify): Deploy to Netlify - [`vercel`](#vercel): Deploy to Vercel - [`cloudflare-module`](#cloudflare-workers): Deploy to Cloudflare Workers -- [`cloudflare-pages`](#cloudflare-pages): Deploy to Cloudflare Pages - [`node-server`](#nodejs): Deploy to a Node.js server - [`bun`](#bun): Deploy to a Bun server - [`docker`](#docker): Deploy using Docker @@ -138,48 +137,6 @@ If you want others to deploy your TanStack Start app on Cloudflare Workers with - Cloudflare will read your `wrangler.jsonc` (preferred) or `wrangler.toml` to automatically provision resources and bind them to your Worker. Ensure any required bindings (for example `vars`, KV/D1/R2, Durable Objects, Secrets Store) are declared with sensible defaults so deployments succeed. - For more, see the official docs: [Deploy to Cloudflare buttons](https://developers.cloudflare.com/workers/platform/deploy-buttons/). -### Cloudflare Pages - -When deploying to Cloudflare Pages, you'll need to complete a few extra steps before your users can start using your app. - -1. Update `vite.config.ts` - -Set the `target` value to `cloudflare-pages` in your `vite.config.ts` file. - -```ts -// vite.config.ts -import { tanstackStart } from '@tanstack/react-start/plugin/vite' -import { defineConfig } from 'vite' - -export default defineConfig({ - plugins: [tanstackStart({ target: 'cloudflare-pages' })], -}) -``` - -2. Add a `wrangler.jsonc` config file (preferred) - -```jsonc -// wrangler.jsonc -{ - "name": "your-cloudflare-project-name", - "pages_build_output_dir": "./.output/public", - "compatibility_flags": ["nodejs_compat"], - "compatibility_date": "2025-08-09" -} -``` - -Or, if you prefer TOML, add a `wrangler.toml` config file instead: - -```toml -# wrangler.toml -name = "your-cloudflare-project-name" -pages_build_output_dir = "./.output/public" -compatibility_flags = ["nodejs_compat"] -compatibility_date = "2025-08-09" -``` - -Deploy your application to Cloudflare Pages (connect your repo in the Pages dashboard and set the output directory to `./.output/public`) and you're ready to go! - ### Node.js Set the `target` value to `node-server` in your `vite.config.ts` file.