From f36fb60375d1d6ed7960b87729809d1fba9046c2 Mon Sep 17 00:00:00 2001 From: Giuseppe Scuglia Date: Wed, 12 Nov 2025 14:31:00 +0100 Subject: [PATCH 1/7] chore: create dockerfile --- .dockerignore | 16 ++++++++++++ Dockerfile | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 18 +++++++++++++ next.config.ts | 1 + 4 files changed, 104 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..e7edc6d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,16 @@ +Dockerfile +.dockerignore +node_modules +npm-debug.log +README.md +.next +.git +.gitignore +.vscode +.idea +*.md +.DS_Store +.env*.local +coverage +.vercel + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5ad6488 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,69 @@ +FROM node:20-alpine AS base + +# Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat + +# Install pnpm +RUN corepack enable && corepack prepare pnpm@latest --activate + +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json pnpm-lock.yaml* ./ +RUN pnpm install --frozen-lockfile + +# Rebuild the source code only when needed +FROM base AS builder + +# Install pnpm +RUN corepack enable && corepack prepare pnpm@latest --activate + +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +# ENV NEXT_TELEMETRY_DISABLED=1 + +RUN pnpm build + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV=production +# Uncomment the following line in case you want to disable telemetry during runtime. +# ENV NEXT_TELEMETRY_DISABLED=1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public + +# Set the correct permission for prerender cache +RUN mkdir .next +RUN chown nextjs:nodejs .next + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT=3000 + +# server.js is created by next build from the standalone output +# https://nextjs.org/docs/pages/api-reference/config/next-config-js/output +ENV HOSTNAME="0.0.0.0" + +# server.js is created by next build from the standalone output +# https://nextjs.org/docs/pages/api-reference/next-config-js/output +CMD ["node", "server.js"] + diff --git a/README.md b/README.md index e215bc4..fe88f43 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,24 @@ You can start editing the page by modifying `app/page.tsx`. The page auto-update This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. +## Docker + +This project includes Docker support for containerized deployments. + +### Build the Docker image + +```bash +docker build -t toolhive-cloud-ui . +``` + +### Run the container + +```bash +docker run -p 3000:3000 toolhive-cloud-ui +``` + +The application will be available at [http://localhost:3000](http://localhost:3000). + ## Learn More To learn more about Next.js, take a look at the following resources: diff --git a/next.config.ts b/next.config.ts index 66e1566..30d7f8b 100644 --- a/next.config.ts +++ b/next.config.ts @@ -3,6 +3,7 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { /* config options here */ reactCompiler: true, + output: "standalone", }; export default nextConfig; From 1f639b485e648cc538257fc101aadb080eb79055 Mon Sep 17 00:00:00 2001 From: Giuseppe Scuglia Date: Wed, 12 Nov 2025 14:35:41 +0100 Subject: [PATCH 2/7] leftover --- Dockerfile | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5ad6488..322ac11 100644 --- a/Dockerfile +++ b/Dockerfile @@ -62,8 +62,4 @@ ENV PORT=3000 # server.js is created by next build from the standalone output # https://nextjs.org/docs/pages/api-reference/config/next-config-js/output ENV HOSTNAME="0.0.0.0" - -# server.js is created by next build from the standalone output -# https://nextjs.org/docs/pages/api-reference/next-config-js/output -CMD ["node", "server.js"] - +CMD ["node", "server.js"] \ No newline at end of file From 45c126be2990f6cc430bc16574bb9a7e002f5424 Mon Sep 17 00:00:00 2001 From: Giuseppe Scuglia Date: Wed, 12 Nov 2025 14:37:39 +0100 Subject: [PATCH 3/7] chore: use pinned pnpm version --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 322ac11..5aa0121 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ FROM base AS deps RUN apk add --no-cache libc6-compat # Install pnpm -RUN corepack enable && corepack prepare pnpm@latest --activate +RUN corepack enable && corepack prepare pnpm@10.18.3 --activate WORKDIR /app @@ -18,7 +18,7 @@ RUN pnpm install --frozen-lockfile FROM base AS builder # Install pnpm -RUN corepack enable && corepack prepare pnpm@latest --activate +RUN corepack enable && corepack prepare pnpm@10.18.3 --activate WORKDIR /app COPY --from=deps /app/node_modules ./node_modules From 4e5032a24671c4b1ad0e684afded24748e9b693f Mon Sep 17 00:00:00 2001 From: Giuseppe Scuglia Date: Wed, 12 Nov 2025 15:19:49 +0100 Subject: [PATCH 4/7] chore: node version 22 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5aa0121..1009418 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:20-alpine AS base +FROM node:22-alpine AS base # Install dependencies only when needed FROM base AS deps From 5b7e14e7a37f2926cf23d4493b429afe0aef7e09 Mon Sep 17 00:00:00 2001 From: Giuseppe Scuglia Date: Wed, 12 Nov 2025 17:25:26 +0100 Subject: [PATCH 5/7] chore: add makefile --- Makefile | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 29 ++++++++++++++++++++++++++--- 2 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3e8f920 --- /dev/null +++ b/Makefile @@ -0,0 +1,52 @@ +.PHONY: help build start stop restart logs clean dev shell rebuild + +# Variables +IMAGE_NAME := toolhive-cloud-ui +CONTAINER_NAME := toolhive-cloud-ui +PORT := 3000 + +## Show this help message +help: + @echo "Available commands:" + @grep -E '^## ' $(MAKEFILE_LIST) | sed 's/## //' | awk 'NR%2==1{printf "\033[36m%-15s\033[0m ",$$1} NR%2==0{print}' + +## Build the production docker image +build: + @echo "Building ${IMAGE_NAME} Docker image..." + @docker build -t $(IMAGE_NAME) . + +## Start the production docker container +start: + @docker run -d -p $(PORT):$(PORT) --name $(CONTAINER_NAME) $(IMAGE_NAME) + @echo "Container $(CONTAINER_NAME) running at http://localhost:$(PORT)" + +## Stop the production docker container +stop: + @docker stop $(CONTAINER_NAME) > /dev/null 2>&1 || true + @docker rm $(CONTAINER_NAME) > /dev/null 2>&1 || true + @echo "Container $(CONTAINER_NAME) stopped" + +## Restart the production docker container +restart: stop start + +## Show container logs (follow mode) +logs: + docker logs -f $(CONTAINER_NAME) + +## Remove container and image +clean: stop + @docker rmi $(IMAGE_NAME) > /dev/null 2>&1 || true + @echo "Cleanup complete" + +## Run development server locally +dev: + pnpm dev + +## Open shell in running container +shell: + docker exec -it $(CONTAINER_NAME) /bin/sh + +## Clean and rebuild image +rebuild: clean build + @echo "Rebuild complete" + diff --git a/README.md b/README.md index fe88f43..ac8384a 100644 --- a/README.md +++ b/README.md @@ -24,15 +24,38 @@ This project uses [`next/font`](https://nextjs.org/docs/app/building-your-applic This project includes Docker support for containerized deployments. -### Build the Docker image +### Using Makefile (Recommended) ```bash -docker build -t toolhive-cloud-ui . +# Show all available commands +make help + +# Build Docker image +make build + +# Start container +make start + +# View logs +make logs + +# Stop container +make stop + +# Clean up (remove container and image) +make clean + +# Rebuild from scratch +make rebuild ``` -### Run the container +### Using Docker commands directly ```bash +# Build the Docker image +docker build -t toolhive-cloud-ui . + +# Run the container docker run -p 3000:3000 toolhive-cloud-ui ``` From 4d57396d1651d2e674a542d7f030dcfdc07274fc Mon Sep 17 00:00:00 2001 From: Giuseppe Scuglia Date: Wed, 12 Nov 2025 17:44:29 +0100 Subject: [PATCH 6/7] leftover --- README.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/README.md b/README.md index ac8384a..cd01ecc 100644 --- a/README.md +++ b/README.md @@ -47,17 +47,6 @@ make clean # Rebuild from scratch make rebuild -``` - -### Using Docker commands directly - -```bash -# Build the Docker image -docker build -t toolhive-cloud-ui . - -# Run the container -docker run -p 3000:3000 toolhive-cloud-ui -``` The application will be available at [http://localhost:3000](http://localhost:3000). From 19a721767954a049735e1ddfe65e95d067bdfcb6 Mon Sep 17 00:00:00 2001 From: Giuseppe Scuglia Date: Wed, 12 Nov 2025 17:47:07 +0100 Subject: [PATCH 7/7] chore: add docker image tag to makefile --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 3e8f920..4033492 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ # Variables IMAGE_NAME := toolhive-cloud-ui +IMAGE_TAG := latest CONTAINER_NAME := toolhive-cloud-ui PORT := 3000 @@ -12,12 +13,12 @@ help: ## Build the production docker image build: - @echo "Building ${IMAGE_NAME} Docker image..." - @docker build -t $(IMAGE_NAME) . + @echo "Building ${IMAGE_NAME}:${IMAGE_TAG} Docker image..." + @docker build -t $(IMAGE_NAME):$(IMAGE_TAG) . ## Start the production docker container start: - @docker run -d -p $(PORT):$(PORT) --name $(CONTAINER_NAME) $(IMAGE_NAME) + @docker run -d -p $(PORT):$(PORT) --name $(CONTAINER_NAME) $(IMAGE_NAME):$(IMAGE_TAG) @echo "Container $(CONTAINER_NAME) running at http://localhost:$(PORT)" ## Stop the production docker container @@ -35,7 +36,7 @@ logs: ## Remove container and image clean: stop - @docker rmi $(IMAGE_NAME) > /dev/null 2>&1 || true + @docker rmi $(IMAGE_NAME):$(IMAGE_TAG) > /dev/null 2>&1 || true @echo "Cleanup complete" ## Run development server locally