fork of https://github.com/sourcegraph/zoekt
0

Configure Feed

Select the types of activity you want to include in your feed.

ci: build and push docker images (#42)

This is a port and improvement of our docker images in infrastructure. It will
build and push zoekt-webserver and zoekt-indexserver images on every push to
master. We use GitHub actions to achieve this. It uses the same version format
as we previously did.

The improvement is to share a base image which contains all the zoekt binaries
and dependencies. The different images then just copy out what they need and
do the sourcegraph specific customizations. This helps us share layers in a
cluster as well as reduce the time it takes to build.

+272 -14
+13
.ctags.d/additional-languages.ctags
··· 1 + # To avoid the warning: 2 + # 3 + # Unknown ctags kind: foo 4 + # 5 + # Make sure that all ctags kinds in this file 6 + # are handled in ctagsKindToLSPSymbolKind in 7 + # cmd/frontend/graphqlbackend/search_symbols.go 8 + 9 + # After changing this file, run a dev server and check for any other warnings 10 + # from the symbols service. 11 + 12 + # When you want to add a parser, make a file in this directory with 13 + # .ctags as suffix.
+11
.ctags.d/clojure.ctags
··· 1 + --regex-clojure=/def ([A-Za-z0-9_!?+*<>=-]+)/\1/v,variable/ 2 + --regex-clojure=/defmacro ([A-Za-z0-9_!?+*<>=-]+)/\1/m,macro/ 3 + --regex-clojure=/defprotocol ([A-Za-z0-9_!?+*<>=-]+)/\1/p,protocol/ 4 + --regex-clojure=/defrecord ([A-Za-z0-9_!?+*<>=-]+)/\1/r,record/ 5 + --regex-clojure=/deftype ([A-Za-z0-9_!?+*<>=-]+)/\1/t,type/ 6 + --regex-clojure=/s\/def ([A-Za-z0-9_!?+*<>=-]+)/\1/v,variable/ 7 + --regex-clojure=/s\/defn ([A-Za-z0-9_!?+*<>=-]+)/\1/f,function/ 8 + --regex-clojure=/s\/defmacro ([A-Za-z0-9_!?+*<>=-]+)/\1/m,macro/ 9 + --regex-clojure=/s\/defprotocol ([A-Za-z0-9_!?+*<>=-]+)/\1/p,protocol/ 10 + --regex-clojure=/s\/defrecord ([A-Za-z0-9_!?+*<>=-]+)/\1/r,record/ 11 + --regex-clojure=/s\/deftype ([A-Za-z0-9_!?+*<>=-]+)/\1/t,type/
+11
.ctags.d/graphql.ctags
··· 1 + --langdef=GraphQL 2 + --langmap=GraphQL:.graphql 3 + --regex-graphql=/^[ \t]*([_A-Za-z][_A-Za-z0-9]*)[\(:]/\1/v,field/ 4 + --regex-graphql=/^[ \t]*enum[ \t]+([_A-Za-z][_0-9A-Za-z]*)/\1/e,enum/ 5 + --regex-graphql=/^[ \t]*fragment[ \t]+([_A-Za-z][_0-9A-Za-z]*)/\1/f,fragment/ 6 + --regex-graphql=/^[ \t]*input[ \t]+([_A-Za-z][_0-9A-Za-z]*)/\1/i,input/ 7 + --regex-graphql=/^[ \t]*interface[ \t]+([_A-Za-z][_0-9A-Za-z]*)/\1/n,interface/ 8 + --regex-graphql=/^[ \t]*mutation[ \t]+([_A-Za-z][_0-9A-Za-z]*)/\1/m,mutation/ 9 + --regex-graphql=/^[ \t]*query[ \t]+([_A-Za-z][_0-9A-Za-z]*)/\1/q,query/ 10 + --regex-graphql=/^[ \t]*type[ \t]+([_A-Za-z][_0-9A-Za-z]*)/\1/t,type/ 11 + --regex-graphql=/^[ \t]*scalar[ \t]+([_A-Za-z][_0-9A-Za-z]*)/\1/t,type/
+10
.ctags.d/groovy.ctags
··· 1 + --langdef=Groovy 2 + --langmap=Groovy:.groovy 3 + --regex-groovy=/^[ \t]*package[ \t]+([a-zA-Z0-9.-_]+)/\1/p,package/ 4 + --regex-groovy=/^[ \t]*((private|public)[ \t]*)?(abstract|final|static)?[ \t]*class[ \t]+([A-Za-z0-9_]+)/\4/c,class/ 5 + --regex-groovy=/^[ \t]*((private|public)[ \t]*)?interface[ \t]+([A-Za-z0-9_]+)/\3/n,interface/ 6 + --regex-groovy=/^[ \t]*((private|public)[ \t]*)?trait[ \t]+([A-Za-z0-9_]+)/\3/t,trait/ 7 + --regex-groovy=/^[ \t]*((private|public)[ \t]*)?enum[ \t]+([A-Za-z0-9_]+)/\3/e,enum/ 8 + --regex-groovy=/^[ \t]*(public|private|protected[ \t]*)*([a-zA-Z0-9_]{3,})\([A-Za-z0-9 _,]*\)[ \t]+/\2/r,constructor/ 9 + --regex-groovy=/^[ \t]*((abstract|final|public|private|protected|static)[ \t]*)*(def|void|byte|int|short|long|float|double|boolean|char|[A-Z][a-zA-Z0-9_]*)[ \t]+([a-zA-Z0-9_]+)\(/\4/m,method/ 10 + --regex-groovy=/^[ \t]*((final|public|private|protected|static|synchronized)[ \t]*)*(def|byte|int|short|long|float|double|boolean|char|[A-Z][A-Za-z0-9_]*)[ \t]+([a-zA-Z0-9_]+)[ \t]*([\/]+.*)?$/\4/v,field/
+8
.ctags.d/haskell.ctags
··· 1 + # See additional-language.ctags for maintaining this file 2 + --langdef=haskell 3 + --langmap=haskell:.hs 4 + --regex-haskell=/^module[ \t]*([A-Z][a-zA-Z0-9'_.]*)/\1/m,module/ 5 + --regex-haskell=/^type[ \t]*([A-Z][a-zA-Z0-9'_]*)./\1/a,alias/ 6 + --regex-haskell=/^class[ \t]*([A-Z][a-zA-Z0-9'_]*)/\1/c,class/ 7 + --regex-haskell=/^(data|newtype)[ \t]*([A-Z][a-zA-Z0-9'_]*)/\2/t,type/ 8 + --regex-haskell=/^([a-z_][a-zA-Z0-9'_]*) ::/\1/v,constant/
+6
.ctags.d/jsonnet.ctags
··· 1 + --langdef=Jsonnet 2 + --langmap=Jsonnet:.jsonnet 3 + --langmap=Jsonnet:.libsonnet 4 + --regex-jsonnet=/^[ \t]*local ([A-Za-z0-9_]+)/\1/v,variable/ 5 + --regex-jsonnet=/^[ \t]*([A-Za-z0-9_]+):::?/\1/m,member/ 6 + --regex-jsonnet=/^[ \t]*([A-Za-z0-9_]+)\([^)]*\):::?/\1/f,function/
+12
.ctags.d/kotlin.ctags
··· 1 + --langdef=kotlin 2 + --langmap=kotlin:+.kt 3 + --langmap=kotlin:+.kts 4 + --regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|inner|open)[[:space:]]*)*(private[^ ]*|protected)?[[:space:]]*class[[:space:]]+([[:alnum:]_:]+)/\4/c,class/ 5 + --regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy)[[:space:]]*)*(private[^ ]*|protected)?[[:space:]]*object[[:space:]]+([[:alnum:]_:]+)/\4/o,object/ 6 + --regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|open)[[:space:]]*)*(private[^ ]*|protected)?[[:space:]]*((abstract|final|sealed|implicit|lazy)[[:space:]]*)*data class[[:space:]]+([[:alnum:]_:]+)/\6/c,class/ 7 + --regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy)[[:space:]]*)*(private[^ ]*|protected)?[[:space:]]*interface[[:space:]]+([[:alnum:]_:]+)/\4/i,interface/ 8 + --regex-kotlin=/^[[:space:]]*type[[:space:]]+([[:alnum:]_:]+)/\1/T,type/ 9 + --regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|override|open|private[^ ]*(\[[a-z]*\])*|protected)[[:space:]]*)*fun[[:space:]]+([[:alnum:]_:]+)/\4/m,method/ 10 + --regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*|protected)[[:space:]]*)*(const[[:space:]])*val[[:space:]]+([[:alnum:]_]+)/\4/C,constant/ 11 + --regex-kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*|protected)[[:space:]]*)*(lateinit[[:space:]]*)*var[[:space:]]+([[:alnum:]_]+)/\4/v,variable/ 12 + --regex-kotlin=/^[[:space:]]*package[[:space:]]+([[:alnum:]_.:]+)/\1/p,package/
+13
.ctags.d/scala.ctags
··· 1 + # See additional-language.ctags for maintaining this file 2 + --langdef=scala 3 + --langmap=scala:.scala 4 + --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*class[ \t]+([a-zA-Z0-9_]+)/\4/c,class/ 5 + --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*object[ \t]+([a-zA-Z0-9_]+)/\4/o,object/ 6 + --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*((abstract|final|sealed|implicit|lazy)[ \t ]*)*case class[ \t ]+([a-zA-Z0-9_]+)/\6/c,class/ 7 + --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*case object[ \t]+([a-zA-Z0-9_]+)/\4/o,object/ 8 + --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private[^ ]*|protected)?[ \t]*trait[ \t]+([a-zA-Z0-9_]+)/\4/i,interface/ 9 + --regex-scala=/^[ \t]*type[ \t]+([a-zA-Z0-9_]+)/\1/T,type/ 10 + --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*(\[[a-z]*\])*|protected)[ \t]*)*def[ \t]+([a-zA-Z0-9_]+)/\4/m,method/ 11 + --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*|protected)[ \t]*)*val[ \t]+([a-zA-Z0-9_]+)/\3/v,variable/ 12 + --regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy|override|private[^ ]*|protected)[ \t]*)*var[ \t]+([a-zA-Z0-9_]+)/\3/v,variable/ 13 + --regex-scala=/^[ \t]*package[ \t]+([a-zA-Z0-9_.]+)/\1/p,package/
+11
.ctags.d/swift.ctags
··· 1 + --langdef=swift 2 + --langmap=swift:.swift 3 + --regex-swift=/^[[:space:]]*((associatedtype|class|deinit|enum|extension|fileprivate|func|import|init|inout|internal|let|open|operator|private|protocol|public|static|struct|subscript|typealias|var)[[:space:]])*class[[:space:]]+([[:alnum:]_]+)/\3/c,class/ 4 + --regex-swift=/^[[:space:]]*public[[:space:]]*((associatedtype|class|deinit|enum|extension|fileprivate|func|import|init|inout|internal|let|open|operator|private|protocol|public|static|struct|subscript|typealias|final)[[:space:]])*let[[:space:]]+([[:alnum:]_]+)/\3/C,constant/ 5 + --regex-swift=/^[[:space:]]*public[[:space:]]*((associatedtype|class|deinit|enum|extension|fileprivate|func|import|init|inout|internal|let|open|operator|private|protocol|public|static|struct|subscript|typealias|final|lazy|mutating|nonmutating|optional|override|required|unowned|weak)[[:space:]])*var[[:space:]]+([[:alnum:]_]+)/\3/v,variable/ 6 + --regex-swift=/^[[:space:]]*((associatedtype|class|deinit|enum|extension|fileprivate|func|import|init|inout|internal|let|open|operator|private|protocol|public|static|struct|subscript|typealias|var)[[:space:]])*enum[[:space:]]+([[:alnum:]_]+)/\3/e,enum/ 7 + --regex-swift=/^[[:space:]]*((associatedtype|class|deinit|enum|extension|fileprivate|func|import|init|inout|internal|let|open|operator|private|protocol|public|static|struct|subscript|typealias|var|convenience|dynamic|final|mutating|nonmutating|optional|override|required)[[:space:]])*func[[:space:]]+([[:alnum:]_]+)/\3/f,function/ 8 + --regex-swift=/^[[:space:]]*((associatedtype|class|deinit|enum|extension|fileprivate|func|import|init|inout|internal|let|open|operator|private|protocol|public|static|struct|subscript|typealias|var)[[:space:]])*protocol[[:space:]]+([[:alnum:]_]+)/\3/i,interface/ 9 + --regex-swift=/^[[:space:]]*((associatedtype|class|deinit|enum|extension|fileprivate|func|import|init|inout|internal|let|open|operator|private|protocol|public|static|struct|subscript|typealias|var)[[:space:]])*struct[[:space:]]+([[:alnum:]_]+)/\3/s,struct/ 10 + --regex-swift=/^[[:space:]]*((associatedtype|class|deinit|enum|extension|fileprivate|func|import|init|inout|internal|let|open|operator|private|protocol|public|static|struct|subscript|typealias|var)[[:space:]])*extension[[:space:]]+([[:alnum:]_]+)/\3/d,define/ 11 + --regex-swift=/^[[:space:]]*((associatedtype|class|deinit|enum|extension|fileprivate|func|import|init|inout|internal|let|open|operator|private|protocol|public|static|struct|subscript|typealias|var)[[:space:]])*typealias[[:space:]]+([[:alnum:]_]+)/\3/a,alias/
+9
.ctags.d/thrift.ctags
··· 1 + --langdef=Thrift 2 + --langmap=Thrift:.thrift 3 + --regex-thrift=/^[ \t]*exception[ \t]+([a-zA-Z0-9_]+)/\1/x,exception/ 4 + --regex-thrift=/^[ \t]*enum[ \t]+([a-zA-Z0-9_]+)/\1/e,enum/ 5 + --regex-thrift=/^[ \t]*struct[ \t]+([a-zA-Z0-9_]+)/\1/s,struct/ 6 + --regex-thrift=/^[ \t]*service[ \t]+([a-zA-Z0-9_]+)/\1/v,service/ 7 + --regex-thrift=/^[ \t]*[0-9]+:[ \t]+([a-zA-Z0-9_]+)[ \t]+([a-zA-Z0-9_]+)/\2/m,member/ 8 + --regex-thrift=/^[ \t]*([a-zA-Z0-9_]+)[ \t]+=/\1/a,value/ 9 + --regex-thrift=/^[ \t]*[a-zA-Z0-9_<>]+[ \t]+([a-zA-Z0-9_]+)[ \t]*\(/\1/f,function/
+20
.ctags.d/tsx.ctags
··· 1 + # See additional-language.ctags for maintaining this file 2 + 3 + # To avoid the warning: 4 + # 5 + # Don't reuse the kind letter `c' in a language typescript (old: "classes", new: "modules") 6 + # 7 + # Make sure there's a 1-1 correspondence between kind letters and kind names. 8 + 9 + --langdef=tsx 10 + --langmap=tsx:.tsx 11 + --regex-tsx=/^[ \t]*(export[ \t]+([a-z]+[ \t]+)?)?class[ \t]+([a-zA-Z0-9_$]+)/\3/c,class/ 12 + --regex-tsx=/^[ \t]*(declare[ \t]+)?namespace[ \t]+([a-zA-Z0-9_$]+)/\2/n,module/ 13 + --regex-tsx=/^[ \t]*(export[ \t]+)?module[ \t]+([a-zA-Z0-9_$]+)/\2/n,module/ 14 + --regex-tsx=/^[ \t]*(export[ \t]+)?(default[ \t]+)?(async[ \t]+)?function[ \t]+([a-zA-Z0-9_$]+)/\4/f,function/ 15 + --regex-tsx=/^[ \t]*export[ \t]+(var|let|const)[ \t]+([a-zA-Z0-9_$]+)/\2/v,variable/ 16 + --regex-tsx=/^[ \t]*(var|let|const)[ \t]+([a-zA-Z0-9_$]+)[ \t]*=[ \t]*function[ \t]*[*]?[ \t]*\(\)/\2/v,variable/ 17 + --regex-tsx=/^[ \t]*(export[ \t]+)?(public|protected|private)[ \t]+(static[ \t]+)?(abstract[ \t]+)?(((get|set)[ \t]+)|(async[ \t]+[*]*[ \t]*))?([a-zA-Z1-9_$]+)/\9/m,member/ 18 + --regex-tsx=/^[ \t]*(export[ \t]+)?interface[ \t]+([a-zA-Z0-9_$]+)/\2/i,interface/ 19 + --regex-tsx=/^[ \t]*(export[ \t]+)?type[ \t]+([a-zA-Z0-9_$]+)/\2/t,type/ 20 + --regex-tsx=/^[ \t]*(export[ \t]+)?enum[ \t]+([a-zA-Z0-9_$]+)/\2/e,enum/
+3
.dockerignore
··· 1 + .git 2 + Dockerfile* 3 + .dockerignore
+57
.github/workflows/ci.yml
··· 1 + on: push 2 + name: CI 3 + jobs: 4 + test: 5 + runs-on: ubuntu-latest 6 + steps: 7 + - name: go 8 + uses: actions/setup-go@v1 9 + with: 10 + go-version: 1.14.x 11 + - name: checkout 12 + uses: actions/checkout@v2 13 + - name: test 14 + run: go test ./... 15 + 16 + # We build a shared docker image called "zoekt". This is not pushed, but is 17 + # used for creating the indexserver and webserver images. 18 + docker: 19 + if: github.ref == 'refs/heads/master' 20 + runs-on: ubuntu-latest 21 + needs: test 22 + steps: 23 + - name: checkout 24 + uses: actions/checkout@v2 25 + 26 + # This is the same tag we used for zoekt in the infrastructure repo. 27 + - name: version 28 + id: version 29 + run: echo "::set-output name=value::`date -u +'0.0.%Y%m%d%H%M%S'`-`git rev-parse --short HEAD`" 30 + 31 + - name: build-zoekt 32 + uses: docker/build-push-action@v1 33 + with: 34 + repository: zoekt 35 + tags: "latest" 36 + add_git_labels: "true" 37 + push: "false" 38 + 39 + - name: build-push-webserver 40 + uses: docker/build-push-action@v1 41 + with: 42 + repository: sourcegraph/zoekt-webserver 43 + tags: ${{ steps.version.outputs.value }},latest 44 + dockerfile: Dockerfile.webserver 45 + add_git_labels: "true" 46 + username: ${{ secrets.DOCKER_USERNAME }} 47 + password: ${{ secrets.DOCKER_PASSWORD }} 48 + 49 + - name: build-push-indexserver 50 + uses: docker/build-push-action@v1 51 + with: 52 + repository: sourcegraph/zoekt-indexserver 53 + tags: ${{ steps.version.outputs.value }},latest 54 + dockerfile: Dockerfile.indexserver 55 + add_git_labels: "true" 56 + username: ${{ secrets.DOCKER_USERNAME }} 57 + password: ${{ secrets.DOCKER_PASSWORD }}
-14
.github/workflows/test.yml
··· 1 - on: push 2 - name: Test 3 - jobs: 4 - test: 5 - runs-on: ubuntu-latest 6 - steps: 7 - - name: Install Go 8 - uses: actions/setup-go@v1 9 - with: 10 - go-version: 1.14.x 11 - - name: Checkout code 12 - uses: actions/checkout@v2 13 - - name: Test 14 - run: go test ./...
+42
Dockerfile
··· 1 + FROM golang:alpine AS builder 2 + 3 + RUN apk add --no-cache ca-certificates 4 + 5 + ENV CGO_ENABLED=0 GO111MODULE=on 6 + WORKDIR /go/src/github.com/google/zoekt 7 + 8 + # Cache dependencies 9 + COPY go.mod go.sum ./ 10 + RUN go mod download 11 + 12 + COPY . ./ 13 + RUN go install ./cmd/... 14 + 15 + FROM alpine AS ctags 16 + 17 + RUN apk add --no-cache --virtual build-deps ca-certificates curl jansson-dev \ 18 + libseccomp-dev linux-headers autoconf pkgconfig make automake \ 19 + gcc g++ binutils 20 + 21 + ENV CTAGS_VERSION=1a94658c2cb47304d0e9811d49e0a5f48bdb3a0a 22 + 23 + RUN curl -fsSL -o ctags.tar.gz "https://codeload.github.com/universal-ctags/ctags/tar.gz/$CTAGS_VERSION" && \ 24 + tar -C /tmp -xzf ctags.tar.gz && cd /tmp/ctags-$CTAGS_VERSION && \ 25 + ./autogen.sh && LDFLAGS=-static ./configure --program-prefix=universal- --enable-json --enable-seccomp && \ 26 + make -j8 && make install && cd && \ 27 + rm -rf /tmp/ctags-$CTAGS_VERSION && \ 28 + apk --no-cache --purge del build-deps 29 + 30 + FROM alpine AS zoekt 31 + 32 + RUN apk add --no-cache git ca-certificates bind-tools tini 33 + 34 + COPY .ctags.d /.ctags.d 35 + COPY --from=ctags /usr/local/bin/universal-* /usr/local/bin/ 36 + COPY --from=builder /go/bin/* /usr/local/bin/ 37 + 38 + # zoekt-webserver has a large stable heap size (10s of gigs), and as such the 39 + # default GOGC=100 could be better tuned. https://dave.cheney.net/tag/gogc 40 + ENV GOGC=50 41 + 42 + ENTRYPOINT ["/sbin/tini", "--"]
+24
Dockerfile.indexserver
··· 1 + FROM alpine 2 + 3 + RUN apk add --no-cache ca-certificates bind-tools 4 + 5 + # Run as non-root user sourcegraph. External volumes should be mounted under /data (which will be owned by sourcegraph). 6 + RUN mkdir -p /home/sourcegraph 7 + RUN addgroup -S sourcegraph && adduser -S -G sourcegraph -h /home/sourcegraph sourcegraph && mkdir -p /data && chown -R sourcegraph:sourcegraph /data 8 + USER sourcegraph 9 + WORKDIR /home/sourcegraph 10 + 11 + ENV SRC_FRONTEND_INTERNAL http://sourcegraph-frontend-internal 12 + ENV DATA_DIR /data/index 13 + RUN mkdir -p ${DATA_DIR} 14 + 15 + # We copy from the locally built zoekt image 16 + COPY --from=zoekt /.ctags.d / 17 + COPY --from=zoekt /usr/local/bin/universal-* /usr/local/bin/zoekt-sourcegraph-indexserver /usr/local/bin/zoekt-archive-index /usr/local/bin/ 18 + 19 + # zoekt indexing has a large stable heap size (gigs), and as such the default 20 + # GOGC=100 could be better tuned. https://dave.cheney.net/tag/gogc 21 + ENV GOGC=50 22 + 23 + ENTRYPOINT ["/sbin/tini", "--"] 24 + CMD zoekt-sourcegraph-indexserver -index $DATA_DIR -sourcegraph_url $SRC_FRONTEND_INTERNAL -listen :6072 -interval 1m -cpu_fraction 1.0
+22
Dockerfile.webserver
··· 1 + FROM alpine 2 + 3 + RUN apk add --no-cache ca-certificates bind-tools 4 + 5 + # Run as non-root user sourcegraph. External volumes should be mounted under /data (which will be owned by sourcegraph). 6 + RUN mkdir -p /home/sourcegraph 7 + RUN addgroup -S sourcegraph && adduser -S -G sourcegraph -h /home/sourcegraph sourcegraph && mkdir -p /data && chown -R sourcegraph:sourcegraph /data 8 + USER sourcegraph 9 + WORKDIR /home/sourcegraph 10 + 11 + ENV DATA_DIR /data/index 12 + RUN mkdir -p ${DATA_DIR} 13 + 14 + # We copy from the locally built zoekt image 15 + COPY --from=zoekt /usr/local/bin/zoekt-webserver /usr/local/bin/ 16 + 17 + # zoekt-webserver has a large stable heap size (10s of gigs), and as such the 18 + # default GOGC=100 could be better tuned. https://dave.cheney.net/tag/gogc 19 + ENV GOGC=50 20 + 21 + ENTRYPOINT ["/sbin/tini", "--"] 22 + CMD zoekt-webserver -index $DATA_DIR -pprof -rpc