-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathDockerfile
More file actions
105 lines (79 loc) · 3.66 KB
/
Copy pathDockerfile
File metadata and controls
105 lines (79 loc) · 3.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# BugPin Dockerfile
# Multi-stage build for optimized production image
ARG BUN_VERSION=1.4.0
# =============================================================================
# Stage 1: Builder
# =============================================================================
FROM oven/bun:${BUN_VERSION}-alpine AS builder
# Pull latest Alpine security patches (libssl3, libcrypto3, musl, zlib, etc.)
RUN apk update && apk upgrade --no-cache
WORKDIR /app
# Install dependencies first (better layer caching)
# Copy package manifests and the required lockfile
COPY package.json bun.lock ./
COPY src/server/package.json ./src/server/
COPY src/admin/package.json ./src/admin/
COPY src/widget/package.json ./src/widget/
# Install the exact dependency graph from the committed lockfile
RUN bun install --frozen-lockfile
# Copy source code
COPY . .
# Stamp version from build arg (set by CI from git tag) into package.json
# so both the admin build and server runtime pick it up automatically
ARG APP_VERSION
RUN if [ -n "$APP_VERSION" ]; then \
node -e "const fs=require('fs');const p='./package.json';const j=JSON.parse(fs.readFileSync(p));j.version='$APP_VERSION';fs.writeFileSync(p,JSON.stringify(j,null,2)+'\n');"; \
fi
# Build admin portal and widget
RUN bun run build:admin && bun run build:widget
# Build EE module (compile TypeScript to JavaScript) if submodule is present
# Create stub files for CE-only builds so COPY commands don't fail
RUN if [ -d "ee/src" ]; then cd ee && bun run build.ts; fi && \
mkdir -p ee/dist && \
(test -f ee/package.json || echo '{}' > ee/package.json) && \
(test -f ee/tsconfig.json || echo '{}' > ee/tsconfig.json)
# =============================================================================
# Stage 2: Production
# =============================================================================
FROM oven/bun:${BUN_VERSION}-alpine
WORKDIR /app
# Pull latest Alpine security patches (libssl3, libcrypto3, musl, zlib, etc.)
# and install tini for signal handling and wget for health checks.
RUN apk update && apk upgrade --no-cache && apk add --no-cache tini wget
# Copy the workspace manifests and lockfile before installing server dependencies
COPY package.json bun.lock ./
COPY src/server/package.json ./src/server/
COPY src/admin/package.json ./src/admin/
COPY src/widget/package.json ./src/widget/
RUN bun install --production --frozen-lockfile --filter @bugpin/server
# Copy server source (Bun runs TypeScript directly)
COPY src/server ./src/server
COPY src/shared ./src/shared
# Copy Enterprise Edition compiled output only (no TypeScript source)
COPY --from=builder /app/ee/dist ./ee/dist
COPY --from=builder /app/ee/package.json ./ee/package.json
COPY --from=builder /app/ee/tsconfig.json ./ee/tsconfig.json
# Copy built frontend assets from builder
COPY --from=builder /app/dist/admin ./dist/admin
# Copy entire widget source directory (includes dist/ and test-widget.html)
COPY --from=builder /app/src/widget ./src/widget
# Copy default branding assets (required for fallback when no custom branding uploaded)
COPY --from=builder /app/src/admin/public/branding ./src/admin/public/branding
# Create data directory and fix permissions for bun user
RUN mkdir -p /data/uploads && chown -R bun:bun /data /app
# Environment configuration
ENV NODE_ENV=production
ENV DATA_DIR=/data
ENV PORT=7300
ENV HOST=0.0.0.0
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -q -O /dev/null http://localhost:7300/health || exit 1
# Switch to non-root user
USER bun
# Expose port
EXPOSE 7300
# Use tini as init system for proper signal handling
ENTRYPOINT ["/sbin/tini", "--"]
# Start server
CMD ["bun", "run", "src/server/index.ts"]