mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-07-29 12:42:46 +00:00
Update Dockerfile (#2342)
Updates/adds a new multistage (build-kit) Dockerfile. (if accepted, could make `Dockerfile.monolith` and `Dockerfile.polylith` in `build/docker` obsolete) There's no huge difference between the dockerfiles, except this uses a non-root user when running the container, also doesn't copy the working directory to the image when building. Also adds vulnerabilities scans using [Trivy](https://github.com/aquasecurity/trivy) for the created docker images. (untested) Building images is done using ``` docker build . --target image-monolith -t dendrite-monolith docker build . --target image-polylith -t dendrite-polylith ``` As noted in the comments, only adds `dendrite-polylith-multi` to the polylith image and all required binaries to the monolith image. Probably needs some docs updating, if this is accepted. Co-authored-by: Neil Alexander <neilalexander@users.noreply.github.com>
This commit is contained in:
parent
34ed316584
commit
e6c992ba8b
13 changed files with 257 additions and 115 deletions
101
build/dendritejs-pinecone/jsServer.go
Normal file
101
build/dendritejs-pinecone/jsServer.go
Normal file
|
@ -0,0 +1,101 @@
|
|||
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build wasm
|
||||
// +build wasm
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"syscall/js"
|
||||
)
|
||||
|
||||
// JSServer exposes an HTTP-like server interface which allows JS to 'send' requests to it.
|
||||
type JSServer struct {
|
||||
// The router which will service requests
|
||||
Mux http.Handler
|
||||
}
|
||||
|
||||
// OnRequestFromJS is the function that JS will invoke when there is a new request.
|
||||
// The JS function signature is:
|
||||
// function(reqString: string): Promise<{result: string, error: string}>
|
||||
// Usage is like:
|
||||
// const res = await global._go_js_server.fetch(reqString);
|
||||
// if (res.error) {
|
||||
// // handle error: this is a 'network' error, not a non-2xx error.
|
||||
// }
|
||||
// const rawHttpResponse = res.result;
|
||||
func (h *JSServer) OnRequestFromJS(this js.Value, args []js.Value) interface{} {
|
||||
// we HAVE to spawn a new goroutine and return immediately or else Go will deadlock
|
||||
// if this request blocks at all e.g for /sync calls
|
||||
httpStr := args[0].String()
|
||||
promise := js.Global().Get("Promise").New(js.FuncOf(func(pthis js.Value, pargs []js.Value) interface{} {
|
||||
// The initial callback code for new Promise() is also called on the critical path, which is why
|
||||
// we need to put this in an immediately invoked goroutine.
|
||||
go func() {
|
||||
resolve := pargs[0]
|
||||
resStr, err := h.handle(httpStr)
|
||||
errStr := ""
|
||||
if err != nil {
|
||||
errStr = err.Error()
|
||||
}
|
||||
resolve.Invoke(map[string]interface{}{
|
||||
"result": resStr,
|
||||
"error": errStr,
|
||||
})
|
||||
}()
|
||||
return nil
|
||||
}))
|
||||
return promise
|
||||
}
|
||||
|
||||
// handle invokes the http.ServeMux for this request and returns the raw HTTP response.
|
||||
func (h *JSServer) handle(httpStr string) (resStr string, err error) {
|
||||
req, err := http.ReadRequest(bufio.NewReader(strings.NewReader(httpStr)))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
h.Mux.ServeHTTP(w, req)
|
||||
|
||||
res := w.Result()
|
||||
var resBuffer strings.Builder
|
||||
err = res.Write(&resBuffer)
|
||||
return resBuffer.String(), err
|
||||
}
|
||||
|
||||
// ListenAndServe registers a variable in JS-land with the given namespace. This variable is
|
||||
// a function which JS-land can call to 'send' HTTP requests. The function is attached to
|
||||
// a global object called "_go_js_server". See OnRequestFromJS for more info.
|
||||
func (h *JSServer) ListenAndServe(namespace string) {
|
||||
globalName := "_go_js_server"
|
||||
// register a hook in JS-land for it to invoke stuff
|
||||
server := js.Global().Get(globalName)
|
||||
if !server.Truthy() {
|
||||
server = js.Global().Get("Object").New()
|
||||
js.Global().Set(globalName, server)
|
||||
}
|
||||
|
||||
server.Set(namespace, js.FuncOf(h.OnRequestFromJS))
|
||||
|
||||
fmt.Printf("Listening for requests from JS on function %s.%s\n", globalName, namespace)
|
||||
// Block forever to mimic http.ListenAndServe
|
||||
select {}
|
||||
}
|
234
build/dendritejs-pinecone/main.go
Normal file
234
build/dendritejs-pinecone/main.go
Normal file
|
@ -0,0 +1,234 @@
|
|||
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build wasm
|
||||
// +build wasm
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"syscall/js"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/matrix-org/dendrite/appservice"
|
||||
"github.com/matrix-org/dendrite/cmd/dendrite-demo-pinecone/conn"
|
||||
"github.com/matrix-org/dendrite/cmd/dendrite-demo-pinecone/rooms"
|
||||
"github.com/matrix-org/dendrite/cmd/dendrite-demo-yggdrasil/signing"
|
||||
"github.com/matrix-org/dendrite/federationapi"
|
||||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
"github.com/matrix-org/dendrite/keyserver"
|
||||
"github.com/matrix-org/dendrite/roomserver"
|
||||
"github.com/matrix-org/dendrite/setup"
|
||||
"github.com/matrix-org/dendrite/setup/base"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/userapi"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
_ "github.com/matrix-org/go-sqlite3-js"
|
||||
|
||||
pineconeConnections "github.com/matrix-org/pinecone/connections"
|
||||
pineconeRouter "github.com/matrix-org/pinecone/router"
|
||||
pineconeSessions "github.com/matrix-org/pinecone/sessions"
|
||||
)
|
||||
|
||||
var GitCommit string
|
||||
|
||||
func init() {
|
||||
fmt.Printf("[%s] dendrite.js starting...\n", GitCommit)
|
||||
}
|
||||
|
||||
const publicPeer = "wss://pinecone.matrix.org/public"
|
||||
const keyNameEd25519 = "_go_ed25519_key"
|
||||
|
||||
func readKeyFromLocalStorage() (key ed25519.PrivateKey, err error) {
|
||||
localforage := js.Global().Get("localforage")
|
||||
if !localforage.Truthy() {
|
||||
err = fmt.Errorf("readKeyFromLocalStorage: no localforage")
|
||||
return
|
||||
}
|
||||
// https://localforage.github.io/localForage/
|
||||
item, ok := await(localforage.Call("getItem", keyNameEd25519))
|
||||
if !ok || !item.Truthy() {
|
||||
err = fmt.Errorf("readKeyFromLocalStorage: no key in localforage")
|
||||
return
|
||||
}
|
||||
fmt.Println("Found key in localforage")
|
||||
// extract []byte and make an ed25519 key
|
||||
seed := make([]byte, 32, 32)
|
||||
js.CopyBytesToGo(seed, item)
|
||||
|
||||
return ed25519.NewKeyFromSeed(seed), nil
|
||||
}
|
||||
|
||||
func writeKeyToLocalStorage(key ed25519.PrivateKey) error {
|
||||
localforage := js.Global().Get("localforage")
|
||||
if !localforage.Truthy() {
|
||||
return fmt.Errorf("writeKeyToLocalStorage: no localforage")
|
||||
}
|
||||
|
||||
// make a Uint8Array from the key's seed
|
||||
seed := key.Seed()
|
||||
jsSeed := js.Global().Get("Uint8Array").New(len(seed))
|
||||
js.CopyBytesToJS(jsSeed, seed)
|
||||
// write it
|
||||
localforage.Call("setItem", keyNameEd25519, jsSeed)
|
||||
return nil
|
||||
}
|
||||
|
||||
// taken from https://go-review.googlesource.com/c/go/+/150917
|
||||
|
||||
// await waits until the promise v has been resolved or rejected and returns the promise's result value.
|
||||
// The boolean value ok is true if the promise has been resolved, false if it has been rejected.
|
||||
// If v is not a promise, v itself is returned as the value and ok is true.
|
||||
func await(v js.Value) (result js.Value, ok bool) {
|
||||
if v.Type() != js.TypeObject || v.Get("then").Type() != js.TypeFunction {
|
||||
return v, true
|
||||
}
|
||||
done := make(chan struct{})
|
||||
onResolve := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||
result = args[0]
|
||||
ok = true
|
||||
close(done)
|
||||
return nil
|
||||
})
|
||||
defer onResolve.Release()
|
||||
onReject := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||
result = args[0]
|
||||
ok = false
|
||||
close(done)
|
||||
return nil
|
||||
})
|
||||
defer onReject.Release()
|
||||
v.Call("then", onResolve, onReject)
|
||||
<-done
|
||||
return
|
||||
}
|
||||
|
||||
func generateKey() ed25519.PrivateKey {
|
||||
// attempt to look for a seed in JS-land and if it exists use it.
|
||||
priv, err := readKeyFromLocalStorage()
|
||||
if err == nil {
|
||||
fmt.Println("Read key from localStorage")
|
||||
return priv
|
||||
}
|
||||
// generate a new key
|
||||
fmt.Println(err, " : Generating new ed25519 key")
|
||||
_, priv, err = ed25519.GenerateKey(nil)
|
||||
if err != nil {
|
||||
logrus.Fatalf("Failed to generate ed25519 key: %s", err)
|
||||
}
|
||||
if err := writeKeyToLocalStorage(priv); err != nil {
|
||||
fmt.Println("failed to write key to localStorage: ", err)
|
||||
// non-fatal, we'll just have amnesia for a while
|
||||
}
|
||||
return priv
|
||||
}
|
||||
|
||||
func main() {
|
||||
startup()
|
||||
|
||||
// We want to block forever to let the fetch and libp2p handler serve the APIs
|
||||
select {}
|
||||
}
|
||||
|
||||
func startup() {
|
||||
sk := generateKey()
|
||||
pk := sk.Public().(ed25519.PublicKey)
|
||||
|
||||
pRouter := pineconeRouter.NewRouter(logrus.WithField("pinecone", "router"), sk, false)
|
||||
pSessions := pineconeSessions.NewSessions(logrus.WithField("pinecone", "sessions"), pRouter, []string{"matrix"})
|
||||
pManager := pineconeConnections.NewConnectionManager(pRouter)
|
||||
pManager.AddPeer("wss://pinecone.matrix.org/public")
|
||||
|
||||
cfg := &config.Dendrite{}
|
||||
cfg.Defaults(true)
|
||||
cfg.UserAPI.AccountDatabase.ConnectionString = "file:/idb/dendritejs_account.db"
|
||||
cfg.AppServiceAPI.Database.ConnectionString = "file:/idb/dendritejs_appservice.db"
|
||||
cfg.FederationAPI.Database.ConnectionString = "file:/idb/dendritejs_fedsender.db"
|
||||
cfg.MediaAPI.Database.ConnectionString = "file:/idb/dendritejs_mediaapi.db"
|
||||
cfg.RoomServer.Database.ConnectionString = "file:/idb/dendritejs_roomserver.db"
|
||||
cfg.SyncAPI.Database.ConnectionString = "file:/idb/dendritejs_syncapi.db"
|
||||
cfg.KeyServer.Database.ConnectionString = "file:/idb/dendritejs_e2ekey.db"
|
||||
cfg.Global.JetStream.StoragePath = "file:/idb/dendritejs/"
|
||||
cfg.Global.TrustedIDServers = []string{}
|
||||
cfg.Global.KeyID = gomatrixserverlib.KeyID(signing.KeyID)
|
||||
cfg.Global.PrivateKey = sk
|
||||
cfg.Global.ServerName = gomatrixserverlib.ServerName(hex.EncodeToString(pk))
|
||||
cfg.ClientAPI.RegistrationDisabled = false
|
||||
cfg.ClientAPI.OpenRegistrationWithoutVerificationEnabled = true
|
||||
|
||||
if err := cfg.Derive(); err != nil {
|
||||
logrus.Fatalf("Failed to derive values from config: %s", err)
|
||||
}
|
||||
base := base.NewBaseDendrite(cfg, "Monolith")
|
||||
defer base.Close() // nolint: errcheck
|
||||
|
||||
federation := conn.CreateFederationClient(base, pSessions)
|
||||
keyAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, federation)
|
||||
|
||||
serverKeyAPI := &signing.YggdrasilKeys{}
|
||||
keyRing := serverKeyAPI.KeyRing()
|
||||
|
||||
rsAPI := roomserver.NewInternalAPI(base)
|
||||
|
||||
userAPI := userapi.NewInternalAPI(base, &cfg.UserAPI, nil, keyAPI, rsAPI, base.PushGatewayHTTPClient())
|
||||
keyAPI.SetUserAPI(userAPI)
|
||||
|
||||
asQuery := appservice.NewInternalAPI(
|
||||
base, userAPI, rsAPI,
|
||||
)
|
||||
rsAPI.SetAppserviceAPI(asQuery)
|
||||
fedSenderAPI := federationapi.NewInternalAPI(base, federation, rsAPI, base.Caches, keyRing, true)
|
||||
rsAPI.SetFederationAPI(fedSenderAPI, keyRing)
|
||||
|
||||
monolith := setup.Monolith{
|
||||
Config: base.Cfg,
|
||||
Client: conn.CreateClient(base, pSessions),
|
||||
FedClient: federation,
|
||||
KeyRing: keyRing,
|
||||
|
||||
AppserviceAPI: asQuery,
|
||||
FederationAPI: fedSenderAPI,
|
||||
RoomserverAPI: rsAPI,
|
||||
UserAPI: userAPI,
|
||||
KeyAPI: keyAPI,
|
||||
//ServerKeyAPI: serverKeyAPI,
|
||||
ExtPublicRoomsProvider: rooms.NewPineconeRoomProvider(pRouter, pSessions, fedSenderAPI, federation),
|
||||
}
|
||||
monolith.AddAllPublicRoutes(base)
|
||||
|
||||
httpRouter := mux.NewRouter().SkipClean(true).UseEncodedPath()
|
||||
httpRouter.PathPrefix(httputil.InternalPathPrefix).Handler(base.InternalAPIMux)
|
||||
httpRouter.PathPrefix(httputil.PublicClientPathPrefix).Handler(base.PublicClientAPIMux)
|
||||
httpRouter.PathPrefix(httputil.PublicMediaPathPrefix).Handler(base.PublicMediaAPIMux)
|
||||
|
||||
p2pRouter := pSessions.Protocol("matrix").HTTP().Mux()
|
||||
p2pRouter.Handle(httputil.PublicFederationPathPrefix, base.PublicFederationAPIMux)
|
||||
p2pRouter.Handle(httputil.PublicMediaPathPrefix, base.PublicMediaAPIMux)
|
||||
|
||||
// Expose the matrix APIs via fetch - for local traffic
|
||||
go func() {
|
||||
logrus.Info("Listening for service-worker fetch traffic")
|
||||
s := JSServer{
|
||||
Mux: httpRouter,
|
||||
}
|
||||
s.ListenAndServe("fetch")
|
||||
}()
|
||||
}
|
24
build/dendritejs-pinecone/main_noop.go
Normal file
24
build/dendritejs-pinecone/main_noop.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !wasm
|
||||
// +build !wasm
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("dendritejs: no-op when not compiling for WebAssembly")
|
||||
}
|
26
build/dendritejs-pinecone/main_test.go
Normal file
26
build/dendritejs-pinecone/main_test.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build wasm
|
||||
// +build wasm
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStartup(t *testing.T) {
|
||||
startup()
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
FROM docker.io/golang:1.19-alpine AS base
|
||||
|
||||
RUN apk --update --no-cache add bash build-base
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
COPY . /build
|
||||
|
||||
RUN mkdir -p bin
|
||||
RUN go build -trimpath -o bin/ ./cmd/dendrite-demo-pinecone
|
||||
RUN go build -trimpath -o bin/ ./cmd/create-account
|
||||
RUN go build -trimpath -o bin/ ./cmd/generate-keys
|
||||
|
||||
FROM alpine:latest
|
||||
LABEL org.opencontainers.image.title="Dendrite (Pinecone demo)"
|
||||
LABEL org.opencontainers.image.description="Next-generation Matrix homeserver written in Go"
|
||||
LABEL org.opencontainers.image.source="https://github.com/matrix-org/dendrite"
|
||||
LABEL org.opencontainers.image.licenses="Apache-2.0"
|
||||
|
||||
COPY --from=base /build/bin/* /usr/bin/
|
||||
|
||||
VOLUME /etc/dendrite
|
||||
WORKDIR /etc/dendrite
|
||||
|
||||
ENTRYPOINT ["/usr/bin/dendrite-demo-pinecone"]
|
|
@ -1,25 +0,0 @@
|
|||
FROM docker.io/golang:1.19-alpine AS base
|
||||
|
||||
RUN apk --update --no-cache add bash build-base
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
COPY . /build
|
||||
|
||||
RUN mkdir -p bin
|
||||
RUN go build -trimpath -o bin/ ./cmd/dendrite-monolith-server
|
||||
RUN go build -trimpath -o bin/ ./cmd/create-account
|
||||
RUN go build -trimpath -o bin/ ./cmd/generate-keys
|
||||
|
||||
FROM alpine:latest
|
||||
LABEL org.opencontainers.image.title="Dendrite (Monolith)"
|
||||
LABEL org.opencontainers.image.description="Next-generation Matrix homeserver written in Go"
|
||||
LABEL org.opencontainers.image.source="https://github.com/matrix-org/dendrite"
|
||||
LABEL org.opencontainers.image.licenses="Apache-2.0"
|
||||
|
||||
COPY --from=base /build/bin/* /usr/bin/
|
||||
|
||||
VOLUME /etc/dendrite
|
||||
WORKDIR /etc/dendrite
|
||||
|
||||
ENTRYPOINT ["/usr/bin/dendrite-monolith-server"]
|
|
@ -1,25 +0,0 @@
|
|||
FROM docker.io/golang:1.19-alpine AS base
|
||||
|
||||
RUN apk --update --no-cache add bash build-base
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
COPY . /build
|
||||
|
||||
RUN mkdir -p bin
|
||||
RUN go build -trimpath -o bin/ ./cmd/dendrite-polylith-multi
|
||||
RUN go build -trimpath -o bin/ ./cmd/create-account
|
||||
RUN go build -trimpath -o bin/ ./cmd/generate-keys
|
||||
|
||||
FROM alpine:latest
|
||||
LABEL org.opencontainers.image.title="Dendrite (Polylith)"
|
||||
LABEL org.opencontainers.image.description="Next-generation Matrix homeserver written in Go"
|
||||
LABEL org.opencontainers.image.source="https://github.com/matrix-org/dendrite"
|
||||
LABEL org.opencontainers.image.licenses="Apache-2.0"
|
||||
|
||||
COPY --from=base /build/bin/* /usr/bin/
|
||||
|
||||
VOLUME /etc/dendrite
|
||||
WORKDIR /etc/dendrite
|
||||
|
||||
ENTRYPOINT ["/usr/bin/dendrite-polylith-multi"]
|
|
@ -9,11 +9,15 @@ They can be found on Docker Hub:
|
|||
|
||||
## Dockerfiles
|
||||
|
||||
The `Dockerfile` builds the base image which contains all of the Dendrite
|
||||
components. The `Dockerfile.component` file takes the given component, as
|
||||
specified with `--buildarg component=` from the base image and produce
|
||||
smaller component-specific images, which are substantially smaller and do
|
||||
not contain the Go toolchain etc.
|
||||
The `Dockerfile` is a multistage file which can build all three Dendrite
|
||||
images depending on the supplied `--target`. From the root of the Dendrite
|
||||
repository, run:
|
||||
|
||||
```
|
||||
docker build . --target monolith -t matrixdotorg/dendrite-monolith
|
||||
docker build . --target polylith -t matrixdotorg/dendrite-monolith
|
||||
docker build . --target demo-pinecone -t matrixdotorg/dendrite-monolith
|
||||
```
|
||||
|
||||
## Compose files
|
||||
|
||||
|
|
67
build/docker/crossbuild.sh
Normal file
67
build/docker/crossbuild.sh
Normal file
|
@ -0,0 +1,67 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# In order to cross-compile with the multi-stage Docker builds, we need to
|
||||
# ensure that the suitable toolchain for cross-compiling is installed. Since
|
||||
# the images are Alpine-based, we will use musl. Download and install the
|
||||
# toolchain inside the build container.
|
||||
|
||||
USERARCH=`go env GOARCH`
|
||||
GOARCH="$TARGETARCH"
|
||||
GOOS="linux"
|
||||
|
||||
echo "Target arch: $TARGETARCH"
|
||||
echo "User arch: $USERARCH"
|
||||
|
||||
if [ "$TARGETARCH" != "$USERARCH" ]; then
|
||||
if [ "$USERARCH" != "amd64" ]; then
|
||||
echo "Cross-compiling only supported on amd64"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Cross compile"
|
||||
case $GOARCH in
|
||||
arm64)
|
||||
curl -s https://more.musl.cc/x86_64-linux-musl/aarch64-linux-musl-cross.tgz | tar xz --strip-components=1 -C /usr
|
||||
export CC=aarch64-linux-musl-gcc
|
||||
;;
|
||||
|
||||
amd64)
|
||||
curl -s https://more.musl.cc/x86_64-linux-musl/x86_64-linux-musl-cross.tgz | tar xz --strip-components=1 -C /usr
|
||||
export CC=x86_64-linux-musl-gcc
|
||||
;;
|
||||
|
||||
386)
|
||||
curl -s https://more.musl.cc/x86_64-linux-musl/i686-linux-musl-cross.tgz | tar xz --strip-components=1 -C /usr
|
||||
export CC=i686-linux-musl-gcc
|
||||
;;
|
||||
|
||||
arm)
|
||||
curl -s https://more.musl.cc/x86_64-linux-musl/armv7l-linux-musleabihf-cross.tgz | tar xz --strip-components=1 -C /usr
|
||||
export CC=armv7l-linux-musleabihf-gcc
|
||||
;;
|
||||
|
||||
s390x)
|
||||
curl -s https://more.musl.cc/x86_64-linux-musl/s390x-linux-musl-cross.tgz | tar xz --strip-components=1 -C /usr
|
||||
export CC=s390x-linux-musl-gcc
|
||||
;;
|
||||
|
||||
ppc64le)
|
||||
curl -s https://more.musl.cc/x86_64-linux-musl/powerpc64le-linux-musl-cross.tgz | tar xz --strip-components=1 -C /usr
|
||||
export CC=powerpc64le-linux-musl-gcc
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unsupported GOARCH=${GOARCH}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo "Native compile"
|
||||
fi
|
||||
|
||||
# Output the go environment just in case it is useful for debugging.
|
||||
go env
|
||||
|
||||
# Build Dendrite and tools, statically linking them.
|
||||
CGO_ENABLED=1 go build -v -ldflags="-linkmode external -extldflags -static ${FLAGS}" -trimpath -o /out/ ./cmd/...
|
|
@ -6,5 +6,6 @@ TAG=${1:-latest}
|
|||
|
||||
echo "Building tag '${TAG}'"
|
||||
|
||||
docker build -t matrixdotorg/dendrite-monolith:${TAG} -f build/docker/Dockerfile.monolith .
|
||||
docker build -t matrixdotorg/dendrite-polylith:${TAG} -f build/docker/Dockerfile.polylith .
|
||||
docker build . --target monolith -t matrixdotorg/dendrite-monolith:${TAG}
|
||||
docker build . --target polylith -t matrixdotorg/dendrite-monolith:${TAG}
|
||||
docker build . --target demo-pinecone -t matrixdotorg/dendrite-demo-pinecone:${TAG}
|
Loading…
Add table
Add a link
Reference in a new issue