fix: Update docker configuration for production deployment
- Fixed NEXT_PUBLIC_NOTES_API_URL to use public API endpoint - Updated docker-compose.yml environment format to proper YAML - Updated Dockerfiles to remove Gitea secrets and use .docker-deps - Added docker-prep.sh script for dependency packaging - Changed NODE_ENV back to development for compatibility with memory DB Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
4337793034
commit
3dd981198e
@ -1 +1 @@
|
||||
@bytelyst:registry=http://gitea.bytelyst.com:3300/api/packages/bytelyst/npm/
|
||||
@bytelyst:registry=http://localhost:3300/api/packages/bytelyst/npm/
|
||||
@ -4,12 +4,10 @@ WORKDIR /app/backend
|
||||
RUN npm install -g pnpm@10.6.5
|
||||
|
||||
COPY .npmrc.docker ./.npmrc
|
||||
COPY .docker-deps/ ../.docker-deps/
|
||||
COPY backend/package.json ./package.json
|
||||
|
||||
RUN --mount=type=secret,id=gitea_npm_token \
|
||||
TOKEN=$(cat /run/secrets/gitea_npm_token) && \
|
||||
echo "//gitea.bytelyst.com:3300/:_authToken=$TOKEN" >> .npmrc && \
|
||||
pnpm install --ignore-scripts --lockfile=false
|
||||
RUN pnpm install --ignore-scripts --lockfile=false
|
||||
|
||||
COPY backend/tsconfig.json ./tsconfig.json
|
||||
COPY backend/src/ ./src/
|
||||
|
||||
@ -1,37 +1,38 @@
|
||||
services:
|
||||
backend:
|
||||
container_name: notelett-backend
|
||||
build:
|
||||
context: .
|
||||
dockerfile: backend/Dockerfile
|
||||
ports:
|
||||
- "4016:4016"
|
||||
environment:
|
||||
- NODE_ENV=${NODE_ENV:-development}
|
||||
- PORT=4016
|
||||
- HOST=0.0.0.0
|
||||
- PRODUCT_ID=notelett
|
||||
- SERVICE_NAME=notelett-backend
|
||||
- JWT_SECRET=${JWT_SECRET:-dev-secret-change-me-at-least-32-characters}
|
||||
- COSMOS_ENDPOINT=${COSMOS_ENDPOINT:-}
|
||||
- COSMOS_KEY=${COSMOS_KEY:-}
|
||||
- COSMOS_DATABASE=${COSMOS_DATABASE:-bytelyst}
|
||||
- DB_PROVIDER=${DB_PROVIDER:-memory}
|
||||
- CORS_ORIGIN=${CORS_ORIGIN:-http://localhost:3000}
|
||||
- PLATFORM_SERVICE_URL=${PLATFORM_SERVICE_URL:-http://localhost:4003}
|
||||
- EXTRACTION_SERVICE_URL=${EXTRACTION_SERVICE_URL:-http://localhost:4005}
|
||||
- MCP_SERVER_URL=${MCP_SERVER_URL:-http://localhost:4007}
|
||||
- TELEMETRY_ENABLED=${TELEMETRY_ENABLED:-false}
|
||||
- FEATURE_FLAGS_ENABLED=${FEATURE_FLAGS_ENABLED:-false}
|
||||
- FIELD_ENCRYPT_ENABLED=${FIELD_ENCRYPT_ENABLED:-false}
|
||||
- FIELD_ENCRYPT_KEY_PROVIDER=${FIELD_ENCRYPT_KEY_PROVIDER:-memory}
|
||||
- LLM_PROVIDER=${LLM_PROVIDER:-mock}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
|
||||
- OPENAI_BASE_URL=${OPENAI_BASE_URL:-}
|
||||
- AZURE_OPENAI_ENDPOINT=${AZURE_OPENAI_ENDPOINT:-}
|
||||
- AZURE_OPENAI_API_KEY=${AZURE_OPENAI_API_KEY:-}
|
||||
- LLM_DEFAULT_MODEL=${LLM_DEFAULT_MODEL:-gpt-4o-mini}
|
||||
- LLM_VISION_MODEL=${LLM_VISION_MODEL:-gpt-4o}
|
||||
- LLM_EMBEDDING_MODEL=${LLM_EMBEDDING_MODEL:-text-embedding-3-small}
|
||||
NODE_ENV: development
|
||||
PORT: 4016
|
||||
HOST: 0.0.0.0
|
||||
PRODUCT_ID: notelett
|
||||
SERVICE_NAME: notelett-backend
|
||||
JWT_SECRET: ${JWT_SECRET:-dev-secret-change-me-at-least-32-characters}
|
||||
COSMOS_ENDPOINT: ${COSMOS_ENDPOINT:-}
|
||||
COSMOS_KEY: ${COSMOS_KEY:-}
|
||||
COSMOS_DATABASE: ${COSMOS_DATABASE:-bytelyst}
|
||||
DB_PROVIDER: ${DB_PROVIDER:-memory}
|
||||
CORS_ORIGIN: ${CORS_ORIGIN:-http://localhost:3000}
|
||||
PLATFORM_SERVICE_URL: ${PLATFORM_SERVICE_URL:-http://localhost:4003}
|
||||
EXTRACTION_SERVICE_URL: ${EXTRACTION_SERVICE_URL:-http://localhost:4005}
|
||||
MCP_SERVER_URL: ${MCP_SERVER_URL:-http://localhost:4007}
|
||||
TELEMETRY_ENABLED: ${TELEMETRY_ENABLED:-false}
|
||||
FEATURE_FLAGS_ENABLED: ${FEATURE_FLAGS_ENABLED:-false}
|
||||
FIELD_ENCRYPT_ENABLED: ${FIELD_ENCRYPT_ENABLED:-false}
|
||||
FIELD_ENCRYPT_KEY_PROVIDER: ${FIELD_ENCRYPT_KEY_PROVIDER:-memory}
|
||||
LLM_PROVIDER: ${LLM_PROVIDER:-mock}
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
|
||||
OPENAI_BASE_URL: ${OPENAI_BASE_URL:-}
|
||||
AZURE_OPENAI_ENDPOINT: ${AZURE_OPENAI_ENDPOINT:-}
|
||||
AZURE_OPENAI_API_KEY: ${AZURE_OPENAI_API_KEY:-}
|
||||
LLM_DEFAULT_MODEL: ${LLM_DEFAULT_MODEL:-gpt-4o-mini}
|
||||
LLM_VISION_MODEL: ${LLM_VISION_MODEL:-gpt-4o}
|
||||
LLM_EMBEDDING_MODEL: ${LLM_EMBEDDING_MODEL:-text-embedding-3-small}
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "node -e \"fetch('http://localhost:4016/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\""]
|
||||
@ -40,24 +41,25 @@ services:
|
||||
retries: 3
|
||||
|
||||
web:
|
||||
container_name: notelett-web
|
||||
build:
|
||||
context: .
|
||||
dockerfile: web/Dockerfile
|
||||
args:
|
||||
NEXT_PUBLIC_NOTES_API_URL: ${NEXT_PUBLIC_NOTES_API_URL:-http://localhost:4016/api}
|
||||
NEXT_PUBLIC_NOTES_API_URL: https://api.bytelyst.com/notelett
|
||||
NEXT_PUBLIC_PLATFORM_SERVICE_URL: ${NEXT_PUBLIC_PLATFORM_SERVICE_URL:-http://localhost:4003/api}
|
||||
ports:
|
||||
- "3000:3045"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- NEXT_PUBLIC_PRODUCT_NAME=NoteLett
|
||||
- NEXT_PUBLIC_PRODUCT_ID=notelett
|
||||
- NEXT_PUBLIC_NOTES_API_URL=${NEXT_PUBLIC_NOTES_API_URL:-http://localhost:4016/api}
|
||||
- NEXT_PUBLIC_PLATFORM_SERVICE_URL=${NEXT_PUBLIC_PLATFORM_SERVICE_URL:-http://localhost:4003/api}
|
||||
- NEXT_PUBLIC_EXTRACTION_SERVICE_URL=${EXTRACTION_SERVICE_URL:-http://localhost:4005}
|
||||
- NEXT_PUBLIC_MCP_SERVER_URL=${MCP_SERVER_URL:-http://localhost:4007}/api
|
||||
- NEXT_PUBLIC_DIAGNOSTICS_URL=${DIAGNOSTICS_URL:-http://localhost:3000}
|
||||
- NEXT_PUBLIC_TELEMETRY_TRANSPORT=fetch
|
||||
NODE_ENV: production
|
||||
NEXT_PUBLIC_PRODUCT_NAME: NoteLett
|
||||
NEXT_PUBLIC_PRODUCT_ID: notelett
|
||||
NEXT_PUBLIC_NOTES_API_URL: https://api.bytelyst.com/notelett
|
||||
NEXT_PUBLIC_PLATFORM_SERVICE_URL: ${NEXT_PUBLIC_PLATFORM_SERVICE_URL:-http://localhost:4003/api}
|
||||
NEXT_PUBLIC_EXTRACTION_SERVICE_URL: ${EXTRACTION_SERVICE_URL:-http://localhost:4005}
|
||||
NEXT_PUBLIC_MCP_SERVER_URL: ${MCP_SERVER_URL:-http://localhost:4007}/api
|
||||
NEXT_PUBLIC_DIAGNOSTICS_URL: ${DIAGNOSTICS_URL:-http://localhost:3000}
|
||||
NEXT_PUBLIC_TELEMETRY_TRANSPORT: fetch
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
|
||||
146
scripts/docker-prep.sh
Executable file
146
scripts/docker-prep.sh
Executable file
@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env bash
|
||||
# Pack @bytelyst/* tarballs from the sibling common-plat repo for
|
||||
# self-contained Docker builds that don't need the Gitea npm registry.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/docker-prep.sh # pack tarballs + rewrite package.json
|
||||
# ./scripts/docker-prep.sh --restore # undo rewrite
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
COMMON_PLAT="${COMMON_PLAT:-${REPO_DIR}/../learning_ai/learning_ai_common_plat}"
|
||||
if [[ ! -d "$COMMON_PLAT" && -d "${REPO_DIR}/../learning_ai_common_plat" ]]; then
|
||||
COMMON_PLAT="${REPO_DIR}/../learning_ai_common_plat"
|
||||
fi
|
||||
|
||||
TARBALL_DIR="${REPO_DIR}/.docker-deps"
|
||||
|
||||
# ── Restore mode ───────────────────────────────────────────────────
|
||||
if [[ "${1:-}" == "--restore" ]]; then
|
||||
echo "Restoring original package.json files..."
|
||||
for bak in $(find "$REPO_DIR" -name "package.json.bak" -not -path "*/node_modules/*"); do
|
||||
mv "$bak" "${bak%.bak}"
|
||||
echo " Restored ${bak%.bak}"
|
||||
done
|
||||
rm -rf "$TARBALL_DIR"
|
||||
echo "Done."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ── Pack mode ──────────────────────────────────────────────────────
|
||||
if [[ ! -d "$COMMON_PLAT" ]]; then
|
||||
echo "Common platform checkout not found: $COMMON_PLAT" >&2
|
||||
echo "Set COMMON_PLAT=/path/to/learning_ai_common_plat or place it at ../learning_ai/learning_ai_common_plat." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== docker-prep: packing @bytelyst/* tarballs ==="
|
||||
|
||||
rm -rf "$TARBALL_DIR"
|
||||
mkdir -p "$TARBALL_DIR"
|
||||
|
||||
# Build all packages first (--filter limits to packages/, skips services/)
|
||||
echo "Building @bytelyst/* packages..."
|
||||
(cd "$COMMON_PLAT" && pnpm -r --filter './packages/*' build)
|
||||
|
||||
# Pack each package and build a mapping of name → tarball filename
|
||||
# (uses a temp file instead of associative array for bash 3.2 compat)
|
||||
TARBALL_MAP_FILE=$(mktemp)
|
||||
trap 'rm -f "$TARBALL_MAP_FILE"' EXIT
|
||||
|
||||
for pkg_dir in "$COMMON_PLAT"/packages/*/; do
|
||||
pkg_name=$(node -p "require('${pkg_dir}package.json').name" 2>/dev/null || true)
|
||||
if [[ -z "$pkg_name" ]]; then continue; fi
|
||||
|
||||
echo " Packing $pkg_name..."
|
||||
tarball=$(cd "$pkg_dir" && pnpm pack --pack-destination "$TARBALL_DIR" 2>/dev/null | tail -1)
|
||||
filename=$(basename "$tarball")
|
||||
echo "${pkg_name}=${filename}" >> "$TARBALL_MAP_FILE"
|
||||
echo " -> $filename"
|
||||
done
|
||||
|
||||
# ── Rewrite package.json files ─────────────────────────────────────
|
||||
echo ""
|
||||
echo "Rewriting package.json @bytelyst/* refs to .docker-deps/ tarballs..."
|
||||
|
||||
rewrite_package_json() {
|
||||
local pkg_file="$1"
|
||||
local rel_prefix="$2" # relative path from package.json dir to repo root
|
||||
|
||||
if [[ ! -f "$pkg_file" ]]; then return; fi
|
||||
|
||||
# Backup
|
||||
cp "$pkg_file" "${pkg_file}.bak"
|
||||
|
||||
local tmp="${pkg_file}.tmp"
|
||||
cp "$pkg_file" "$tmp"
|
||||
|
||||
while IFS='=' read -r pkg_name tarball; do
|
||||
[[ -z "$pkg_name" ]] && continue
|
||||
node -e "
|
||||
const fs = require('fs');
|
||||
const file = process.argv[1];
|
||||
const pkgName = process.argv[2];
|
||||
const replacement = process.argv[3];
|
||||
const p = JSON.parse(fs.readFileSync(file, 'utf8'));
|
||||
for (const section of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
|
||||
if (p[section] && Object.prototype.hasOwnProperty.call(p[section], pkgName)) {
|
||||
p[section][pkgName] = replacement;
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(file, JSON.stringify(p, null, 2) + '\n');
|
||||
" "$tmp" "$pkg_name" "file:${rel_prefix}.docker-deps/${tarball}"
|
||||
done < "$TARBALL_MAP_FILE"
|
||||
|
||||
mv "$tmp" "$pkg_file"
|
||||
echo " Rewrote $pkg_file"
|
||||
}
|
||||
|
||||
# Backend package.json
|
||||
rewrite_package_json "${REPO_DIR}/backend/package.json" "../"
|
||||
|
||||
# Web package.json
|
||||
rewrite_package_json "${REPO_DIR}/web/package.json" "../"
|
||||
|
||||
# ── Inject pnpm.overrides for transitive @bytelyst/* deps ─────────
|
||||
# Tarball packages may depend on other @bytelyst/* packages (e.g.
|
||||
# @bytelyst/fastify-core → @bytelyst/errors). Without overrides, pnpm
|
||||
# tries to fetch them from the npm registry which fails.
|
||||
inject_overrides() {
|
||||
local pkg_file="$1"
|
||||
local rel_prefix="$2"
|
||||
|
||||
if [[ ! -f "$pkg_file" ]]; then return; fi
|
||||
|
||||
local overrides=""
|
||||
while IFS='=' read -r pkg_name tarball; do
|
||||
[[ -z "$pkg_name" ]] && continue
|
||||
if [[ -n "$overrides" ]]; then overrides="$overrides, "; fi
|
||||
overrides="$overrides\"${pkg_name}\": \"file:${rel_prefix}.docker-deps/${tarball}\""
|
||||
done < "$TARBALL_MAP_FILE"
|
||||
|
||||
if [[ -n "$overrides" ]]; then
|
||||
node -e "
|
||||
const fs = require('fs');
|
||||
const p = JSON.parse(fs.readFileSync('${pkg_file}', 'utf8'));
|
||||
p.pnpm = p.pnpm || {};
|
||||
p.pnpm.overrides = { ...(p.pnpm.overrides || {}), ...JSON.parse('{${overrides}}') };
|
||||
fs.writeFileSync('${pkg_file}', JSON.stringify(p, null, 2) + '\n');
|
||||
"
|
||||
echo " Injected pnpm.overrides into $pkg_file"
|
||||
fi
|
||||
}
|
||||
|
||||
inject_overrides "${REPO_DIR}/backend/package.json" "../"
|
||||
inject_overrides "${REPO_DIR}/web/package.json" "../"
|
||||
|
||||
echo ""
|
||||
echo "Done. Tarballs in $TARBALL_DIR"
|
||||
echo ""
|
||||
echo "To build Docker images:"
|
||||
echo " docker compose build"
|
||||
echo ""
|
||||
echo "To restore after build:"
|
||||
echo " ./scripts/docker-prep.sh --restore"
|
||||
@ -10,11 +10,9 @@ RUN npm config set strict-ssl false \
|
||||
&& npm install -g pnpm@10.6.5
|
||||
|
||||
COPY .npmrc.docker ./.npmrc
|
||||
COPY .docker-deps/ /app/.docker-deps/
|
||||
COPY .docker-deps/ ../.docker-deps/
|
||||
COPY web/package.json ./package.json
|
||||
RUN --mount=type=secret,id=gitea_npm_token \
|
||||
export GITEA_NPM_TOKEN="$(cat /run/secrets/gitea_npm_token 2>/dev/null || echo '')" && \
|
||||
pnpm install --ignore-scripts --lockfile=false
|
||||
RUN pnpm install --ignore-scripts --lockfile=false
|
||||
|
||||
COPY web/next.config.ts ./next.config.ts
|
||||
COPY web/tsconfig.json ./tsconfig.json
|
||||
|
||||
Loading…
Reference in New Issue
Block a user