forked from github-mirrorer/quake-kube
Add docker cross-compile for arm64
This makes use of the docker buildx to cross-compile images for amd64/arm64. It is worth noting that there are ongoing issues with the Go compiler and qemu (used by buildx/buildkit) and the solution I ended up using here was to limit the affinity to `go build`. Better solutions may be forthcoming. Refs: https://github.com/golang/go/issues/24656 https://bugs.launchpad.net/qemu/+bug/1696773 This relates to issue #11 regarding container images built for running on Raspberry Pi.
This commit is contained in:
10
Dockerfile
10
Dockerfile
@ -11,19 +11,19 @@ COPY cmd cmd/
|
|||||||
COPY internal internal/
|
COPY internal internal/
|
||||||
COPY public public/
|
COPY public public/
|
||||||
|
|
||||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o q3 ./cmd/q3
|
RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on taskset -c 1 /usr/local/go/bin/go build -a -o q3 ./cmd/q3
|
||||||
|
|
||||||
FROM alpine:3.12 as quake-n-bake
|
FROM alpine:3.12 as quake-n-bake
|
||||||
|
|
||||||
RUN apk add --no-cache git gcc make libc-dev sdl2-dev mesa-dev
|
RUN apk add --no-cache git gcc make libc-dev
|
||||||
RUN git clone https://github.com/ioquake/ioq3
|
RUN git clone https://github.com/ioquake/ioq3
|
||||||
RUN cd /ioq3 && make
|
RUN cd /ioq3 && make BUILD_MISSIONPACK=0 BUILD_BASEGAME=0 BUILD_CLIENT=0 BUILD_SERVER=1 BUILD_GAME_SO=0 BUILD_GAME_QVM=0 BUILD_RENDERER_OPENGL2=0
|
||||||
RUN cp /ioq3/build/release-linux-x86_64/ioq3ded.x86_64 /usr/local/bin/ioq3ded
|
RUN cp /ioq3/build/release-linux-$(uname -m)/ioq3ded.$(uname -m) /usr/local/bin/ioq3ded
|
||||||
|
|
||||||
FROM alpine:3.12
|
FROM alpine:3.12
|
||||||
|
|
||||||
COPY --from=builder /workspace/q3 /usr/local/bin
|
COPY --from=builder /workspace/q3 /usr/local/bin
|
||||||
COPY --from=quake-n-bake /usr/local/bin/ioq3ded /usr/local/bin
|
COPY --from=quake-n-bake /usr/local/bin/ioq3ded /usr/local/bin
|
||||||
COPY --from=quake-n-bake /lib/ld-musl-x86_64.so.1 /lib
|
COPY --from=quake-n-bake /lib/ld-musl-*.so.1 /lib
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/q3"]
|
ENTRYPOINT ["/usr/local/bin/q3"]
|
||||||
|
|||||||
6
Makefile
6
Makefile
@ -9,9 +9,13 @@ q3: gen
|
|||||||
gen: ## Generate and embed templates
|
gen: ## Generate and embed templates
|
||||||
@go run tools/genstatic.go public public
|
@go run tools/genstatic.go public public
|
||||||
|
|
||||||
VERSION ?= v1.0.2
|
VERSION ?= v1.0.3
|
||||||
IMAGE ?= docker.io/criticalstack/quake:$(VERSION)
|
IMAGE ?= docker.io/criticalstack/quake:$(VERSION)
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build:
|
build:
|
||||||
@docker build . --force-rm --build-arg GOPROXY --build-arg GOSUMDB -t $(IMAGE)
|
@docker build . --force-rm --build-arg GOPROXY --build-arg GOSUMDB -t $(IMAGE)
|
||||||
|
|
||||||
|
.PHONY: buildx
|
||||||
|
buildx:
|
||||||
|
@docker buildx build . --platform=linux/amd64,linux/arm64 --progress=auto -t $(IMAGE) --push
|
||||||
|
|||||||
11
README.md
11
README.md
@ -122,6 +122,17 @@ The easiest way to develop quake-kube is building the binary locally with `make`
|
|||||||
$ bin/q3 server -c config.yaml --assets-dir $HOME/.q3a --agree-eula
|
$ bin/q3 server -c config.yaml --assets-dir $HOME/.q3a --agree-eula
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Multi-platform images
|
||||||
|
|
||||||
|
Container images are being cross-compiled with [Docker Buildx](https://docs.docker.com/buildx/working-with-buildx/) so it can run on hardware with different architectures and operating systems. Currently, it is building for `linux/amd64` and `linux/arm64`. While not specifically compiling to the macOS platform (`darwin/amd64`) QuakeKube should also work on macOS and maybe even Windows. This is due to the fact that they both use a linux VM to provide container support.
|
||||||
|
|
||||||
|
Docker Buildx uses [QEMU](https://www.qemu.org/) to virtualize non-native platforms, which has unfortunately had long-running issues running the Go compiler:
|
||||||
|
|
||||||
|
* [golang/go#24656](https://github.com/golang/go/issues/24656)
|
||||||
|
* [https://bugs.launchpad.net/qemu/+bug/1696773](https://bugs.launchpad.net/qemu/+bug/1696773)
|
||||||
|
|
||||||
|
This issue is circumvented by ensuring that the Go compiler does not run across multiple hardware threads, which is why the affinity is being limited in the Dockerfile.
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
* [inolen/quakejs](https://github.com/inolen/quakejs) - The really awesome QuakeJS project that makes this possible.
|
* [inolen/quakejs](https://github.com/inolen/quakejs) - The really awesome QuakeJS project that makes this possible.
|
||||||
|
|||||||
@ -22,7 +22,7 @@ spec:
|
|||||||
- --config=/config/config.yaml
|
- --config=/config/config.yaml
|
||||||
- --content-server=http://localhost:9090
|
- --content-server=http://localhost:9090
|
||||||
- --agree-eula
|
- --agree-eula
|
||||||
image: docker.io/criticalstack/quake:v1.0.2
|
image: docker.io/criticalstack/quake:v1.0.3
|
||||||
name: server
|
name: server
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
@ -40,7 +40,7 @@ spec:
|
|||||||
- q3
|
- q3
|
||||||
- content
|
- content
|
||||||
- --seed-content-url=http://content.quakejs.com
|
- --seed-content-url=http://content.quakejs.com
|
||||||
image: docker.io/criticalstack/quake:v1.0.2
|
image: docker.io/criticalstack/quake:v1.0.3
|
||||||
name: content-server
|
name: content-server
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 9090
|
- containerPort: 9090
|
||||||
|
|||||||
@ -22,14 +22,17 @@ var (
|
|||||||
Name: "quake_active_players",
|
Name: "quake_active_players",
|
||||||
Help: "The current number of active players",
|
Help: "The current number of active players",
|
||||||
})
|
})
|
||||||
|
|
||||||
scores = promauto.NewGaugeVec(prometheus.GaugeOpts{
|
scores = promauto.NewGaugeVec(prometheus.GaugeOpts{
|
||||||
Name: "quake_player_scores",
|
Name: "quake_player_scores",
|
||||||
Help: "Current scores by player, by map",
|
Help: "Current scores by player, by map",
|
||||||
}, []string{"player", "map"})
|
}, []string{"player", "map"})
|
||||||
|
|
||||||
pings = promauto.NewGaugeVec(prometheus.GaugeOpts{
|
pings = promauto.NewGaugeVec(prometheus.GaugeOpts{
|
||||||
Name: "quake_player_pings",
|
Name: "quake_player_pings",
|
||||||
Help: "Current ping by player",
|
Help: "Current ping by player",
|
||||||
}, []string{"player"})
|
}, []string{"player"})
|
||||||
|
|
||||||
configReloads = promauto.NewCounter(prometheus.CounterOpts{
|
configReloads = promauto.NewCounter(prometheus.CounterOpts{
|
||||||
Name: "quake_config_reloads",
|
Name: "quake_config_reloads",
|
||||||
Help: "Config file reload count",
|
Help: "Config file reload count",
|
||||||
@ -97,6 +100,7 @@ func (s *Server) Start(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
tick := time.NewTicker(5 * time.Second)
|
tick := time.NewTicker(5 * time.Second)
|
||||||
defer tick.Stop()
|
defer tick.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-tick.C:
|
case <-tick.C:
|
||||||
@ -107,7 +111,9 @@ func (s *Server) Start(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
actrvePlayers.Set(float64(len(status.Players)))
|
actrvePlayers.Set(float64(len(status.Players)))
|
||||||
for _, p := range status.Players {
|
for _, p := range status.Players {
|
||||||
scores.WithLabelValues(p.Name, status.Configuration["mapname"]).Set(float64(p.Score))
|
if mapname, ok := status.Configuration["mapname"]; ok {
|
||||||
|
scores.WithLabelValues(p.Name, mapname).Set(float64(p.Score))
|
||||||
|
}
|
||||||
pings.WithLabelValues(p.Name).Set(float64(p.Ping))
|
pings.WithLabelValues(p.Name).Set(float64(p.Ping))
|
||||||
}
|
}
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
|
|||||||
Reference in New Issue
Block a user