-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathDockerfile.crosscompile
More file actions
163 lines (137 loc) · 6.29 KB
/
Dockerfile.crosscompile
File metadata and controls
163 lines (137 loc) · 6.29 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# syntax=docker/dockerfile:1.6
# Cross-compilation optimized Multi-stage Dockerfile for LiveReview
# Fully Dockerized: builds UI and Go binaries in Docker, then assembles runtime image.
# Stage 1: Build React UI once (architecture-agnostic)
FROM --platform=$BUILDPLATFORM node:18-alpine AS ui-builder
WORKDIR /app/ui
# Copy package files and install dependencies
COPY ui/package*.json ./
RUN echo "📦 Installing UI dependencies..." && npm ci --progress=true
# Copy UI source and build production assets
COPY ui/ ./
# Copy .env.selfhosted for self-hosted Docker builds (LIVEREVIEW_IS_CLOUD=false)
COPY .env.selfhosted ../.env.selfhosted
# Build UI with explicit SELFHOSTED mode to ensure is_cloud=false
RUN echo "🔨 Building UI for SELF-HOSTED deployment (is_cloud=false)..." && \
LIVEREVIEW_BUILD_MODE=selfhosted CI=true NODE_ENV=production npm run build:obfuscated && \
echo "✅ UI build completed successfully"
# Stage 2: Cross-compile all binaries for all architectures in one stage
FROM --platform=$BUILDPLATFORM golang:1.24-alpine AS builder
# Accept target platform args (injected by buildx)
ARG TARGETOS
ARG TARGETARCH
ARG TARGETVARIANT
ARG GO_BUILD_TAGS=""
WORKDIR /app
# Install build dependencies
RUN echo "🔧 Installing Go build dependencies..." && \
apk add --no-cache curl git ca-certificates
# Copy Go module files and download dependencies
COPY go.mod go.sum ./
RUN echo "📦 Downloading Go dependencies..." && \
go mod download && go mod verify && \
echo "Go dependencies downloaded successfully"
# Copy source code
COPY . .
# Copy UI assets from UI builder stage
COPY --from=ui-builder /app/ui/dist ./ui/dist
# Build arguments for version injection (will be set by lrops.py)
ARG VERSION=development
ARG BUILD_TIME=unknown
ARG GIT_COMMIT=unknown
# Cross-compile main Go binary for target architecture
RUN echo "🔨 Cross-compiling LiveReview binary for ${TARGETOS}/${TARGETARCH}${TARGETVARIANT:+/${TARGETVARIANT}} with version: ${VERSION} (tags: ${GO_BUILD_TAGS})" && \
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
$([ "$TARGETARCH" = "arm" ] && [ "$TARGETVARIANT" = "v7" ] && echo "GOARM=7" || echo "") \
go build \
-tags "${GO_BUILD_TAGS}" \
-ldflags="-w -s -X main.version=${VERSION} -X main.buildTime=${BUILD_TIME} -X main.gitCommit=${GIT_COMMIT}" \
-v -o /out/livereview . && \
echo "LiveReview binary cross-compiled successfully for ${TARGETARCH} (tags: ${GO_BUILD_TAGS})"
# Cross-compile River CLI and UI tools for target architecture
RUN echo "🌊 Cross-compiling River CLI and UI tools for ${TARGETARCH}..." && \
# Create temporary directory for building tools
mkdir -p /tmp/tools && \
cd /tmp/tools && \
# Initialize a temporary module
go mod init temp && \
# Add the dependencies
go get github.com/riverqueue/river/cmd/river@latest && \
go get riverqueue.com/riverui/cmd/riverui@latest && \
# Cross-compile River CLI
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
$([ "$TARGETARCH" = "arm" ] && [ "$TARGETVARIANT" = "v7" ] && echo "GOARM=7" || echo "") \
go build -o /out/river github.com/riverqueue/river/cmd/river && \
# Cross-compile River UI
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
$([ "$TARGETARCH" = "arm" ] && [ "$TARGETVARIANT" = "v7" ] && echo "GOARM=7" || echo "") \
go build -o /out/riverui riverqueue.com/riverui/cmd/riverui && \
cd /app && rm -rf /tmp/tools && \
echo "River tools cross-compiled successfully for ${TARGETARCH}"
# Download dbmate for target architecture
RUN echo "� Installing dbmate for ${TARGETARCH}..." && \
DBMATE_ARCH=$(case ${TARGETARCH} in \
"amd64") echo "amd64" ;; \
"arm64") echo "arm64" ;; \
"arm") echo "arm" ;; \
*) echo "amd64" ;; \
esac) && \
curl -fsSL -o /out/dbmate \
https://github.com/amacneil/dbmate/releases/latest/download/dbmate-linux-${DBMATE_ARCH} && \
chmod +x /out/dbmate && \
echo "dbmate installed successfully for ${TARGETARCH}"
# Stage 3: Create minimal runtime container for target architecture
FROM alpine:3.18
LABEL maintainer="LiveReview Team"
LABEL description="LiveReview - AI-powered code review tool (cross-compiled)"
# Install runtime dependencies
RUN echo "🔧 Installing runtime dependencies..." && \
apk add --no-cache \
ca-certificates \
curl \
postgresql-client \
tzdata \
&& rm -rf /var/cache/apk/* && \
echo "Runtime dependencies installed successfully"
# Create non-root user for security
RUN echo "👤 Creating non-root user..." && \
addgroup -g 1001 -S livereview && \
adduser -u 1001 -S livereview -G livereview && \
echo "User 'livereview' created successfully"
# Create directories
RUN echo "📁 Creating application directories..." && \
mkdir -p /app/db/migrations /app/data /app/logs && \
chown -R livereview:livereview /app && \
echo "Directories created and permissions set"
# Copy architecture-specific binaries from builder stage
COPY --from=builder /out/dbmate /usr/local/bin/dbmate
COPY --from=builder /out/river /usr/local/bin/river
COPY --from=builder /out/riverui /usr/local/bin/riverui
COPY --from=builder /out/livereview /app/livereview
COPY --from=builder /app/livereview.toml /app/livereview.toml
COPY --from=builder /app/db/migrations/ /app/db/migrations/
# Copy the startup script
COPY docker-entrypoint.sh /app/docker-entrypoint.sh
RUN chmod +x /app/docker-entrypoint.sh && \
chmod +x /usr/local/bin/dbmate && \
chmod +x /usr/local/bin/river && \
chmod +x /usr/local/bin/riverui && \
chmod +x /app/livereview
RUN echo "📋 Final image contents:" && \
ls -la /app/ && \
echo "📦 Installed binaries:" && \
ls -la /usr/local/bin/ && \
echo "📊 Database migrations:" && \
ls -la /app/db/migrations/ && \
echo "Migration count: $(ls /app/db/migrations/*.sql | wc -l)" && \
echo "✅ LiveReview cross-compiled container build completed successfully!"
# Switch to non-root user
USER livereview
WORKDIR /app
# Expose ports for backend API (8888), frontend (8081), and River UI (8080)
EXPOSE 8888 8081 8080
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8888/api/health || exit 1
# Default command - runs the startup script that handles the full initialization sequence
CMD ["/app/docker-entrypoint.sh"]