mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:01:09 +02:00
feat(infra): add sveltekit-base image and build-app script for Mac Mini
- Add docker/Dockerfile.sveltekit-base: pre-built base with all 34 shared packages (mirrors nestjs-base pattern), eliminates redundant COPY/build steps from individual web Dockerfiles - Add scripts/mac-mini/build-app.sh: stops monitoring stack before build to free RAM, auto-restarts on exit (trap cleanup) - Migrate todo web Dockerfile to use sveltekit-base:local (47 COPY lines → 2, 4 build steps → 0) - Update CD workflow to build sveltekit-base when deploying web apps Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c681a5d66a
commit
cdfbfcd13e
4 changed files with 233 additions and 61 deletions
21
.github/workflows/cd-macmini.yml
vendored
21
.github/workflows/cd-macmini.yml
vendored
|
|
@ -243,12 +243,29 @@ jobs:
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
NEEDS_WEB_BASE=false
|
||||||
|
if [ "$DEPLOY_ALL" == "true" ]; then
|
||||||
|
NEEDS_WEB_BASE=true
|
||||||
|
else
|
||||||
|
for svc in $SERVICES; do
|
||||||
|
case "$svc" in *-web) NEEDS_WEB_BASE=true; break ;; esac
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$NEEDS_BASE" == "true" ]; then
|
if [ "$NEEDS_BASE" == "true" ]; then
|
||||||
echo "=== Building shared NestJS base image ==="
|
echo "=== Building shared NestJS base image ==="
|
||||||
docker build -f docker/Dockerfile.nestjs-base -t nestjs-base:local . 2>&1 | tail -5
|
docker build -f docker/Dockerfile.nestjs-base -t nestjs-base:local . 2>&1 | tail -5
|
||||||
echo "Base image built"
|
echo "NestJS base image built"
|
||||||
else
|
else
|
||||||
echo "No backends to deploy, skipping base image"
|
echo "No backends to deploy, skipping NestJS base image"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$NEEDS_WEB_BASE" == "true" ]; then
|
||||||
|
echo "=== Building shared SvelteKit base image ==="
|
||||||
|
docker build -f docker/Dockerfile.sveltekit-base -t sveltekit-base:local . 2>&1 | tail -5
|
||||||
|
echo "SvelteKit base image built"
|
||||||
|
else
|
||||||
|
echo "No web apps to deploy, skipping SvelteKit base image"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Build and deploy services
|
- name: Build and deploy services
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
# Build stage
|
# Build stage - inherits pre-built shared packages from sveltekit-base
|
||||||
FROM node:20-alpine AS builder
|
FROM sveltekit-base:local AS builder
|
||||||
|
|
||||||
# Build arguments for SvelteKit static env vars
|
# Build arguments for SvelteKit static env vars
|
||||||
ARG PUBLIC_BACKEND_URL=http://todo-backend:3018
|
ARG PUBLIC_BACKEND_URL=http://todo-backend:3018
|
||||||
|
|
@ -10,66 +10,13 @@ ARG PUBLIC_MANA_CORE_AUTH_URL=http://mana-core-auth:3001
|
||||||
ENV PUBLIC_BACKEND_URL=$PUBLIC_BACKEND_URL
|
ENV PUBLIC_BACKEND_URL=$PUBLIC_BACKEND_URL
|
||||||
ENV PUBLIC_MANA_CORE_AUTH_URL=$PUBLIC_MANA_CORE_AUTH_URL
|
ENV PUBLIC_MANA_CORE_AUTH_URL=$PUBLIC_MANA_CORE_AUTH_URL
|
||||||
|
|
||||||
# Install pnpm
|
# Copy app-specific packages
|
||||||
RUN corepack enable && corepack prepare pnpm@9.15.0 --activate
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# Copy root workspace files
|
|
||||||
COPY pnpm-workspace.yaml ./
|
|
||||||
COPY package.json ./
|
|
||||||
COPY pnpm-lock.yaml ./
|
|
||||||
|
|
||||||
# --- AUTO-GENERATED COPY STATEMENTS (do not edit manually) ---
|
|
||||||
COPY patches/ ./patches/
|
|
||||||
COPY packages/shared-api-client ./packages/shared-api-client
|
|
||||||
COPY packages/shared-app-onboarding ./packages/shared-app-onboarding
|
|
||||||
COPY packages/shared-auth ./packages/shared-auth
|
|
||||||
COPY packages/shared-auth-ui ./packages/shared-auth-ui
|
|
||||||
COPY packages/shared-branding ./packages/shared-branding
|
|
||||||
COPY packages/shared-error-tracking ./packages/shared-error-tracking
|
|
||||||
COPY packages/shared-feedback-service ./packages/shared-feedback-service
|
|
||||||
COPY packages/shared-feedback-types ./packages/shared-feedback-types
|
|
||||||
COPY packages/shared-feedback-ui ./packages/shared-feedback-ui
|
|
||||||
COPY packages/shared-help-content ./packages/shared-help-content
|
|
||||||
COPY packages/shared-help-types ./packages/shared-help-types
|
|
||||||
COPY packages/shared-help-ui ./packages/shared-help-ui
|
|
||||||
COPY packages/shared-i18n ./packages/shared-i18n
|
|
||||||
COPY packages/shared-icons ./packages/shared-icons
|
|
||||||
COPY packages/shared-profile-ui ./packages/shared-profile-ui
|
|
||||||
COPY packages/shared-pwa ./packages/shared-pwa
|
|
||||||
COPY packages/shared-splitscreen ./packages/shared-splitscreen
|
|
||||||
COPY packages/shared-stores ./packages/shared-stores
|
|
||||||
COPY packages/shared-subscription-ui ./packages/shared-subscription-ui
|
|
||||||
COPY packages/shared-tags ./packages/shared-tags
|
|
||||||
COPY packages/shared-tailwind ./packages/shared-tailwind
|
|
||||||
COPY packages/shared-theme ./packages/shared-theme
|
|
||||||
COPY packages/shared-theme-ui ./packages/shared-theme-ui
|
|
||||||
COPY packages/shared-types ./packages/shared-types
|
|
||||||
COPY packages/shared-ui ./packages/shared-ui
|
|
||||||
COPY packages/shared-utils ./packages/shared-utils
|
|
||||||
COPY packages/shared-vite-config ./packages/shared-vite-config
|
|
||||||
COPY packages/spiral-db ./packages/spiral-db
|
|
||||||
COPY apps/todo/packages/shared ./apps/todo/packages/shared
|
COPY apps/todo/packages/shared ./apps/todo/packages/shared
|
||||||
# --- END AUTO-GENERATED ---
|
|
||||||
|
|
||||||
COPY apps/todo/apps/web ./apps/todo/apps/web
|
COPY apps/todo/apps/web ./apps/todo/apps/web
|
||||||
|
|
||||||
# Install dependencies
|
# Install app-specific dependencies
|
||||||
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile
|
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \
|
||||||
|
pnpm install --frozen-lockfile --ignore-scripts
|
||||||
# Build shared packages that need building
|
|
||||||
WORKDIR /app/packages/shared-vite-config
|
|
||||||
RUN pnpm build
|
|
||||||
|
|
||||||
WORKDIR /app/packages/shared-auth
|
|
||||||
RUN pnpm build || true
|
|
||||||
|
|
||||||
WORKDIR /app/packages/shared-error-tracking
|
|
||||||
RUN pnpm build
|
|
||||||
|
|
||||||
WORKDIR /app/packages/shared-pwa
|
|
||||||
RUN pnpm build
|
|
||||||
|
|
||||||
# Build the web app
|
# Build the web app
|
||||||
WORKDIR /app/apps/todo/apps/web
|
WORKDIR /app/apps/todo/apps/web
|
||||||
|
|
|
||||||
76
docker/Dockerfile.sveltekit-base
Normal file
76
docker/Dockerfile.sveltekit-base
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
# Shared builder base for all SvelteKit web apps
|
||||||
|
# Contains pre-installed shared packages and pre-built dependencies
|
||||||
|
#
|
||||||
|
# Usage in web Dockerfiles:
|
||||||
|
# FROM sveltekit-base:local AS builder
|
||||||
|
# COPY apps/myapp/packages/shared ./apps/myapp/packages/shared
|
||||||
|
# COPY apps/myapp/apps/web ./apps/myapp/apps/web
|
||||||
|
# RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile
|
||||||
|
# WORKDIR /app/apps/myapp/apps/web
|
||||||
|
# RUN pnpm exec svelte-kit sync
|
||||||
|
# RUN NODE_OPTIONS="--max-old-space-size=4096" pnpm build
|
||||||
|
|
||||||
|
FROM node:20-alpine
|
||||||
|
|
||||||
|
# Install pnpm
|
||||||
|
RUN corepack enable && corepack prepare pnpm@9.15.0 --activate
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy root workspace files
|
||||||
|
COPY pnpm-workspace.yaml ./
|
||||||
|
COPY package.json ./
|
||||||
|
COPY pnpm-lock.yaml ./
|
||||||
|
COPY patches/ ./patches/
|
||||||
|
|
||||||
|
# Copy ALL shared packages used by SvelteKit web apps
|
||||||
|
COPY packages/credit-operations ./packages/credit-operations
|
||||||
|
COPY packages/qr-export ./packages/qr-export
|
||||||
|
COPY packages/shared-api-client ./packages/shared-api-client
|
||||||
|
COPY packages/shared-app-onboarding ./packages/shared-app-onboarding
|
||||||
|
COPY packages/shared-auth ./packages/shared-auth
|
||||||
|
COPY packages/shared-auth-ui ./packages/shared-auth-ui
|
||||||
|
COPY packages/shared-branding ./packages/shared-branding
|
||||||
|
COPY packages/shared-config ./packages/shared-config
|
||||||
|
COPY packages/shared-error-tracking ./packages/shared-error-tracking
|
||||||
|
COPY packages/shared-feedback-service ./packages/shared-feedback-service
|
||||||
|
COPY packages/shared-feedback-types ./packages/shared-feedback-types
|
||||||
|
COPY packages/shared-feedback-ui ./packages/shared-feedback-ui
|
||||||
|
COPY packages/shared-help-content ./packages/shared-help-content
|
||||||
|
COPY packages/shared-help-types ./packages/shared-help-types
|
||||||
|
COPY packages/shared-help-ui ./packages/shared-help-ui
|
||||||
|
COPY packages/shared-i18n ./packages/shared-i18n
|
||||||
|
COPY packages/shared-icons ./packages/shared-icons
|
||||||
|
COPY packages/shared-profile-ui ./packages/shared-profile-ui
|
||||||
|
COPY packages/shared-pwa ./packages/shared-pwa
|
||||||
|
COPY packages/shared-splitscreen ./packages/shared-splitscreen
|
||||||
|
COPY packages/shared-stores ./packages/shared-stores
|
||||||
|
COPY packages/shared-subscription-types ./packages/shared-subscription-types
|
||||||
|
COPY packages/shared-subscription-ui ./packages/shared-subscription-ui
|
||||||
|
COPY packages/shared-tags ./packages/shared-tags
|
||||||
|
COPY packages/shared-tailwind ./packages/shared-tailwind
|
||||||
|
COPY packages/shared-theme ./packages/shared-theme
|
||||||
|
COPY packages/shared-theme-ui ./packages/shared-theme-ui
|
||||||
|
COPY packages/shared-types ./packages/shared-types
|
||||||
|
COPY packages/shared-ui ./packages/shared-ui
|
||||||
|
COPY packages/shared-utils ./packages/shared-utils
|
||||||
|
COPY packages/shared-vite-config ./packages/shared-vite-config
|
||||||
|
COPY packages/spiral-db ./packages/spiral-db
|
||||||
|
COPY packages/wallpaper-generator ./packages/wallpaper-generator
|
||||||
|
|
||||||
|
# Install dependencies (shared packages only - app deps added later)
|
||||||
|
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \
|
||||||
|
pnpm install --frozen-lockfile --ignore-scripts
|
||||||
|
|
||||||
|
# Build shared packages in dependency order
|
||||||
|
RUN cd packages/shared-vite-config && pnpm build \
|
||||||
|
&& cd /app/packages/shared-auth && pnpm build || true \
|
||||||
|
&& cd /app/packages/shared-error-tracking && pnpm build \
|
||||||
|
&& cd /app/packages/shared-pwa && pnpm build \
|
||||||
|
&& cd /app/packages/shared-tags && pnpm build \
|
||||||
|
&& cd /app/packages/shared-api-client && pnpm build 2>/dev/null || true \
|
||||||
|
&& cd /app/packages/credit-operations && pnpm build 2>/dev/null || true \
|
||||||
|
&& cd /app/packages/spiral-db && pnpm build 2>/dev/null || true
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
132
scripts/mac-mini/build-app.sh
Executable file
132
scripts/mac-mini/build-app.sh
Executable file
|
|
@ -0,0 +1,132 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Build and deploy specific app containers on the Mac Mini
|
||||||
|
# Automatically frees RAM by stopping monitoring before build
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./scripts/mac-mini/build-app.sh todo-web
|
||||||
|
# ./scripts/mac-mini/build-app.sh todo-web todo-backend
|
||||||
|
# ./scripts/mac-mini/build-app.sh --all-web # rebuild all web apps
|
||||||
|
# ./scripts/mac-mini/build-app.sh --base # rebuild base images only
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
COMPOSE_FILE="$PROJECT_ROOT/docker-compose.macmini.yml"
|
||||||
|
DOCKER="${DOCKER_CMD:-/usr/local/bin/docker}"
|
||||||
|
|
||||||
|
# Monitoring services (compose service names)
|
||||||
|
MONITORING_SERVICES=(
|
||||||
|
grafana
|
||||||
|
umami
|
||||||
|
victoriametrics
|
||||||
|
pushgateway
|
||||||
|
cadvisor
|
||||||
|
postgres-exporter
|
||||||
|
redis-exporter
|
||||||
|
node-exporter
|
||||||
|
vmalert
|
||||||
|
alertmanager
|
||||||
|
alert-notifier
|
||||||
|
glitchtip
|
||||||
|
glitchtip-worker
|
||||||
|
)
|
||||||
|
|
||||||
|
# Track if we stopped monitoring
|
||||||
|
MONITORING_STOPPED=false
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
if [ "$MONITORING_STOPPED" = true ]; then
|
||||||
|
echo ""
|
||||||
|
echo "=== Restarting monitoring stack ==="
|
||||||
|
$DOCKER compose -f "$COMPOSE_FILE" start "${MONITORING_SERVICES[@]}" 2>/dev/null || true
|
||||||
|
echo "Monitoring restored."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Always restart monitoring on exit (success, failure, or interrupt)
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
stop_monitoring() {
|
||||||
|
echo "=== Stopping monitoring to free RAM ==="
|
||||||
|
$DOCKER compose -f "$COMPOSE_FILE" stop "${MONITORING_SERVICES[@]}" 2>/dev/null || true
|
||||||
|
MONITORING_STOPPED=true
|
||||||
|
|
||||||
|
# Also prune dangling build cache
|
||||||
|
$DOCKER builder prune -f 2>/dev/null | tail -1 || true
|
||||||
|
echo "RAM freed."
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
build_base_images() {
|
||||||
|
echo "=== Building sveltekit-base image ==="
|
||||||
|
$DOCKER build -f "$PROJECT_ROOT/docker/Dockerfile.sveltekit-base" -t sveltekit-base:local "$PROJECT_ROOT" 2>&1 | tail -5
|
||||||
|
echo "sveltekit-base:local built."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "=== Building nestjs-base image ==="
|
||||||
|
$DOCKER build -f "$PROJECT_ROOT/docker/Dockerfile.nestjs-base" -t nestjs-base:local "$PROJECT_ROOT" 2>&1 | tail -5
|
||||||
|
echo "nestjs-base:local built."
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
build_services() {
|
||||||
|
local services=("$@")
|
||||||
|
echo "=== Building: ${services[*]} ==="
|
||||||
|
$DOCKER compose -f "$COMPOSE_FILE" build --no-cache "${services[@]}"
|
||||||
|
echo ""
|
||||||
|
echo "=== Restarting: ${services[*]} ==="
|
||||||
|
$DOCKER compose -f "$COMPOSE_FILE" up -d --no-deps "${services[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Main ---
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
echo "Usage: $0 <service...> | --base | --all-web"
|
||||||
|
echo ""
|
||||||
|
echo "Examples:"
|
||||||
|
echo " $0 todo-web # Build & restart todo web"
|
||||||
|
echo " $0 todo-web todo-backend # Build & restart both"
|
||||||
|
echo " $0 --base # Rebuild base images"
|
||||||
|
echo " $0 --all-web # Rebuild all web apps"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Pull latest code
|
||||||
|
echo "=== Pulling latest code ==="
|
||||||
|
git pull
|
||||||
|
|
||||||
|
# Free RAM
|
||||||
|
stop_monitoring
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
--base)
|
||||||
|
build_base_images
|
||||||
|
;;
|
||||||
|
--all-web)
|
||||||
|
build_base_images
|
||||||
|
# Find all web services in compose
|
||||||
|
WEB_SERVICES=$($DOCKER compose -f "$COMPOSE_FILE" config --services 2>/dev/null | grep '\-web$' || true)
|
||||||
|
if [ -n "$WEB_SERVICES" ]; then
|
||||||
|
build_services $WEB_SERVICES
|
||||||
|
else
|
||||||
|
echo "No web services found."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
build_services "$@"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Build complete ==="
|
||||||
|
|
||||||
|
# Show status of built services
|
||||||
|
for svc in "$@"; do
|
||||||
|
if [ "$svc" != "--base" ] && [ "$svc" != "--all-web" ]; then
|
||||||
|
STATUS=$($DOCKER compose -f "$COMPOSE_FILE" ps --format '{{.Name}}\t{{.Status}}' "$svc" 2>/dev/null || echo "$svc: unknown")
|
||||||
|
echo " $STATUS"
|
||||||
|
fi
|
||||||
|
done
|
||||||
Loading…
Add table
Add a link
Reference in a new issue