From f34b98337f34959d3343a56ad54225055df9d5ab Mon Sep 17 00:00:00 2001 From: gibbyb Date: Sat, 13 Sep 2025 03:34:48 -0500 Subject: [PATCH] Had to work some magic to remove some personal data from the git repo --- docker/Dockerfile | 55 ++++++++++++++++++++++++++++++++++++ docker/compose.yml | 70 ++++++++++++++++++++++++++++++++++++++++++++++ docker/env.example | 35 +++++++++++++++++++++++ docker/update | 49 ++++++++++++++++++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 docker/Dockerfile create mode 100644 docker/compose.yml create mode 100644 docker/env.example create mode 100755 docker/update diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..75a9838 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,55 @@ +# syntax=docker/dockerfile:1 + +# --- Bun on Alpine for build --- +FROM oven/bun:alpine AS base + +# --- deps: install node_modules with Bun --- +FROM base AS deps +RUN apk add --no-cache libc6-compat +WORKDIR /app + +# Copy package + whichever Bun lock file you have (optional) +COPY package.json bun.lockb* bun.lock* ./ +COPY tsconfig.base.json ./ +COPY apps/next/package.json ./apps/next/ + +# If bun.lockb exists, enforce frozen; otherwise install and generate it +RUN if [ -f bun.lockb ]; then \ + bun install --frozen-lockfile; \ + else \ + bun install; \ + fi + +# --- builder: build Next.js with Bun --- +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY --from=deps /app/tsconfig.base.json ./tsconfig.base.json +COPY apps/next ./apps/next +COPY packages ./packages +WORKDIR /app/apps/next +ENV NEXT_TELEMETRY_DISABLED=1 +RUN bun run build + +# --- runner: Node on Alpine to run server.js --- +FROM node:20-alpine AS runner +WORKDIR /app +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 + +# non-root user +RUN addgroup -S nodejs -g 1001 && adduser -S nextjs -u 1001 +COPY --from=builder /app/apps/next/public ./public +RUN mkdir .next && chown -R nextjs:nodejs .next +RUN mkdir -p .next/cache && chown -R nextjs:nodejs .next + +# Next standalone output +COPY --from=builder /app/apps/next/.next/standalone ./ +COPY --from=builder /app/apps/next/.next/static ./.next/static +COPY --from=builder /app/node_modules ./node_modules + +USER nextjs +EXPOSE 3000 +ENV PORT=3000 +ENV HOSTNAME=0.0.0.0 +CMD ["node", "server.js"] diff --git a/docker/compose.yml b/docker/compose.yml new file mode 100644 index 0000000..cbb91e1 --- /dev/null +++ b/docker/compose.yml @@ -0,0 +1,70 @@ +networks: + nginx-bridge: # You need to change this line to your defined network is as well + external: true + +services: + techtracker-next: + build: + context: ../ + dockerfile: ./docker/Dockerfile + image: ${NEXT_CONTAINER_NAME}:alpine + container_name: ${NEXT_CONTAINER_NAME} + env_file: [.env] + hostname: ${NEXT_CONTAINER_NAME} + domainname: ${NEXT_DOMAIN_NAME} + networks: ['${NETWORK:-nginx-bridge}'] + #ports: ['${NEXT_PORT}:3000'] + depends_on: ['convex-backend'] + tty: true + stdin_open: true + restart: unless-stopped + + convex-backend: + image: ghcr.io/get-convex/convex-backend:${BACKEND_TAG:-00bd92723422f3bff968230c94ccdeb8c1719832} + container_name: ${BACKEND_CONTAINER_NAME:-convex-backend} + hostname: ${BACKEND_CONTAINER_NAME:-convex-backend} + domainname: ${BACKEND_DOMAIN_NAME:-convex.gbrown.org} + networks: ['${NETWORK:-nginx-bridge}'] + #user: '1000:1000' + #ports: ['${BACKEND_PORT:-3210}:3210','${SITE_PROXY_PORT:-3211}:3211'] + volumes: [./data:/convex/data] + labels: ['com.centurylinklabs.watchtower.enable=true'] + env_file: ['.env'] + environment: + - INSTANCE_NAME + - INSTANCE_SECRET + - CONVEX_CLOUD_ORIGIN=${CONVEX_CLOUD_ORIGIN:-http://${BACKEND_CONTAINER_NAME:-convex-backend}:${BACKEND_PORT:-3210}} + - CONVEX_SITE_ORIGIN=${CONVEX_SITE_ORIGIN:-http://${BACKEND_CONTAINER_NAME:-convex-backend}:${SITE_PROXY_PORT:-3211}} + - DISABLE_BEACON=${DISABLE_BEACON:-} + - REDACT_LOGS_TO_CLIENT=${REDACT_LOGS_TO_CLIENT:-} + - DO_NOT_REQUIRE_SSL=${DO_NOT_REQUIRE_SSL:-} + #- DATABASE_URL=${DATABASE_URL:-} + stdin_open: true + tty: true + restart: unless-stopped + healthcheck: + test: curl -f http://localhost:3210/version + interval: 5s + start_period: 10s + stop_grace_period: 10s + stop_signal: SIGINT + convex-dashboard: + image: ghcr.io/get-convex/convex-dashboard:${DASHBOARD_TAG:-33cef775a8a6228cbacee4a09ac2c4073d62ed13} + container_name: ${DASHBOARD_CONTAINER_NAME:-convex-dashboard} + hostname: ${DASHBOARD_CONTAINER_NAME:-convex-dashboard} + domainname: ${DASHBOARD_DOMAIN_NAME:-dashboard.${BACKEND_DOMAIN_NAME:-convex.gbrown.org}} + networks: ['${NETWORK:-nginx-bridge}'] + #user: 1000:1000 + #ports: ['${DASHBOARD_PORT:-6791}:6791'] + labels: ['com.centurylinklabs.watchtower.enable=true'] + env_file: [.env] + environment: + - NEXT_PUBLIC_DEPLOYMENT_URL=${NEXT_PUBLIC_DEPLOYMENT_URL:-http://${BACKEND_CONTAINER_NAME:-convex-backend}:${PORT:-3210}} + depends_on: + convex-backend: + condition: service_healthy + stdin_open: true + tty: true + restart: unless-stopped + stop_grace_period: 10s + stop_signal: SIGINT diff --git a/docker/env.example b/docker/env.example new file mode 100644 index 0000000..32f8731 --- /dev/null +++ b/docker/env.example @@ -0,0 +1,35 @@ +# Next Envrionment Variables +NETWORK=nginx-bridge +NEXT_CONTAINER_NAME=techtracker-next +NEXT_DOMAIN_NAME=techtracker.gbrown.org +# Port is disabled by default as suggested +# config is to have reverse proxy on the same +# network so you can just forward to the +# port on the internal network. +NEXT_PORT=3000 + +# Convex Environment Variables +BACKEND_TAG=00bd92723422f3bff968230c94ccdeb8c1719832 +BACKEND_CONTAINER_NAME=tt-convex-backend +BACKEND_DOMAIN_NAME=convex.gbrown.org +#BACKEND_PORT= +#SITE_PROXY_PORT= +DASHBOARD_TAG=33cef775a8a6228cbacee4a09ac2c4073d62ed13 +DASHBOARD_CONTAINER_NAME=tt-convex-dashboard +DASHBOARD_DOMAIN=dashboard.convex.gbrown.org +#DASHBOARD_PORT +INSTANCE_NAME=Convex.gib +#INSTANCE_SECRET= +CONVEX_CLOUD_ORIGIN=https://api.convex.gbrown.org +CONVEX_SITE_ORIGIN=https://convex.gbrown.org +DISABLE_BEACON=true +REDACT_LOGS_TO_CLIENT=true +DO_NOT_REQUIRE_SSL=true +NEXT_PUBLIC_DEPLOYMENT_URL=https://api.convex.gbrown.org +#POSTGRES_URL= +#DATABASE_URL= +#CONVEX_RELEASE_VERSION_DEV= +#ACTIONS_USER_TIMEOUT_SECS= +#MYSQL_URL= +#RUST_LOG= +#RUST_BACKTRACE= diff --git a/docker/update b/docker/update new file mode 100755 index 0000000..2c2b51a --- /dev/null +++ b/docker/update @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +set -e # Exit immediately if a command exits with a non-zero status. + +# --- Configuration --- +COMPOSE_FILE="./docker/compose.yml" +DEFAULT_PROJECT_NAME="techtracker" +DEV_PROJECT_NAME="dev-techtracker" # The project name for dev mode + +COMPOSE_PROJECT_FLAG=${DEFAULT_PROJECT_NAME} # This will hold "-p dev-techtracker" if --dev is used + +# --- Function to display usage --- +usage() { + echo "Usage: $0 [OPTIONS]" + echo "Or: ./update.sh [OPTIONS]" # Assuming the script is named update.sh + echo "" + echo "Options:" + echo " -d, --dev Run in development mode, using project name '${DEV_PROJECT_NAME}'." + echo " Adds '-p ${DEV_PROJECT_NAME}' to docker compose commands." + echo " -h, --help Display this help message." + exit 1 +} + +# --- Parse arguments --- +while [[ "$#" -gt 0 ]]; do + case "$1" in + -d|--dev) + COMPOSE_PROJECT_FLAG=${DEV_PROJECT_NAME} + shift # Consume the argument + ;; + -h|--help) + usage + ;; + *) + echo "Error: Unknown argument '$1'" >&2 + usage + ;; + esac +done + +# --- Main Script Logic --- +echo "\n--- Pulling latest git changes ---\n" +git pull +echo "\n--- Building Docker Compose services ${COMPOSE_PROJECT_FLAG} ---\n" +sudo docker compose -p ${COMPOSE_PROJECT_FLAG} -f "${COMPOSE_FILE}" build +echo "\n--- Bringing down Docker Compose services ${COMPOSE_PROJECT_FLAG} ---\n" +sudo docker compose -p ${COMPOSE_PROJECT_FLAG} -f "${COMPOSE_FILE}" down +echo "\n--- Bringing up Docker Compose services ${COMPOSE_PROJECT_FLAG} in detached mode ---\n" +sudo docker compose -p ${COMPOSE_PROJECT_FLAG} -f "${COMPOSE_FILE}" up -d +echo "\n--- Script finished successfully ---\n"