Skip to content

Commit 149538b

Browse files
feat: Add multi-platform Docker build and push commands, update Dockerfiles to accept target architecture
1 parent c7288c2 commit 149538b

File tree

6 files changed

+242
-20
lines changed

6 files changed

+242
-20
lines changed

.goreleaser.yml

Lines changed: 152 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,46 @@ release:
3131
# Docker images
3232
dockers:
3333
- image_templates:
34-
- "ghcr.io/developerkunal/openmorph:{{ .Tag }}"
35-
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}"
36-
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}"
37-
- "ghcr.io/developerkunal/openmorph:latest"
34+
- "ghcr.io/developerkunal/openmorph:{{ .Tag }}-amd64"
35+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}-amd64"
36+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-amd64"
37+
- "ghcr.io/developerkunal/openmorph:latest-amd64"
3838
dockerfile: Dockerfile
39+
use: buildx
40+
goos: linux
41+
goarch: amd64
3942
build_flag_templates:
4043
- "--pull"
44+
- "--platform=linux/amd64"
4145
- "--label=org.opencontainers.image.created={{.Date}}"
4246
- "--label=org.opencontainers.image.title={{.ProjectName}}"
4347
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
4448
- "--label=org.opencontainers.image.version={{.Version}}"
4549
- "--label=org.opencontainers.image.source={{.GitURL}}"
4650
- "--build-arg=VERSION={{.Version}}"
51+
- "--build-arg=TARGETARCH=amd64"
52+
extra_files:
53+
- go.mod
54+
- go.sum
55+
- image_templates:
56+
- "ghcr.io/developerkunal/openmorph:{{ .Tag }}-arm64"
57+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}-arm64"
58+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-arm64"
59+
- "ghcr.io/developerkunal/openmorph:latest-arm64"
60+
dockerfile: Dockerfile
61+
use: buildx
62+
goos: linux
63+
goarch: arm64
64+
build_flag_templates:
65+
- "--pull"
66+
- "--platform=linux/arm64"
67+
- "--label=org.opencontainers.image.created={{.Date}}"
68+
- "--label=org.opencontainers.image.title={{.ProjectName}}"
69+
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
70+
- "--label=org.opencontainers.image.version={{.Version}}"
71+
- "--label=org.opencontainers.image.source={{.GitURL}}"
72+
- "--build-arg=VERSION={{.Version}}"
73+
- "--build-arg=TARGETARCH=arm64"
4774
extra_files:
4875
- go.mod
4976
- go.sum
@@ -52,18 +79,139 @@ dockers:
5279
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}-distroless"
5380
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-distroless"
5481
dockerfile: Dockerfile.distroless
82+
use: buildx
83+
goos: linux
84+
goarch: amd64
85+
build_flag_templates:
86+
- "--pull"
87+
- "--platform=linux/amd64"
88+
- "--label=org.opencontainers.image.created={{.Date}}"
89+
- "--label=org.opencontainers.image.title={{.ProjectName}}"
90+
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
91+
- "--label=org.opencontainers.image.version={{.Version}}"
92+
- "--label=org.opencontainers.image.source={{.GitURL}}"
93+
- "--build-arg=VERSION={{.Version}}"
94+
- "--build-arg=TARGETARCH=amd64"
95+
extra_files:
96+
- go.mod
97+
- go.sum
98+
- image_templates:
99+
- "ghcr.io/developerkunal/openmorph:{{ .Tag }}-distroless-arm64"
100+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}-distroless-arm64"
101+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-distroless-arm64"
102+
dockerfile: Dockerfile.distroless
103+
use: buildx
104+
goos: linux
105+
goarch: arm64
55106
build_flag_templates:
56107
- "--pull"
108+
- "--platform=linux/arm64"
57109
- "--label=org.opencontainers.image.created={{.Date}}"
58110
- "--label=org.opencontainers.image.title={{.ProjectName}}"
59111
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
60112
- "--label=org.opencontainers.image.version={{.Version}}"
61113
- "--label=org.opencontainers.image.source={{.GitURL}}"
62114
- "--build-arg=VERSION={{.Version}}"
115+
- "--build-arg=TARGETARCH=arm64"
63116
extra_files:
64117
- go.mod
65118
- go.sum
66119

120+
# Add dev variant Docker builds
121+
- image_templates:
122+
- "ghcr.io/developerkunal/openmorph:{{ .Tag }}-dev-amd64"
123+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}-dev-amd64"
124+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-dev-amd64"
125+
- "ghcr.io/developerkunal/openmorph:latest-dev-amd64"
126+
dockerfile: Dockerfile.dev
127+
use: buildx
128+
goos: linux
129+
goarch: amd64
130+
build_flag_templates:
131+
- "--pull"
132+
- "--platform=linux/amd64"
133+
- "--label=org.opencontainers.image.created={{.Date}}"
134+
- "--label=org.opencontainers.image.title={{.ProjectName}}"
135+
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
136+
- "--label=org.opencontainers.image.version={{.Version}}"
137+
- "--label=org.opencontainers.image.source={{.GitURL}}"
138+
- "--build-arg=VERSION={{.Version}}"
139+
- "--build-arg=TARGETARCH=amd64"
140+
extra_files:
141+
- go.mod
142+
- go.sum
143+
- image_templates:
144+
- "ghcr.io/developerkunal/openmorph:{{ .Tag }}-dev-arm64"
145+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}-dev-arm64"
146+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-dev-arm64"
147+
- "ghcr.io/developerkunal/openmorph:latest-dev-arm64"
148+
dockerfile: Dockerfile.dev
149+
use: buildx
150+
goos: linux
151+
goarch: arm64
152+
build_flag_templates:
153+
- "--pull"
154+
- "--platform=linux/arm64"
155+
- "--label=org.opencontainers.image.created={{.Date}}"
156+
- "--label=org.opencontainers.image.title={{.ProjectName}}"
157+
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
158+
- "--label=org.opencontainers.image.version={{.Version}}"
159+
- "--label=org.opencontainers.image.source={{.GitURL}}"
160+
- "--build-arg=VERSION={{.Version}}"
161+
- "--build-arg=TARGETARCH=arm64"
162+
extra_files:
163+
- go.mod
164+
- go.sum
165+
166+
# Docker manifests for multi-platform support
167+
docker_manifests:
168+
- name_template: "ghcr.io/developerkunal/openmorph:{{ .Tag }}"
169+
image_templates:
170+
- "ghcr.io/developerkunal/openmorph:{{ .Tag }}-amd64"
171+
- "ghcr.io/developerkunal/openmorph:{{ .Tag }}-arm64"
172+
- name_template: "ghcr.io/developerkunal/openmorph:v{{ .Major }}"
173+
image_templates:
174+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}-amd64"
175+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}-arm64"
176+
- name_template: "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}"
177+
image_templates:
178+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-amd64"
179+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-arm64"
180+
- name_template: "ghcr.io/developerkunal/openmorph:latest"
181+
image_templates:
182+
- "ghcr.io/developerkunal/openmorph:latest-amd64"
183+
- "ghcr.io/developerkunal/openmorph:latest-arm64"
184+
# Distroless multi-platform manifests
185+
- name_template: "ghcr.io/developerkunal/openmorph:{{ .Tag }}-distroless"
186+
image_templates:
187+
- "ghcr.io/developerkunal/openmorph:{{ .Tag }}-distroless"
188+
- "ghcr.io/developerkunal/openmorph:{{ .Tag }}-distroless-arm64"
189+
- name_template: "ghcr.io/developerkunal/openmorph:v{{ .Major }}-distroless"
190+
image_templates:
191+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}-distroless"
192+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}-distroless-arm64"
193+
- name_template: "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-distroless"
194+
image_templates:
195+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-distroless"
196+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-distroless-arm64"
197+
# Dev multi-platform manifests
198+
- name_template: "ghcr.io/developerkunal/openmorph:{{ .Tag }}-dev"
199+
image_templates:
200+
- "ghcr.io/developerkunal/openmorph:{{ .Tag }}-dev-amd64"
201+
- "ghcr.io/developerkunal/openmorph:{{ .Tag }}-dev-arm64"
202+
- name_template: "ghcr.io/developerkunal/openmorph:v{{ .Major }}-dev"
203+
image_templates:
204+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}-dev-amd64"
205+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}-dev-arm64"
206+
- name_template: "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-dev"
207+
image_templates:
208+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-dev-amd64"
209+
- "ghcr.io/developerkunal/openmorph:v{{ .Major }}.{{ .Minor }}-dev-arm64"
210+
- name_template: "ghcr.io/developerkunal/openmorph:latest-dev"
211+
image_templates:
212+
- "ghcr.io/developerkunal/openmorph:latest-dev-amd64"
213+
- "ghcr.io/developerkunal/openmorph:latest-dev-arm64"
214+
67215
# Homebrew tap
68216
brews:
69217
- name: openmorph

Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ RUN go mod download && go mod verify
1919
# Copy source code
2020
COPY . .
2121

22-
# Accept version as build argument
22+
# Accept version and target architecture as build arguments
2323
ARG VERSION=dev
24+
ARG TARGETARCH
2425

2526
# Build the binary with optimizations for container usage
26-
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
27+
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build \
2728
-ldflags="-w -s -extldflags '-static' -X 'github.com/developerkunal/OpenMorph/cmd.version=${VERSION}'" \
2829
-a -installsuffix cgo \
2930
-o openmorph \

Dockerfile.dev

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ RUN go mod download && go mod verify
1010

1111
COPY . .
1212

13-
# Accept version as build argument
13+
# Accept version and target architecture as build arguments
1414
ARG VERSION=dev
15+
ARG TARGETARCH
1516

16-
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
17+
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build \
1718
-ldflags="-w -s -extldflags '-static' -X 'github.com/developerkunal/OpenMorph/cmd.version=${VERSION}'" \
1819
-a -installsuffix cgo \
1920
-o openmorph \

Dockerfile.distroless

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,25 @@ RUN go mod download && go mod verify
2323
# Copy source code
2424
COPY . .
2525

26-
# Accept version as build argument
26+
# Accept version and target architecture as build arguments
2727
ARG VERSION=dev
28+
ARG TARGETARCH
2829

2930
# Build the binary with optimizations for container usage
30-
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
31+
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build \
3132
-ldflags="-w -s -extldflags '-static' -X 'github.com/developerkunal/OpenMorph/cmd.version=${VERSION}'" \
3233
-a -installsuffix cgo \
3334
-o openmorph \
3435
./main.go
3536

36-
# Final distroless stage with Node.js support for swagger-cli
37-
FROM gcr.io/distroless/nodejs22-debian12:nonroot
37+
# Final minimal stage - using alpine for smaller size
38+
FROM alpine:latest
3839

39-
# Copy Node.js runtime and npm packages from nodejs stage
40-
COPY --from=nodejs /usr/local/bin/node /usr/local/bin/node
41-
COPY --from=nodejs /usr/local/lib/node_modules /usr/local/lib/node_modules
40+
# Install minimal runtime dependencies
41+
RUN apk add --no-cache ca-certificates nodejs npm && \
42+
npm install -g @apidevtools/swagger-cli && \
43+
addgroup -g 1001 -S openmorph && \
44+
adduser -u 1001 -S openmorph -G openmorph
4245

4346
# Copy certificates and timezone data from builder
4447
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
@@ -50,8 +53,8 @@ COPY --from=builder /build/openmorph /usr/local/bin/openmorph
5053
# Copy swagger-cli binary with proper permissions (make it executable)
5154
COPY --from=nodejs --chmod=755 /usr/local/lib/node_modules/@apidevtools/swagger-cli/bin/swagger-cli.js /usr/local/bin/swagger-cli
5255

53-
# Use non-root user (already set in distroless base)
54-
USER nonroot:nonroot
56+
# Use non-root user
57+
USER openmorph:openmorph
5558

5659
# Set working directory
5760
WORKDIR /workspace

Makefile

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ help:
4848
@echo ""
4949
@echo "Docker Commands:"
5050
@echo " docker-build Build all Docker images (production, distroless, dev)"
51+
@echo " docker-build-multiplatform Build multi-platform images (production, distroless, dev) for AMD64 + ARM64 locally"
52+
@echo " docker-push-multiplatform Build and push multi-platform images (production, distroless, dev) for AMD64 + ARM64"
5153
@echo " docker-test Test Docker images with health checks"
5254
@echo " docker-run Run OpenMorph in production Docker container"
5355
@echo " docker-dev Start interactive development container"
@@ -192,6 +194,73 @@ docker-build:
192194
docker build --build-arg VERSION=v$(VERSION) -f Dockerfile.distroless -t openmorph:distroless .
193195
docker build --build-arg VERSION=v$(VERSION) -f Dockerfile.dev -t openmorph:dev .
194196

197+
docker-build-multiplatform:
198+
@echo "Building multi-platform Docker images with version $(VERSION)..."
199+
@echo "Creating buildx builder if needed..."
200+
docker buildx create --name multiplatform --use --driver docker-container 2>/dev/null || docker buildx use multiplatform
201+
docker buildx inspect --bootstrap
202+
@echo "Building multi-platform production images..."
203+
docker buildx build \
204+
--platform linux/amd64,linux/arm64 \
205+
--build-arg VERSION=v$(VERSION) \
206+
--tag ghcr.io/developerkunal/openmorph:v$(VERSION) \
207+
--tag ghcr.io/developerkunal/openmorph:latest \
208+
--tag ghcr.io/developerkunal/openmorph:v$(shell echo $(VERSION) | cut -d. -f1) \
209+
--tag ghcr.io/developerkunal/openmorph:v$(shell echo $(VERSION) | cut -d. -f1-2) \
210+
.
211+
@echo "Building multi-platform distroless images..."
212+
docker buildx build \
213+
--platform linux/amd64,linux/arm64 \
214+
--build-arg VERSION=v$(VERSION) \
215+
--file Dockerfile.distroless \
216+
--tag ghcr.io/developerkunal/openmorph:v$(VERSION)-distroless \
217+
--tag ghcr.io/developerkunal/openmorph:latest-distroless \
218+
.
219+
@echo "Building multi-platform dev images..."
220+
docker buildx build \
221+
--platform linux/amd64,linux/arm64 \
222+
--build-arg VERSION=v$(VERSION) \
223+
--file Dockerfile.dev \
224+
--tag ghcr.io/developerkunal/openmorph:v$(VERSION)-dev \
225+
--tag ghcr.io/developerkunal/openmorph:latest-dev \
226+
.
227+
@echo "✅ All multi-platform images built locally!"
228+
229+
docker-push-multiplatform:
230+
@echo "Pushing multi-platform Docker images with version $(VERSION)..."
231+
@echo "Creating buildx builder if needed..."
232+
docker buildx create --name multiplatform --use --driver docker-container 2>/dev/null || docker buildx use multiplatform
233+
docker buildx inspect --bootstrap
234+
@echo "Building and pushing multi-platform production images..."
235+
docker buildx build \
236+
--platform linux/amd64,linux/arm64 \
237+
--build-arg VERSION=v$(VERSION) \
238+
--tag ghcr.io/developerkunal/openmorph:v$(VERSION) \
239+
--tag ghcr.io/developerkunal/openmorph:latest \
240+
--tag ghcr.io/developerkunal/openmorph:v$(shell echo $(VERSION) | cut -d. -f1) \
241+
--tag ghcr.io/developerkunal/openmorph:v$(shell echo $(VERSION) | cut -d. -f1-2) \
242+
--push \
243+
.
244+
@echo "Building and pushing multi-platform distroless images..."
245+
docker buildx build \
246+
--platform linux/amd64,linux/arm64 \
247+
--build-arg VERSION=v$(VERSION) \
248+
--file Dockerfile.distroless \
249+
--tag ghcr.io/developerkunal/openmorph:v$(VERSION)-distroless \
250+
--tag ghcr.io/developerkunal/openmorph:latest-distroless \
251+
--push \
252+
.
253+
@echo "Building and pushing multi-platform dev images..."
254+
docker buildx build \
255+
--platform linux/amd64,linux/arm64 \
256+
--build-arg VERSION=v$(VERSION) \
257+
--file Dockerfile.dev \
258+
--tag ghcr.io/developerkunal/openmorph:v$(VERSION)-dev \
259+
--tag ghcr.io/developerkunal/openmorph:latest-dev \
260+
--push \
261+
.
262+
@echo "✅ All multi-platform images built and pushed!"
263+
195264
docker-test:
196265
@echo "Testing Docker images..."
197266
docker run --rm -v $(PWD)/scripts:/scripts openmorph:dev /scripts/healthcheck.sh || true

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ OpenMorph is a production-grade CLI and TUI tool for transforming OpenAPI vendor
5454
#### Quick Start with Docker
5555

5656
```bash
57-
# Pull the latest image
57+
# Pull the latest image (automatically selects correct architecture)
5858
docker pull ghcr.io/developerkunal/openmorph:latest
5959

6060
# Transform files in current directory
@@ -70,8 +70,8 @@ docker run --rm -v $(pwd):/workspace ghcr.io/developerkunal/openmorph:latest \
7070

7171
**Production Images (Multi-platform: linux/amd64, linux/arm64):**
7272

73-
- `ghcr.io/developerkunal/openmorph:latest` - Always latest release
74-
- `ghcr.io/developerkunal/openmorph:v1.0.0` - Specific version (immutable)
73+
- `ghcr.io/developerkunal/openmorph:latest` - Latest release (auto-selects platform)
74+
- `ghcr.io/developerkunal/openmorph:v1.0.0` - Specific version (auto-selects platform)
7575
- `ghcr.io/developerkunal/openmorph:v1.0` - Latest patch in v1.0.x
7676
- `ghcr.io/developerkunal/openmorph:v1` - Latest minor in v1.x.x
7777

0 commit comments

Comments
 (0)