From 7ec6b5594109e91247ad318fcfba0f4e78addbaf Mon Sep 17 00:00:00 2001 From: "kristiyan.velkov" Date: Thu, 27 Aug 2026 16:03:28 +0300 Subject: [PATCH 1/4] Add TanStack Start language-specific guide. Introduces a full-stack guide for containerizing TanStack Start apps with Docker, including development, testing, GitHub Actions CI/CD, and local Kubernetes deployment. Links to the docker-tanstack-start-sample repo. --- _vale/config/vocabularies/Docker/accept.txt | 1 + content/guides/nodejs/_index.md | 2 +- content/guides/tanstack-start/_index.md | 60 ++++ .../configure-github-actions.md | 265 ++++++++++++++++ content/guides/tanstack-start/containerize.md | 298 ++++++++++++++++++ content/guides/tanstack-start/deploy.md | 199 ++++++++++++ content/guides/tanstack-start/develop.md | 233 ++++++++++++++ content/guides/tanstack-start/run-tests.md | 185 +++++++++++ 8 files changed, 1242 insertions(+), 1 deletion(-) create mode 100644 content/guides/tanstack-start/_index.md create mode 100644 content/guides/tanstack-start/configure-github-actions.md create mode 100644 content/guides/tanstack-start/containerize.md create mode 100644 content/guides/tanstack-start/deploy.md create mode 100644 content/guides/tanstack-start/develop.md create mode 100644 content/guides/tanstack-start/run-tests.md diff --git a/_vale/config/vocabularies/Docker/accept.txt b/_vale/config/vocabularies/Docker/accept.txt index 33acf491e673..b3400b565fb3 100644 --- a/_vale/config/vocabularies/Docker/accept.txt +++ b/_vale/config/vocabularies/Docker/accept.txt @@ -241,6 +241,7 @@ Testcontainers tmpfs Traefik Trivy +TanStack Trixie Turtlesim typesafe diff --git a/content/guides/nodejs/_index.md b/content/guides/nodejs/_index.md index bf73b585988b..837c4d2d0b2b 100644 --- a/content/guides/nodejs/_index.md +++ b/content/guides/nodejs/_index.md @@ -18,7 +18,7 @@ params: [Node.js](https://nodejs.org/en) is a JavaScript runtime for building server-side applications. This guide shows you how to containerize a TypeScript Node.js application using Docker, starting from a simple Express API and progressively adding features like a database and CI/CD. -This guide focuses on a backend Node.js API. If you're building a standalone frontend application, Docker has dedicated guides for [React.js](/guides/reactjs/), [Vue.js](/guides/vuejs/), [Angular](/guides/angular/), and [Next.js](/guides/nextjs/). +This guide focuses on a backend Node.js API. If you're building a standalone frontend application, Docker has dedicated guides for [React.js](/guides/reactjs/), [Vue.js](/guides/vuejs/), [Angular](/guides/angular/), [Next.js](/guides/nextjs/), and [TanStack Start](/guides/tanstack-start/). > **Acknowledgment** > diff --git a/content/guides/tanstack-start/_index.md b/content/guides/tanstack-start/_index.md new file mode 100644 index 000000000000..bec4261de3db --- /dev/null +++ b/content/guides/tanstack-start/_index.md @@ -0,0 +1,60 @@ +--- +title: TanStack Start language-specific guide +linkTitle: TanStack Start +description: Containerize, develop, test, and deploy TanStack Start apps with Docker and Kubernetes +keywords: getting started, TanStack Start, tanstack, react, docker, language, Dockerfile, CI/CD, Kubernetes +summary: | + This guide explains how to containerize TanStack Start applications, set up + development and testing in containers, automate builds with GitHub Actions, + and deploy to Kubernetes. +toc_min: 1 +toc_max: 2 +languages: [js] +tags: [frameworks] +params: + time: 20 minutes +--- + +This guide shows you how to containerize a [TanStack Start](https://tanstack.com/start) +application using Docker, following best practices for production-ready +containers. + +[TanStack Start](https://tanstack.com/start) is a full-stack React framework +built on [TanStack Router](https://tanstack.com/router) and Vite. It supports +server-side rendering, streaming, and type-safe routing. Docker provides a +consistent containerized environment from development to production. + +> **Acknowledgment** +> +> Docker extends its sincere gratitude to [Kristiyan Velkov](https://www.linkedin.com/in/kristiyan-velkov-763130b3/) for authoring this guide and maintaining the [docker-tanstack-start-sample](https://github.com/kristiyan-velkov/docker-tanstack-start-sample) repository used throughout this guide. + +--- + +## What will you learn? + +In this guide, you will learn how to: + +- Containerize and run a TanStack Start application using Docker. +- Set up a local development environment for TanStack Start inside a container. +- Run tests for your TanStack Start application within a Docker container. +- Configure a CI/CD pipeline using GitHub Actions for your containerized app. +- Deploy the containerized TanStack Start application to a local Kubernetes + cluster for testing and debugging. + +To begin, you'll start by containerizing an existing TanStack Start +application. + +--- + +## Prerequisites + +Before you begin, make sure you're familiar with the following: + +- Basic understanding of [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) or [TypeScript](https://www.typescriptlang.org/). +- Basic knowledge of [Node.js](https://nodejs.org/en) and [npm](https://docs.npmjs.com/about-npm) for managing dependencies and running scripts. +- Familiarity with [React](https://react.dev/) and [TanStack Start](https://tanstack.com/start) fundamentals. +- Understanding of Docker concepts such as images, containers, and Dockerfiles. If you're new to Docker, start with the [Docker basics](/get-started/docker-concepts/the-basics/what-is-a-container.md) guide. + +Once you've completed the TanStack Start getting started modules, you'll be +ready to containerize your own application using the examples and instructions +in this guide. diff --git a/content/guides/tanstack-start/configure-github-actions.md b/content/guides/tanstack-start/configure-github-actions.md new file mode 100644 index 000000000000..afea5b4efea5 --- /dev/null +++ b/content/guides/tanstack-start/configure-github-actions.md @@ -0,0 +1,265 @@ +--- +title: Automate your builds with GitHub Actions +linkTitle: GitHub Actions CI +weight: 60 +keywords: CI/CD, GitHub Actions, TanStack Start +description: Learn how to configure CI/CD using GitHub Actions for your TanStack Start application. +--- + +## Prerequisites + +Complete all the previous sections of this guide, starting with +[Containerize TanStack Start application](containerize.md). + +You must also have: + +- A [GitHub](https://github.com/signup) account. +- A verified [Docker Hub](https://hub.docker.com/signup) account. + +--- + +## Overview + +In this section, you'll set up a CI/CD pipeline using +[GitHub Actions](https://docs.github.com/en/actions) to automatically: + +- Build your TanStack Start application inside a Docker container. +- Run tests in a consistent environment. +- Push the production-ready image to [Docker Hub](https://hub.docker.com). + +--- + +## Integrate GitHub and Docker Hub + +To enable GitHub Actions to build and push Docker images, you'll securely +store your Docker Hub credentials in your GitHub repository. + +### Step 1: Connect your GitHub repository to Docker Hub + +1. Create a Personal Access Token (PAT) from [Docker Hub](https://hub.docker.com) + 1. Go to your **Docker Hub account → Account Settings → Security**. + 2. Generate a new Access Token with **Read/Write** permissions. + 3. Name it something like `tanstack-start-sample`. + 4. Copy and save the token — you'll need it in Step 4. + +2. Create a repository in [Docker Hub](https://hub.docker.com/repositories/) + 1. Go to your **Docker Hub account → Create a repository**. + 2. For the Repository Name, use something descriptive — for example: + `tanstack-start-sample`. + 3. Once created, copy and save the repository name — you'll need it in + Step 4. + +3. Create a new [GitHub repository](https://github.com/new) for your TanStack + Start project. + +4. Add Docker Hub credentials as GitHub repository secrets + + In your GitHub repository: + 1. Navigate to: + **Settings → Secrets and variables → Actions → New repository secret**. + + 2. Add the following secrets: + + | Name | Value | + | ------------------------ | --------------------------------------------------- | + | `DOCKER_USERNAME` | Your Docker Hub username | + | `DOCKERHUB_TOKEN` | Your Docker Hub access token (created in Step 1) | + | `DOCKERHUB_PROJECT_NAME` | Your Docker Hub repository name (created in Step 2) | + + These secrets let GitHub Actions authenticate securely with Docker Hub + during automated workflows. + +5. Connect your local project to GitHub + + Link your local project to the GitHub repository you created: + + ```console + $ git remote set-url origin https://github.com/{your-username}/{your-repository-name}.git + ``` + + > [!IMPORTANT] + > Replace `{your-username}` and `{your-repository-name}` with your actual + > GitHub username and repository name. + + Confirm the remote is configured: + + ```console + $ git remote -v + ``` + +6. Push your source code to GitHub + + Stage, commit, and push your project files to the `main` branch. Once + completed, your code is on GitHub and configured workflows run + automatically. + +> [!NOTE] +> Learn more about the Git commands used in this step: +> +> - [Git add](https://git-scm.com/docs/git-add) – Stage changes for commit +> - [Git commit](https://git-scm.com/docs/git-commit) – Save staged changes +> - [Git push](https://git-scm.com/docs/git-push) – Upload commits to GitHub +> - [Git remote](https://git-scm.com/docs/git-remote) – Manage remote URLs + +--- + +### Step 2: Set up the workflow + +Create a GitHub Actions workflow that builds your Docker image, runs tests, +and pushes the image to Docker Hub. + +1. Go to your repository on GitHub and select the **Actions** tab. + +2. Select **Set up a workflow yourself**. + + By default, the file is saved to `.github/workflows/main.yml`. + +3. Add the following workflow configuration: + +```yaml +# CI/CD – TanStack Start Application with Docker +# Builds the app, runs tests in a container, and pushes the production image to Docker Hub. + +name: CI/CD – TanStack Start Application with Docker + +on: + push: + branches: [main] + pull_request: + branches: [main] + types: [opened, synchronize, reopened] + +jobs: + build-test-push: + name: Build, Test and Push Docker Image + runs-on: ubuntu-latest + + steps: + - name: Checkout source code + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Cache Docker layers + uses: actions/cache@v5 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: ${{ runner.os }}-buildx- + + - name: Extract metadata + id: meta + run: | + echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> "$GITHUB_OUTPUT" + echo "SHORT_SHA=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT" + + - name: Build Docker image for tests + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.dev + tags: ${{ steps.meta.outputs.REPO_NAME }}-dev:latest + load: true + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache,mode=max + + - name: Run tests + run: | + docker run --rm \ + --workdir /app \ + --entrypoint "" \ + -e CI=true \ + ${{ steps.meta.outputs.REPO_NAME }}-dev:latest \ + npm run test + env: + CI: true + NODE_ENV: test + timeout-minutes: 10 + + - name: Log in to Docker Hub + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push production image + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile + push: true + platforms: linux/amd64,linux/arm64 + tags: | + ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKERHUB_PROJECT_NAME }}:latest + ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKERHUB_PROJECT_NAME }}:${{ steps.meta.outputs.SHORT_SHA }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache,mode=max +``` + +This workflow: + +- Triggers on every `push` or `pull request` targeting the `main` branch. +- Builds a development Docker image using `Dockerfile.dev` for testing. +- Runs Vitest inside a container with `npm run test`. +- Halts the workflow if any test fails. +- Caches Docker build layers for faster CI runs. +- Authenticates with Docker Hub using GitHub repository secrets. +- Builds and pushes a production image with `latest` and short SHA tags on + pushes to `main`. + +> [!NOTE] +> For more information about `docker/build-push-action`, see the +> [GitHub Action README](https://github.com/docker/build-push-action/blob/master/README.md). + +--- + +### Step 3: Run the workflow + +1. Commit and push your workflow file from the GitHub editor or your local + repository. +2. Open the **Actions** tab and select the workflow run to follow each step. +3. After a successful run on `main`, verify the image on + [Docker Hub](https://hub.docker.com/repositories). + +> [!TIP] Protect your main branch +> To maintain code quality and prevent accidental direct pushes, enable branch +> protection rules: +> +> - Navigate to your **GitHub repo → Settings → Branches**. +> - Under Branch protection rules, select **Add rule**. +> - Specify `main` as the branch name. +> - Enable options like _Require a pull request before merging_ and _Require +> status checks to pass before merging_. + +--- + +## Summary + +In this section, you set up a CI/CD pipeline for your containerized TanStack +Start application using GitHub Actions. + +What you accomplished: + +- Stored Docker Hub credentials as GitHub repository secrets +- Defined a workflow to build, test, and push your application image +- Triggered and verified the workflow through GitHub Actions + +--- + +## Related resources + +- [GitHub Actions documentation](https://docs.github.com/en/actions) – Learn + about workflows, jobs, and steps +- [Docker Hub](https://hub.docker.com/) – Store and share container images +- [docker/build-push-action](https://github.com/docker/build-push-action) – + Build and push Docker images in GitHub Actions + +## Next steps + +In the next section, you'll deploy your TanStack Start application to a local +Kubernetes cluster using Docker Desktop. diff --git a/content/guides/tanstack-start/containerize.md b/content/guides/tanstack-start/containerize.md new file mode 100644 index 000000000000..cb766293c2cc --- /dev/null +++ b/content/guides/tanstack-start/containerize.md @@ -0,0 +1,298 @@ +--- +title: Containerize a TanStack Start Application +linkTitle: Containerize +weight: 10 +keywords: tanstack start, node, image, initialize, build +description: Learn how to containerize a TanStack Start application with Docker by creating an optimized, production-ready image using best practices for performance, security, and scalability. +--- + +## Prerequisites + +Before you begin, make sure the following tools are installed and available on +your system: + +- You have installed the latest version of [Docker Desktop](/get-started/get-docker.md). +- You have a [git client](https://git-scm.com/downloads). The examples in this + section use a command-line based git client, but you can use any client. + +> [!NOTE] +> New to Docker? Start with the [Docker basics](/get-started/docker-concepts/the-basics/what-is-a-container.md) guide to get familiar with key concepts like images, containers, and Dockerfiles. + +--- + +## Overview + +This guide walks you through containerizing a TanStack Start application with +Docker. You'll learn how to create a production-ready Docker image using best +practices that improve performance, security, scalability, and deployment +efficiency. + +By the end of this guide, you will: + +- Containerize a TanStack Start application using Docker. +- Create and optimize a Dockerfile for production builds. +- Use multi-stage builds to minimize image size. +- Run the TanStack Start server from the `.output` build directory. +- Follow best practices for building secure and maintainable Docker images. + +--- + +## Get the sample application + +Clone the sample application to use with this guide. Open a terminal, change +directory to a directory that you want to work in, and run the following +commands: + +```console +$ git clone https://github.com/kristiyan-velkov/docker-tanstack-start-sample +$ cd docker-tanstack-start-sample +``` + +The sample is a TanStack Start app that uses Vite and Nitro. The production +build writes a Node.js server bundle to `.output`. + +--- + +## Build the Docker image + +TanStack Start produces a server-side bundle at build time. The production +container runs that bundle with Node.js on port 3000. + +> [!TIP] +> +> [Gordon](/ai/gordon/), Docker's AI assistant, can generate Docker assets for +> your project. Ask Gordon to create a Dockerfile, Compose file, and +> `.dockerignore` tailored to your application. + +### Step 1: Create the Dockerfile + +Before creating a Dockerfile, choose a base image: the [Node.js Official Image](https://hub.docker.com/_/node) or a [Docker Hardened Image (DHI)](https://hub.docker.com/hardened-images/catalog) from the Hardened Image catalog. + +> [!IMPORTANT] +> This guide uses a stable Node.js image tag that is considered secure when the +> guide is written. Because new releases and security patches are published +> regularly, always review the [official Node.js Docker images](https://hub.docker.com/_/node) and select a secure, up-to-date version before building or deploying. + +Create a file named `Dockerfile` with the following contents (matching the +[sample project](https://github.com/kristiyan-velkov/docker-tanstack-start-sample)): + +```dockerfile +# ========================================= +# Stage 1: Build the TanStack Start Application +# ========================================= +ARG NODE_VERSION=24.14.0-alpine + +FROM node:${NODE_VERSION} AS builder + +WORKDIR /app + +COPY package.json package-lock.json* ./ + +RUN --mount=type=cache,target=/root/.npm npm ci + +COPY . . + +RUN npm run build + +# ========================================= +# Stage 2: Run the TanStack Start Server +# ========================================= +FROM node:${NODE_VERSION} AS runner + +WORKDIR /app + +ENV NODE_ENV=production +ENV PORT=3000 +ENV HOST=0.0.0.0 + +COPY --from=builder /app/.output ./ + +USER node + +EXPOSE 3000 + +ENTRYPOINT ["node", "server/index.mjs"] +``` + +This Dockerfile: + +- Uses a multi-stage build to keep the final image small. +- Installs dependencies with `npm ci` for reproducible builds. +- Runs `npm run build`, which outputs the server bundle to `.output`. +- Runs the app as the non-root `node` user. +- Starts the Nitro server with `node server/index.mjs`. + +### Step 2: Create the compose.yml file + +Create a file named `compose.yml` with the following contents: + +```yaml +services: + tanstack-start-app: + build: + context: . + dockerfile: Dockerfile + args: + NODE_VERSION: 24.14.0-alpine + image: tanstack-start-image + container_name: tanstack-start-container + environment: + NODE_ENV: production + PORT: 3000 + HOST: 0.0.0.0 + ports: + - "3000:3000" + restart: unless-stopped +``` + +### Step 3: Create the .dockerignore file + +The `.dockerignore` file tells Docker which files and folders to exclude when +building the image. + +> [!NOTE] +> This helps reduce image size, speed up builds, and prevent sensitive or +> unnecessary files (like `.env`, `.git`, or `node_modules`) from being added +> to the build context. To learn more, see the +> [.dockerignore reference](/reference/dockerfile/#dockerignore-file). + +Create a file named `.dockerignore` with the following contents: + +```dockerignore +node_modules/ +.output/ +.nitro/ +.vinxi/ +dist/ +build/ +out/ +.vite/ +coverage/ +*.test.ts +*.test.tsx +*.spec.ts +*.spec.tsx +.env +.env.* +!.env.example +.git/ +.vscode/ +.idea/ +*.log +Dockerfile* +compose*.yml +.dockerignore +README.md +``` + +The [sample project](https://github.com/kristiyan-velkov/docker-tanstack-start-sample/blob/main/.dockerignore) includes a more exhaustive `.dockerignore` you can copy for production use. + +### Step 4: Build the TanStack Start application image + +Run the following command from the root of your project: + +```console +$ docker build --tag tanstack-start . +``` + +What this command does: + +- Uses the Dockerfile in the current directory (`.`) +- Packages the application and its dependencies into a Docker image +- Tags the image as `tanstack-start` so you can reference it later + +### Step 5: View local images + +After building your Docker image, list locally available images: + +```console +$ docker images +``` + +Example output: + +```shell +REPOSITORY TAG IMAGE ID CREATED SIZE +tanstack-start latest 8c5fc80f098e 14 seconds ago 130MB +``` + +If the build was successful, you should see the `tanstack-start` image listed. + +--- + +## Run the containerized application + +Run the image in a container and verify that your application works: + +```console +$ docker run -p 3000:3000 tanstack-start +``` + +Open a browser and view the application at +[http://localhost:3000](http://localhost:3000). You should see your TanStack +Start web application. + +Press `ctrl+c` in the terminal to stop your application. + +### Run the application in the background + +Run the application detached from the terminal: + +```console +$ docker run -d -p 3000:3000 --name tanstack-start-app tanstack-start +``` + +To confirm that the container is running: + +```console +$ docker ps +``` + +Stop the container when you're done: + +```console +$ docker stop tanstack-start-app +``` + +### Run with Docker Compose + +From the project root, build and start the service defined in `compose.yml`: + +```console +$ docker compose up --build +``` + +Open [http://localhost:3000](http://localhost:3000) in your browser. Press +`ctrl+c` to stop the services, or run `docker compose down` in another +terminal. + +--- + +## Summary + +In this section, you containerized a TanStack Start application using Docker. + +What you accomplished: + +- Created a multi-stage Dockerfile that builds and runs the TanStack Start + server from `.output` +- Added `compose.yml` and `.dockerignore` for local orchestration and lean + build contexts +- Built and ran the containerized application on port 3000 + +--- + +## Related resources + +- [Multi-stage builds](/manuals/build/building/multi-stage/) – Create + production-ready Docker images +- [Dockerfile best practices](/build/building/best-practices/) – Write clean, + secure, and optimized Dockerfiles +- [TanStack Start documentation](https://tanstack.com/start/latest/docs/framework/react/overview) – + Learn about routing, SSR, and deployment options + +## Next steps + +In the next section, you'll set up a development workflow with Docker Compose +and Compose Watch so you can iterate on your TanStack Start app inside +containers. diff --git a/content/guides/tanstack-start/deploy.md b/content/guides/tanstack-start/deploy.md new file mode 100644 index 000000000000..c89cdf13ce01 --- /dev/null +++ b/content/guides/tanstack-start/deploy.md @@ -0,0 +1,199 @@ +--- +title: Test your TanStack Start deployment +linkTitle: Test your deployment +weight: 70 +keywords: deploy, kubernetes, tanstack start +description: Learn how to deploy locally to test and debug your Kubernetes deployment +--- + +## Prerequisites + +Before you begin, make sure you've completed the following: + +- Complete all the previous sections of this guide, starting with + [Containerize TanStack Start application](containerize.md). +- [Enable Kubernetes](/manuals/desktop/use-desktop/kubernetes.md#enable-kubernetes) in Docker Desktop. + +> [!NOTE] +> New to Kubernetes? Visit the +> [Kubernetes basics tutorial](https://kubernetes.io/docs/tutorials/kubernetes-basics/) +> to learn how clusters, pods, deployments, and services work. + +--- + +## Overview + +This section guides you through deploying your containerized TanStack Start +application locally using +[Docker Desktop's built-in Kubernetes](/desktop/kubernetes/). A local cluster +lets you test and debug workloads before promoting them to staging or +production. + +--- + +## Create a Kubernetes YAML file + +Follow these steps to define your deployment configuration: + +1. In the root of your project, create a file named + `tanstack-start-kubernetes.yaml`. + +2. Open the file in your IDE or preferred text editor. + +3. Add the following configuration. Replace `{DOCKER_USERNAME}` and + `{DOCKERHUB_PROJECT_NAME}` with your Docker Hub username and repository + name from + [Automate your builds with GitHub Actions](configure-github-actions.md). + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: tanstack-start + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: tanstack-start + template: + metadata: + labels: + app: tanstack-start + spec: + containers: + - name: tanstack-start-container + image: {DOCKER_USERNAME}/{DOCKERHUB_PROJECT_NAME}:latest + imagePullPolicy: Always + ports: + - containerPort: 3000 + env: + - name: NODE_ENV + value: "production" + - name: HOST + value: "0.0.0.0" + - name: PORT + value: "3000" +--- +apiVersion: v1 +kind: Service +metadata: + name: tanstack-start-service + namespace: default +spec: + type: NodePort + selector: + app: tanstack-start + ports: + - port: 3000 + targetPort: 3000 + nodePort: 30001 +``` + +This manifest defines two Kubernetes resources, separated by `---`: + +- **Deployment** — Runs a single replica of your TanStack Start application. + The pod uses the Docker image built and pushed by your GitHub Actions + workflow. The container listens on port `3000`. + +- **Service (NodePort)** — Exposes the pod on port `30001` on your host, + forwarding traffic to port `3000` in the container. Open + [http://localhost:30001](http://localhost:30001) in your browser. + +> [!NOTE] +> To learn more about Kubernetes objects, see the +> [Kubernetes documentation](https://kubernetes.io/docs/home/). + +--- + +## Deploy and check your application + +### Step 1: Apply the Kubernetes configuration + +From the directory that contains `tanstack-start-kubernetes.yaml`, run: + +```console +$ kubectl apply -f tanstack-start-kubernetes.yaml +``` + +Expected output: + +```shell +deployment.apps/tanstack-start created +service/tanstack-start-service created +``` + +### Step 2: Check the deployment status + +```console +$ kubectl get deployments +``` + +Example output: + +```shell +NAME READY UP-TO-DATE AVAILABLE AGE +tanstack-start 1/1 1 1 14s +``` + +### Step 3: Verify the service exposure + +```console +$ kubectl get services +``` + +Example output: + +```shell +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +tanstack-start-service NodePort 10.100.244.65 3000:30001/TCP 1m +``` + +### Step 4: Access your app in the browser + +Open [http://localhost:30001](http://localhost:30001). You should see your +TanStack Start application served from the local Kubernetes cluster. + +### Step 5: Clean up Kubernetes resources + +When you're done testing: + +```console +$ kubectl delete -f tanstack-start-kubernetes.yaml +``` + +Expected output: + +```shell +deployment.apps "tanstack-start" deleted +service "tanstack-start-service" deleted +``` + +--- + +## Summary + +In this section, you deployed your TanStack Start application to a local +Kubernetes cluster using Docker Desktop. + +What you accomplished: + +- Created a Kubernetes Deployment and NodePort Service for your app +- Used `kubectl apply` to deploy the application locally +- Verified the app at `http://localhost:30001` +- Cleaned up Kubernetes resources after testing + +--- + +## Related resources + +- [Kubernetes documentation](https://kubernetes.io/docs/home/) – Core concepts, + workloads, and services +- [Deploy on Kubernetes with Docker Desktop](/manuals/desktop/use-desktop/kubernetes.md) – + Use Docker Desktop's built-in Kubernetes support +- [`kubectl` CLI reference](https://kubernetes.io/docs/reference/kubectl/) – + Manage clusters from the command line +- [Kubernetes Deployment resource](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) – + Manage and scale applications +- [Kubernetes Service resource](https://kubernetes.io/docs/concepts/services-networking/service/) – + Expose applications to internal and external traffic diff --git a/content/guides/tanstack-start/develop.md b/content/guides/tanstack-start/develop.md new file mode 100644 index 000000000000..6acda165210d --- /dev/null +++ b/content/guides/tanstack-start/develop.md @@ -0,0 +1,233 @@ +--- +title: Use containers for TanStack Start development +linkTitle: Develop your app +weight: 30 +keywords: tanstack start, development, node +description: Learn how to develop your TanStack Start application locally using containers. +--- + +## Prerequisites + +Complete [Containerize TanStack Start application](containerize.md). + +--- + +## Overview + +In this section, you'll set up production and development environments for your +containerized TanStack Start application using Docker Compose. This setup lets +you run a production build with the Nitro server and develop inside containers +using Vite's dev server with Compose Watch. + +You'll learn how to: + +- Configure separate containers for production and development +- Enable automatic file syncing using Compose Watch in development +- Debug and live-preview your changes without manual rebuilds + +--- + +## Automatically update services (development mode) + +Use Compose Watch to automatically sync source file changes into your +containerized development environment. File changes sync without needing to +restart or rebuild containers manually. + +## Step 1: Create a development Dockerfile + +Create a file named `Dockerfile.dev` in your project root with the following +content (matching the [sample project](https://github.com/kristiyan-velkov/docker-tanstack-start-sample)): + +```dockerfile +# ========================================= +# Development Dockerfile for TanStack Start +# ========================================= +ARG NODE_VERSION=24.14.0-alpine + +FROM node:${NODE_VERSION} AS dev + +WORKDIR /app + +COPY package.json package-lock.json* ./ + +RUN --mount=type=cache,target=/root/.npm npm ci + +COPY . . + +ENV HOST=0.0.0.0 + +EXPOSE 3000 + +CMD ["npm", "run", "dev"] +``` + +This file sets up a development environment that runs `npm run dev`, which +starts the Vite dev server on port 3000. + +### Step 2: Update your `compose.yml` file + +Open your `compose.yml` file and define two services: one for production +(`tanstack-start-prod`) and one for development (`tanstack-start-dev`). This +matches the [sample project](https://github.com/kristiyan-velkov/docker-tanstack-start-sample) structure. + +```yaml +services: + tanstack-start-prod: + build: + context: . + dockerfile: Dockerfile + args: + NODE_VERSION: 24.14.0-alpine + image: tanstack-start:prod + container_name: tanstack-start-prod + environment: + NODE_ENV: production + PORT: 3000 + HOST: 0.0.0.0 + ports: + - "3000:3000" + + tanstack-start-dev: + build: + context: . + dockerfile: Dockerfile.dev + args: + NODE_VERSION: 24.14.0-alpine + image: tanstack-start:dev + container_name: tanstack-start-dev + ports: + - "3000:3000" + develop: + watch: + - action: sync + path: . + target: /app + ignore: + - node_modules/ + - .output/ + - action: rebuild + path: package.json +``` + +- The `tanstack-start-prod` service builds and runs your production TanStack + Start app from the `.output` bundle. +- The `tanstack-start-dev` service runs the Vite dev server with hot module + replacement. +- `watch` triggers file sync with Compose Watch. +- The `rebuild` action for `package.json` reinstalls dependencies when the file + changes. + +> [!NOTE] +> For more details, see the official guide: +> [Use Compose Watch](/manuals/compose/how-tos/file-watch.md). + +### Step 3: Update vite.config.ts for Docker development + +To make Vite's development server reachable from outside the container, add +`server` options to your `vite.config.ts`: + +```ts {hl_lines="15-19",linenos=true} +import { defineConfig } from "vite"; +import { devtools } from "@tanstack/devtools-vite"; +import { tanstackStart } from "@tanstack/react-start/plugin/vite"; +import viteReact from "@vitejs/plugin-react"; +import viteTsConfigPaths from "vite-tsconfig-paths"; +import tailwindcss from "@tailwindcss/vite"; +import { nitro } from "nitro/vite"; + +const config = defineConfig({ + plugins: [ + devtools(), + nitro(), + viteTsConfigPaths({ projects: ["./tsconfig.json"] }), + tailwindcss(), + tanstackStart(), + viteReact(), + ], + server: { + host: true, + port: 3000, + strictPort: true, + }, +}); + +export default config; +``` + +> [!NOTE] +> The `server` options are required for running Vite inside Docker: +> +> - `host: true` lets the dev server accept connections from outside the +> container. +> - `port: 3000` matches the port exposed in Docker and the sample +> `package.json` dev script. +> - `strictPort: true` fails clearly if the port is unavailable. +> +> For full details, see the +> [Vite server configuration docs](https://vitejs.dev/config/server-options.html). + +After completing the previous steps, your project directory should contain: + +```text +├── docker-tanstack-start-sample/ +│ ├── Dockerfile +│ ├── Dockerfile.dev +│ ├── .dockerignore +│ ├── compose.yml +│ └── vite.config.ts +``` + +### Step 4: Start Compose Watch + +Run the following command from your project root: + +```console +$ docker compose watch tanstack-start-dev +``` + +### Step 5: Test Compose Watch with TanStack Start + +To verify that Compose Watch is working: + +1. Open a route file under `src/routes/` in your text editor. +2. Update visible text in the page component. +3. Save the file. +4. Open your browser at [http://localhost:3000](http://localhost:3000). + +You should see the updated content without rebuilding the container manually. + +--- + +## Summary + +In this section, you set up development and production workflows for your +TanStack Start application using Docker and Docker Compose. + +Here's what you achieved: + +- Created a `Dockerfile.dev` for local development with hot reloading +- Defined separate `tanstack-start-dev` and `tanstack-start-prod` services in + `compose.yml` +- Enabled file syncing using Compose Watch +- Verified live updates by modifying a route component + +With this setup, you can build, run, and iterate on your TanStack Start app +entirely within containers across environments. + +--- + +## Related resources + +- [Using Compose Watch](/manuals/compose/how-tos/file-watch.md) – Automatically + sync source changes during development +- [Multi-stage builds](/manuals/build/building/multi-stage/) – Create + production-ready Docker images +- [Dockerfile best practices](/build/building/best-practices/) – Write clean, + secure, and optimized Dockerfiles +- [Compose file reference](/compose/compose-file/) – Configure services in + `compose.yml` + +## Next steps + +In the next section, you'll learn how to run unit tests for your TanStack Start +application inside Docker containers. diff --git a/content/guides/tanstack-start/run-tests.md b/content/guides/tanstack-start/run-tests.md new file mode 100644 index 000000000000..f327b6176006 --- /dev/null +++ b/content/guides/tanstack-start/run-tests.md @@ -0,0 +1,185 @@ +--- +title: Run TanStack Start tests in a container +linkTitle: Run your tests +weight: 40 +keywords: tanstack start, test, vitest +description: Learn how to run your TanStack Start tests in a container. +--- + +## Prerequisites + +Complete all the previous sections of this guide, starting with +[Containerize TanStack Start application](containerize.md). + +## Overview + +Testing is a critical part of the development process. In this section, you'll +learn how to: + +- Run unit tests using Vitest inside a Docker container. +- Use Docker Compose to run tests in an isolated, reproducible environment. + +The [sample project](https://github.com/kristiyan-velkov/docker-tanstack-start-sample) uses [Vitest](https://vitest.dev/) with +[Testing Library](https://testing-library.com/) for component testing. + +--- + +## Run tests during development + +The sample project includes a `test` script in `package.json`: + +```json +"scripts": { + "test": "vitest run" +} +``` + +The sample project includes a test file at: + +```text +src/lib/utils.test.ts +``` + +If you're using your own project and haven't added Vitest yet, install the +testing tools: + +```console +$ npm install --save-dev vitest @vitejs/plugin-react @testing-library/react @testing-library/dom jsdom +``` + +Then add the `test` script to `package.json` as shown above. + +### Step 1: Configure Vitest + +Add a `test` block to your `vite.config.ts`: + +```ts {hl_lines="20-23",linenos=true} +import { defineConfig } from "vite"; +import { devtools } from "@tanstack/devtools-vite"; +import { tanstackStart } from "@tanstack/react-start/plugin/vite"; +import viteReact from "@vitejs/plugin-react"; +import viteTsConfigPaths from "vite-tsconfig-paths"; +import tailwindcss from "@tailwindcss/vite"; +import { nitro } from "nitro/vite"; + +const config = defineConfig({ + plugins: [ + devtools(), + nitro(), + viteTsConfigPaths({ projects: ["./tsconfig.json"] }), + tailwindcss(), + tanstackStart(), + viteReact(), + ], + server: { + host: true, + port: 3000, + strictPort: true, + }, + test: { + environment: "jsdom", + globals: true, + }, +}); + +export default config; +``` + +> [!NOTE] +> The `test` options configure Vitest for React component testing: +> +> - `environment: "jsdom"` simulates a browser-like environment. +> - `globals: true` exposes `describe`, `it`, and `expect` without imports. +> +> For more details, see the +> [Vitest configuration docs](https://vitest.dev/config/). + +### Step 2: Update compose.yml + +Add a `tanstack-start-test` service to your `compose.yml` file: + +```yaml {hl_lines="35-39",linenos=true} +services: + tanstack-start-prod: + build: + context: . + dockerfile: Dockerfile + args: + NODE_VERSION: 24.14.0-alpine + image: tanstack-start:prod + ports: + - "3000:3000" + + tanstack-start-dev: + build: + context: . + dockerfile: Dockerfile.dev + args: + NODE_VERSION: 24.14.0-alpine + image: tanstack-start:dev + ports: + - "3000:3000" + develop: + watch: + - action: sync + path: . + target: /app + ignore: + - node_modules/ + - .output/ + + tanstack-start-test: + build: + context: . + dockerfile: Dockerfile.dev + command: ["npm", "run", "test"] +``` + +The `tanstack-start-test` service reuses `Dockerfile.dev` and overrides the +default command to run `npm run test`. + +### Step 3: Run the tests + +Execute your test suite inside the container: + +```console +$ docker compose run --rm tanstack-start-test +``` + +This command starts the test service, runs Vitest, and removes the container +when tests finish. + +> [!NOTE] +> For more information about Compose commands, see the +> [Compose CLI reference](/reference/cli/docker/compose/). + +--- + +## Summary + +In this section, you learned how to run unit tests for your TanStack Start +application inside a Docker container using Vitest and Docker Compose. + +What you accomplished: + +- Configured Vitest in `vite.config.ts` for component testing +- Created a `tanstack-start-test` service in `compose.yml` +- Ran tests with `docker compose run --rm tanstack-start-test` + +--- + +## Related resources + +- [Dockerfile reference](/reference/dockerfile/) – Dockerfile instructions and + syntax +- [Best practices for writing Dockerfiles](/develop/develop-images/dockerfile_best-practices/) – + Write maintainable and secure Dockerfiles +- [Compose file reference](/compose/compose-file/) – Configure services in + `compose.yml` +- [`docker compose run` CLI reference](/reference/cli/docker/compose/run/) – + Run one-off commands in a service container + +## Next steps + +Next, you'll set up a CI/CD pipeline using GitHub Actions to build, test, and +push your TanStack Start application image to Docker Hub. From e931f557c6d8dfcd1cca0292282f830ce994dced Mon Sep 17 00:00:00 2001 From: "kristiyan.velkov" Date: Thu, 27 Aug 2026 16:07:06 +0300 Subject: [PATCH 2/4] Sync TanStack Start vite.config examples with sample app. Remove devtools plugin from guide snippets after simplifying the sample repository. --- content/guides/tanstack-start/develop.md | 4 +--- content/guides/tanstack-start/run-tests.md | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/content/guides/tanstack-start/develop.md b/content/guides/tanstack-start/develop.md index 6acda165210d..68b4b629e3ba 100644 --- a/content/guides/tanstack-start/develop.md +++ b/content/guides/tanstack-start/develop.md @@ -126,9 +126,8 @@ services: To make Vite's development server reachable from outside the container, add `server` options to your `vite.config.ts`: -```ts {hl_lines="15-19",linenos=true} +```ts {hl_lines="11-15",linenos=true} import { defineConfig } from "vite"; -import { devtools } from "@tanstack/devtools-vite"; import { tanstackStart } from "@tanstack/react-start/plugin/vite"; import viteReact from "@vitejs/plugin-react"; import viteTsConfigPaths from "vite-tsconfig-paths"; @@ -137,7 +136,6 @@ import { nitro } from "nitro/vite"; const config = defineConfig({ plugins: [ - devtools(), nitro(), viteTsConfigPaths({ projects: ["./tsconfig.json"] }), tailwindcss(), diff --git a/content/guides/tanstack-start/run-tests.md b/content/guides/tanstack-start/run-tests.md index f327b6176006..8efaeacc778c 100644 --- a/content/guides/tanstack-start/run-tests.md +++ b/content/guides/tanstack-start/run-tests.md @@ -53,9 +53,8 @@ Then add the `test` script to `package.json` as shown above. Add a `test` block to your `vite.config.ts`: -```ts {hl_lines="20-23",linenos=true} +```ts {hl_lines="16-19",linenos=true} import { defineConfig } from "vite"; -import { devtools } from "@tanstack/devtools-vite"; import { tanstackStart } from "@tanstack/react-start/plugin/vite"; import viteReact from "@vitejs/plugin-react"; import viteTsConfigPaths from "vite-tsconfig-paths"; @@ -64,7 +63,6 @@ import { nitro } from "nitro/vite"; const config = defineConfig({ plugins: [ - devtools(), nitro(), viteTsConfigPaths({ projects: ["./tsconfig.json"] }), tailwindcss(), From 70b1c78099c0c04874e7b3ab2fd2c9d4335c401d Mon Sep 17 00:00:00 2001 From: "kristiyan.velkov" Date: Thu, 27 Aug 2026 16:12:35 +0300 Subject: [PATCH 3/4] Fix Vale term violations in TanStack Start guide. Use Git and Vite canonical casing in containerize and develop pages. --- content/guides/tanstack-start/containerize.md | 4 ++-- content/guides/tanstack-start/develop.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/guides/tanstack-start/containerize.md b/content/guides/tanstack-start/containerize.md index cb766293c2cc..5830c009ce2d 100644 --- a/content/guides/tanstack-start/containerize.md +++ b/content/guides/tanstack-start/containerize.md @@ -12,8 +12,8 @@ Before you begin, make sure the following tools are installed and available on your system: - You have installed the latest version of [Docker Desktop](/get-started/get-docker.md). -- You have a [git client](https://git-scm.com/downloads). The examples in this - section use a command-line based git client, but you can use any client. +- You have a [Git client](https://git-scm.com/downloads). The examples in this + section use a command-line based Git client, but you can use any client. > [!NOTE] > New to Docker? Start with the [Docker basics](/get-started/docker-concepts/the-basics/what-is-a-container.md) guide to get familiar with key concepts like images, containers, and Dockerfiles. diff --git a/content/guides/tanstack-start/develop.md b/content/guides/tanstack-start/develop.md index 68b4b629e3ba..4cc67d76caed 100644 --- a/content/guides/tanstack-start/develop.md +++ b/content/guides/tanstack-start/develop.md @@ -121,10 +121,10 @@ services: > For more details, see the official guide: > [Use Compose Watch](/manuals/compose/how-tos/file-watch.md). -### Step 3: Update vite.config.ts for Docker development +### Step 3: Configure Vite for Docker development To make Vite's development server reachable from outside the container, add -`server` options to your `vite.config.ts`: +`server` options to your Vite config file (`vite.config.ts`): ```ts {hl_lines="11-15",linenos=true} import { defineConfig } from "vite"; From 9e77708a4fac27c06c11e7a57891e3b0002476c0 Mon Sep 17 00:00:00 2001 From: "kristiyan.velkov" Date: Thu, 27 Aug 2026 16:22:54 +0300 Subject: [PATCH 4/4] Polish TanStack Start guide prose for Vale formatting. Wrap the acknowledgment blockquote and use Vite canonical casing in run-tests prose. --- content/guides/tanstack-start/_index.md | 6 +++++- content/guides/tanstack-start/run-tests.md | 7 ++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/content/guides/tanstack-start/_index.md b/content/guides/tanstack-start/_index.md index bec4261de3db..16f1dadcfddc 100644 --- a/content/guides/tanstack-start/_index.md +++ b/content/guides/tanstack-start/_index.md @@ -26,7 +26,11 @@ consistent containerized environment from development to production. > **Acknowledgment** > -> Docker extends its sincere gratitude to [Kristiyan Velkov](https://www.linkedin.com/in/kristiyan-velkov-763130b3/) for authoring this guide and maintaining the [docker-tanstack-start-sample](https://github.com/kristiyan-velkov/docker-tanstack-start-sample) repository used throughout this guide. +> Docker extends its sincere gratitude to +> [Kristiyan Velkov](https://www.linkedin.com/in/kristiyan-velkov-763130b3/) for +> authoring this guide and maintaining the +> [docker-tanstack-start-sample](https://github.com/kristiyan-velkov/docker-tanstack-start-sample) +> repository used throughout this guide. --- diff --git a/content/guides/tanstack-start/run-tests.md b/content/guides/tanstack-start/run-tests.md index 8efaeacc778c..08a59d8bed1b 100644 --- a/content/guides/tanstack-start/run-tests.md +++ b/content/guides/tanstack-start/run-tests.md @@ -19,7 +19,8 @@ learn how to: - Run unit tests using Vitest inside a Docker container. - Use Docker Compose to run tests in an isolated, reproducible environment. -The [sample project](https://github.com/kristiyan-velkov/docker-tanstack-start-sample) uses [Vitest](https://vitest.dev/) with +The [sample project](https://github.com/kristiyan-velkov/docker-tanstack-start-sample) +uses [Vitest](https://vitest.dev/) with [Testing Library](https://testing-library.com/) for component testing. --- @@ -51,7 +52,7 @@ Then add the `test` script to `package.json` as shown above. ### Step 1: Configure Vitest -Add a `test` block to your `vite.config.ts`: +Add a `test` block to your Vite config file (`vite.config.ts`): ```ts {hl_lines="16-19",linenos=true} import { defineConfig } from "vite"; @@ -160,7 +161,7 @@ application inside a Docker container using Vitest and Docker Compose. What you accomplished: -- Configured Vitest in `vite.config.ts` for component testing +- Configured Vitest in your Vite config file for component testing - Created a `tanstack-start-test` service in `compose.yml` - Ran tests with `docker compose run --rm tanstack-start-test`