Skip to content

Commit 16d599c

Browse files
committed
Add Docker configuration for cross-platform builds
- Dockerfile for ARM architecture builds - Docker Compose setup for multi-platform builds - Documentation for Docker-based compilation - Support for Linux ARM64 and ARMv7 builds
1 parent ddae367 commit 16d599c

File tree

3 files changed

+302
-0
lines changed

3 files changed

+302
-0
lines changed

docker/README.md

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# Socket CLI Docker Build Environment
2+
3+
This directory contains Docker configurations for building Socket CLI binaries across different platforms and architectures.
4+
5+
## 🎯 Purpose
6+
7+
Building binaries for different architectures (especially ARM) from an x86_64 host requires cross-compilation. Docker provides a consistent build environment and allows us to target multiple architectures using QEMU emulation.
8+
9+
## 📋 Prerequisites
10+
11+
1. **Docker Desktop** (macOS/Windows) or **Docker Engine** (Linux)
12+
2. **Docker Buildx** (included in Docker Desktop, may need installation on Linux)
13+
3. **QEMU** for cross-platform emulation
14+
15+
### Setup Docker Buildx
16+
17+
```bash
18+
# Create and use a new builder instance
19+
docker buildx create --name socket-builder --use
20+
21+
# Verify it's working
22+
docker buildx inspect --bootstrap
23+
24+
# List available platforms
25+
docker buildx ls
26+
```
27+
28+
## 🏗️ Building Binaries
29+
30+
### Build All Linux Architectures
31+
32+
```bash
33+
# From the socket-cli root directory
34+
docker compose -f docker/docker-compose.build.yml up
35+
36+
# This will build binaries for:
37+
# - Linux x64
38+
# - Linux ARM64
39+
# - Linux ARMv7
40+
```
41+
42+
### Build Specific Architecture
43+
44+
```bash
45+
# Build only ARM64
46+
docker compose -f docker/docker-compose.build.yml up build-linux-arm64
47+
48+
# Build only ARMv7
49+
docker compose -f docker/docker-compose.build.yml up build-linux-armv7
50+
```
51+
52+
### Manual Docker Build
53+
54+
```bash
55+
# Build for ARM64
56+
docker buildx build \
57+
--platform linux/arm64 \
58+
--build-arg ARCH=arm64 \
59+
--build-arg NODE_VERSION=20 \
60+
-f docker/build-arm.dockerfile \
61+
-t socket-cli:linux-arm64 \
62+
--load \
63+
.
64+
65+
# Extract the binary
66+
docker run --rm -v $(pwd)/dist:/output socket-cli:linux-arm64 \
67+
sh -c "cp /usr/local/bin/socket /output/socket-linux-arm64"
68+
```
69+
70+
## 🪟 Windows Binary Building
71+
72+
**Important:** Windows binaries CANNOT be built from macOS/Linux using Docker because:
73+
74+
1. Windows binaries require Windows-specific tools (MSVC, Windows SDK)
75+
2. Docker on macOS/Linux only runs Linux containers
76+
3. Wine is not reliable for Node.js compilation
77+
78+
### Recommended Approaches for Windows Binaries
79+
80+
#### Option 1: GitHub Actions (Recommended)
81+
- Free for public repositories
82+
- Supports Windows, macOS, and Linux runners
83+
- See `.github/workflows/release-sea.yml` for the workflow
84+
85+
#### Option 2: Windows VM
86+
- Use Parallels, VMware, or VirtualBox on macOS
87+
- Use native Windows or WSL2 on Windows
88+
- Requires Windows license
89+
90+
#### Option 3: Cloud Build Services
91+
- Azure DevOps (free tier available)
92+
- AppVeyor (free for open source)
93+
- CircleCI (Windows support with paid plans)
94+
95+
## 📦 Output
96+
97+
Built binaries will be placed in the `dist/` directory:
98+
99+
```
100+
dist/
101+
├── socket-linux-x64 # Linux x64 binary
102+
├── socket-linux-arm64 # Linux ARM64 binary
103+
├── socket-linux-armv7 # Linux ARMv7 binary
104+
└── socket-win-x64.exe # Windows binary (built on Windows/CI)
105+
```
106+
107+
## 🔧 Customization
108+
109+
### Changing Node.js Version
110+
111+
Edit `docker-compose.build.yml` and update the `NODE_VERSION` arg:
112+
113+
```yaml
114+
args:
115+
NODE_VERSION: 22 # Change to desired version
116+
```
117+
118+
### Adding New Architectures
119+
120+
Add a new service to `docker-compose.build.yml`:
121+
122+
```yaml
123+
build-linux-riscv64:
124+
build:
125+
args:
126+
ARCH: riscv64
127+
NODE_VERSION: 20
128+
platforms:
129+
- linux/riscv64
130+
# ... rest of configuration
131+
```
132+
133+
## 💰 Cost Considerations
134+
135+
### Local Builds
136+
- **Free** - Uses your local machine
137+
- **Performance** - ARM emulation is slower than native
138+
- **Time** - ARM64 build can take 10-30 minutes on x86_64
139+
140+
### GitHub Actions
141+
- **Free** for public repositories (2,000 minutes/month)
142+
- **Paid** for private repositories
143+
- **Fast** - Native runners for each platform
144+
145+
### Cloud Services
146+
- **Azure DevOps** - 1,800 minutes free/month
147+
- **AppVeyor** - Free for open source
148+
- **CircleCI** - Limited free tier
149+
150+
## 🚀 Performance Tips
151+
152+
1. **Use native builders when possible** - ARM builds on ARM hardware are much faster
153+
2. **Enable Docker BuildKit** - `export DOCKER_BUILDKIT=1`
154+
3. **Use cache mounts** - Preserve pnpm cache between builds
155+
4. **Parallel builds** - Use `docker compose up -d` for parallel execution
156+
157+
## 🐛 Troubleshooting
158+
159+
### "No matching platform" error
160+
```bash
161+
# Install QEMU support
162+
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
163+
```
164+
165+
### Slow ARM builds
166+
This is expected when emulating ARM on x86_64. Consider using:
167+
- Native ARM hardware (Raspberry Pi, ARM Mac)
168+
- Cloud ARM instances (AWS Graviton, Oracle Ampere)
169+
- GitHub Actions with ARM runners
170+
171+
### Out of memory
172+
Increase Docker memory limit in Docker Desktop settings (recommended: 8GB+)
173+
174+
## 📚 Resources
175+
176+
- [Docker Buildx Documentation](https://docs.docker.com/buildx/working-with-buildx/)
177+
- [QEMU User Emulation](https://www.qemu.org/docs/master/user/index.html)
178+
- [Node.js SEA Documentation](https://nodejs.org/api/single-executable-applications.html)
179+
- [Yao-pkg Documentation](https://github.com/yao-pkg/pkg)

docker/build-arm.dockerfile

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Dockerfile for cross-compiling Socket CLI for ARM architectures
2+
# Supports both ARM64 and ARMv7 builds
3+
4+
ARG ARCH=arm64
5+
ARG NODE_VERSION=20
6+
7+
# Use appropriate base image based on architecture
8+
FROM --platform=linux/${ARCH} node:${NODE_VERSION}-bullseye-slim AS builder
9+
10+
# Install build dependencies
11+
RUN apt-get update && apt-get install -y \
12+
build-essential \
13+
python3 \
14+
git \
15+
curl \
16+
ca-certificates \
17+
&& rm -rf /var/lib/apt/lists/*
18+
19+
# Install pnpm globally
20+
RUN npm install -g pnpm@latest
21+
22+
# Create app directory
23+
WORKDIR /app
24+
25+
# Copy package files
26+
COPY package.json pnpm-lock.yaml ./
27+
COPY .npmrc* ./
28+
29+
# Install dependencies
30+
RUN pnpm install --frozen-lockfile
31+
32+
# Copy source code
33+
COPY . .
34+
35+
# Build the application
36+
RUN pnpm run build
37+
38+
# Build the binary using yao-pkg
39+
RUN pnpm exec pkg \
40+
.config/pkg.json \
41+
--targets node${NODE_VERSION}-linux-${ARCH} \
42+
--output dist/socket-linux-${ARCH}
43+
44+
# Final stage - minimal image with just the binary
45+
FROM --platform=linux/${ARCH} debian:bullseye-slim
46+
47+
# Install minimal runtime dependencies
48+
RUN apt-get update && apt-get install -y \
49+
ca-certificates \
50+
&& rm -rf /var/lib/apt/lists/*
51+
52+
# Copy the binary from builder
53+
COPY --from=builder /app/dist/socket-linux-* /usr/local/bin/socket
54+
55+
# Make it executable
56+
RUN chmod +x /usr/local/bin/socket
57+
58+
# Verify it works
59+
RUN socket --version
60+
61+
# Set entrypoint
62+
ENTRYPOINT ["socket"]

docker/docker-compose.build.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Docker Compose configuration for building Socket CLI binaries
2+
# This setup allows building for multiple architectures from a single host
3+
4+
version: '3.8'
5+
6+
services:
7+
# Build Linux ARM64 binary
8+
build-linux-arm64:
9+
build:
10+
context: ..
11+
dockerfile: docker/build-arm.dockerfile
12+
args:
13+
ARCH: arm64
14+
NODE_VERSION: 20
15+
platforms:
16+
- linux/arm64
17+
image: socket-cli-builder:linux-arm64
18+
volumes:
19+
- ../dist:/output
20+
command: |
21+
sh -c "cp /usr/local/bin/socket /output/socket-linux-arm64 && \
22+
echo 'Binary copied to dist/socket-linux-arm64'"
23+
24+
# Build Linux ARMv7 binary
25+
build-linux-armv7:
26+
build:
27+
context: ..
28+
dockerfile: docker/build-arm.dockerfile
29+
args:
30+
ARCH: arm/v7
31+
NODE_VERSION: 20
32+
platforms:
33+
- linux/arm/v7
34+
image: socket-cli-builder:linux-armv7
35+
volumes:
36+
- ../dist:/output
37+
command: |
38+
sh -c "cp /usr/local/bin/socket /output/socket-linux-armv7 && \
39+
echo 'Binary copied to dist/socket-linux-armv7'"
40+
41+
# Build Linux x64 binary (for consistency)
42+
build-linux-x64:
43+
build:
44+
context: ..
45+
dockerfile: docker/build-arm.dockerfile
46+
args:
47+
ARCH: amd64
48+
NODE_VERSION: 20
49+
platforms:
50+
- linux/amd64
51+
image: socket-cli-builder:linux-x64
52+
volumes:
53+
- ../dist:/output
54+
command: |
55+
sh -c "cp /usr/local/bin/socket /output/socket-linux-x64 && \
56+
echo 'Binary copied to dist/socket-linux-x64'"
57+
58+
# Volumes for output
59+
volumes:
60+
dist:
61+
driver: local

0 commit comments

Comments
 (0)