Error building Go + go-oci8 with docker in WSL2 - oracle

I build a Go project and try to connect exist remote Oracle Database using go-oci8.
The environment is wsl2 on window 10. I'm using Oracle Instant Client 21.1.
My oci8.pc location:
/usr/lib/pkgconfig
My oci8.pc file:
prefix=/opt/oracle/instantclient_21_1
exec_prefix=${prefix}
libdir=${prefix}
includedir=${prefix}/sdk/include
glib_genmarshal=glib-genmarshal
gobject_query=gobject-query
glib_mkenums=glib-mkenums
Name: oci8
Description: oci8 library
Libs: -L${libdir} -lclntsh
Cflags: -I${includedir}
Version: 21.1
My Dockerfile:
# Dockerfile
FROM golang:latest AS builder
ENV GO111MODULE=on
# Download modules
WORKDIR $GOPATH/src/github.com/hadeshunter/todo
COPY go.mod go.sum ./
RUN go mod download
# Build
COPY . ./
RUN CGO_ENABLED=1 GOOS=linux go build -a -installsuffix nocgo -o /todo .
# Run
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /todo ./
EXPOSE 5000
ENTRYPOINT ["./todo"]
My ~/.zshrc, I add
export PKG_CONFIG_PATH=/usr/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=/opt/oracle/instantclient_21_1:$LD_LIBRARY_PATH
I using command run
go run main.go
Everything is success. But when run build with docker
docker-compose build && docker-compose run --rm --service-ports todo
I get error:
# pkg-config --cflags -- oci8
Package oci8 was not found in the pkg-config search path.
Perhaps you should add the directory containing `oci8.pc'
to the PKG_CONFIG_PATH environment variable
No package 'oci8' found
pkg-config: exit status 1
ERROR: Service 'todo' failed to build : The command '/bin/sh -c CGO_ENABLED=1 GOOS=linux go build -a -installsuffix nocgo -o /todo .' returned a non-zero code: 2
Does anyone give me suggestion, pls?

Related

Dockerfile configuration for GSSAPI with SASL_SSL support for alpine based Go image

I have a Confluence Kafka consumer written in Golang. I am trying to deploy it in a PKS cluster.
The Kafka config looks like this,
kafka.bootstrap.servers=server.myserver.com
kafka.security.protocol=SASL_SSL
kafka.sasl.mechanisms=GSSAPI
kafka.group.id=kafka-go-getting-started
kafka.auto.offset.reset=latest
kafka.topic=topic.consumer-topic
acks=all
I need to configure my Dockerfile for GSSAPI mechanism with SASL_SSL protocol. I have managed to resolve the GSSAPI thing, however, currently it shows,
**Failed to create consumer: Unsupported value "SASL_SSL" for configuration property "security.protocol": OpenSSL not available at build time**
Here is how my Dockerfile looks like:
FROM golang:1.19-alpine3.16 as c-bindings
RUN apk update && apk upgrade && apk add pkgconf git bash build-base sudo
RUN git clone https://github.com/edenhill/librdkafka.git
RUN cd librdkafka && ./configure && make && sudo make install
FROM c-bindings as app-builder
WORKDIR /go/app
COPY . .
RUN go mod download
RUN go mod verify
RUN go build -race -tags musl --ldflags "-extldflags -static -s -w" -o main ./main.go
FROM scratch AS app-runner
WORKDIR /go/app/
COPY --from=app-builder /go/app/main ./main
CMD ["/go/app/main"]`
Tried some ways in Dockerfile to make OpenSSL available, however things are stuck at same. Not sure if both GSSAPI mechanism as well as SASL_SSL protocol can be resolved over a common solution.
[Dec 05, 2022] Latest try:
Dockerfile,
FROM golang:1.19-alpine as c-bindings
RUN apk update && apk upgrade && apk add pkgconf git bash build-base sudo
FROM c-bindings as app-builder
WORKDIR /go/app
COPY . .
RUN go mod download
RUN go mod verify
RUN apk add zstd-dev
RUN apk add krb5
RUN apk add cyrus-sasl-gssapiv2
RUN apk add cyrus-sasl-dev
RUN apk add openssl-dev
RUN git clone https://github.com/edenhill/librdkafka.git
RUN cd librdkafka && ./configure --install-deps && make && sudo make install
COPY krb5.conf /etc/krb5.conf
COPY jaas.conf /etc/jaas.conf
RUN go build -race -tags dynamic -o main ./main.go
CMD ["/go/app/main"]
Kafka config -
kafka.bootstrap.servers=server.myserver.com
kafka.security.protocol=SASL_SSL
kafka.sasl.mechanism=GSSAPI
kafka.group.id=kafka-go-getting-started
kafka.auto.offset.reset=latest
kafka.topic=topic.consumer-topic
kafka.ssl.ca.location=/etc/ssl/certs/my-cert.pem
kafka.sasl.kerberos.service.name=kafka
kafka.sasl.kerberos.keytab=/etc/security/keytab/consumer.keytab
kafka.sasl.kerberos.principal=principal#myprincipal.COM
acks=all
Now the container is technically running. However, it is not able to run the Kafka consumer application with below errors -
GSSAPI Error: A token had an invalid MIC (unknown mech-code 0 for mech unknown)
that is because you are missing the SSL or SASL dependancies you would need to make sure that libssl-dev, hoewever it could also needs those libsasl2-dev, libsasl2-modules, but libssl-dev should be enough though
adding the following to the DOCKERFILE should help to resolve it
RUN apk add libressl-dev
here is the official libssl and the alpine pkg

Unable to run golangci-lint on bitbuckt CI

I have setup golangci-lint in my development enviroment with configuring makefile,
MakeFile
build: lint_provider
go build -o ${BINARY}
lint_provider:
golangci-lint run -c .golangci.yml
install: build
mkdir -p ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}...
mv ${BINARY} ~/terraform.d/plugins/....
bitbucket-pipelines.yml
pipelines:
default:
- step:
image:
hashicorp/terraform:latest
script:
- apk add go
- apk add make
- wget -0- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.44.2
- make install
- cd terraformprovider/examples/test
- ./testall.sh
this pipelining failed with
+ make install
golangci-lint run -c .golangci.yml
make: golangci-lint: No such file or directory
make: *** [Makefile:12: lint_provider] Error 127
Makefile : 12 is
golangci-lint run -c .golangci.yml
the same setup is working with the development environment
in the development environment, golangci-lint installed with
brew install golangci-lint
how do I execute golangci-lint with bitbucket pipeline environment?
Looks like golangci-lint isnt installed succesfully or installed in the directory outside of the PATH
By default this installer uses ./bin directory, so you can try ./bin/golangci-lint run -c .golangci.yml, or you can use BINDIR variable to set installation path.

How to import an unpopular package to Docker using the GOLang official image?

I've posted this question already as an issue on the imagick git repository, but it has a very small user-base, so I'm hoping to get some help from here. I've been trying for a few days now to import https://github.com/gographics/imagick to Docker using the official goLang dockerfile for a project I'm working on, but have been unsuccessful. Since this package isn't popular, running apt-get won't work. I've (hesitantly) tried to just add the files to the container, but that didn't work. Here's the DockerFile I've built and the error it produces:
===DOCKERFILE===
# 1) Use the official go docker image built on debian.
FROM golang:latest
# 2) ENV VARS
ENV GOPATH $HOME/<PROJECT>
ENV PATH $HOME/<PROJECT>/bin:$PATH
# 3) Grab the source code and add it to the workspace.
ADD . /<GO>/src/<PROJECT>
ADD . /<GO>/gopkg.in
# Trying to add the files manually... Doesn't help.
ADD . /opt/local/share/doc/ImageMagick-6
# 4) Install revel and the revel CLI.
#(The commented out code is from previous attempts)
#RUN pkg-config --cflags --libs MagickWand
#RUN go get gopkg.in/gographics/imagick.v2/imagick
RUN go get github.com/revel/revel
RUN go get github.com/revel/cmd/revel
# 5) Does not work... Can't find the package.
#RUN apt-get install libmagickwand-dev
# 6) Get godeps from main repo
RUN go get github.com/tools/godep
# 7) Restore godep dependencies
WORKDIR /<GO>/src/<PROJECT>
RUN godep restore
# 8) Install Imagick
#RUN go build -tags no_pkgconfig gopkg.in/gographics/imagick.v2/imagick
# 9) Use the revel CLI to start up our application.
ENTRYPOINT revel run <PROJECT> dev 9000
# 10) Open up the port where the app is running.
EXPOSE 9000
===END DOCKERFILE===
This allows me to build the docker container, but when I try to run it, I get the following error in the logs of kinematic:
===DOCKER ERROR===
ERROR 2016/08/20 21:15:10 build.go:108: # pkg-config --cflags MagickWand MagickCore MagickWand MagickCore
pkg-config: exec: "pkg-config": executable file not found in $PATH
2016-08-20T21:15:10.081426584Z
ERROR 2016/08/20 21:15:10 build.go:308: Failed to parse build errors:
#pkg-config --cflags MagickWand MagickCore MagickWand MagickCore
pkg-config: exec: "pkg-config": executable file not found in $PATH
2016-08-20T21:15:10.082140143Z
===END DOCKER ERROR===
Most base images have package lists removed to avoid to reduce image size. Thus, in order to install something with apt-get, you first need to update the package lists and then install whatever package you wish. Then, after installing the package, remove all side-effects of running apt to avoid polluting the image with unneeded files (all that necessarily as a single RUN command).
The following Dockerfile should do the trick:
FROM golang:latest
RUN apt-get update \ # update package lists
&& apt-get install -y libmagickwand-dev \ # install the package
&& apt-get clean \ # clean package cache
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # remove everything else
RUN go get gopkg.in/gographics/imagick.v2/imagick
Remember to add -y to apt-get install, because docker build is non-interactive.

Go-compiled binary won't run in an alpine docker container on Ubuntu host

Given a binary, compiled with Go using GOOS=linux and GOARCH=amd64, deployed to a docker container based on alpine:3.3, the binary will not run if the docker engine host is Ubuntu (15.10):
sh: /bin/artisan: not found
This same binary (compiled for the same OS and arch) will run just fine if the docker engine host is busybox (which is the base for alpine) deployed within a VirtualBox VM on Mac OS X.
This same binary will also run perfectly fine if the container is based on one of Ubuntu images.
Any idea what this binary is missing?
This is what I've done to reproduce (successful run in VirtualBox/busybox on OS X not shown):
Build (building explicitly with flags even though the arch matches):
➜ artisan git:(master) ✗ GOOS=linux GOARCH=amd64 go build
Check it can run on the host:
➜ artisan git:(master) ✗ ./artisan
10:14:04.925 [ERROR] artisan: need a command, one of server, provision or build
Copy to docker dir, build, run:
➜ artisan git:(master) ✗ cp artisan docker/build/bin/
➜ artisan git:(master) ✗ cd docker
➜ docker git:(master) ✗ cat Dockerfile
FROM docker:1.10
COPY build/ /
➜ docker git:(master) ✗ docker build -t artisan .
Sending build context to Docker daemon 10.15 MB
Step 1 : FROM docker:1.10
...
➜ docker git:(master) ✗ docker run -it artisan sh
/ # /bin/artisan
sh: /bin/artisan: not found
Now changing the image base to phusion/baseimage:
➜ docker git:(master) ✗ cat Dockerfile
#FROM docker:1.10
FROM phusion/baseimage
COPY build/ /
➜ docker git:(master) ✗ docker build -t artisan .
Sending build context to Docker daemon 10.15 MB
Step 1 : FROM phusion/baseimage
...
➜ docker git:(master) ✗ docker run -it artisan sh
# /bin/artisan
08:16:39.424 [ERROR] artisan: need a command, one of server, provision or build
By default, if using the net package a build will likely produce a binary with some dynamic linking, e.g. to libc. You can inspect dynamically vs. statically link by viewing the result of ldd output.bin
There are two solutions I've come across:
Disable CGO, via CGO_ENABLED=0
Force the use of the Go implementation of net dependencies, netgo via go build -tags netgo -a -v, this is implemented for a certain platforms
From https://golang.org/doc/go1.2:
The net package requires cgo by default because the host operating system must in general mediate network call setup. On some systems, though, it is possible to use the network without cgo, and useful to do so, for instance to avoid dynamic linking. The new build tag netgo (off by default) allows the construction of a net package in pure Go on those systems where it is possible.
The above assumes that the only CGO dependency is the standard library's net package.
I had the same issue with a go binary, and I got it to work after adding this to my docker file:
RUN apk add --no-cache libc6-compat
Go compiler from your build machine probably links your binary with libraries on different location than in Alpine. In my case it was compiled with dependencies under /lib64 but Alpine does not use that folder.
FROM alpine:edge AS build
RUN apk update
RUN apk upgrade
RUN apk add --update go=1.8.3-r0 gcc=6.3.0-r4 g++=6.3.0-r4
WORKDIR /app
ENV GOPATH /app
ADD src /app/src
RUN go get server # server is name of our application
RUN CGO_ENABLED=1 GOOS=linux go install -a server
FROM alpine:edge
WORKDIR /app
RUN cd /app
COPY --from=build /app/bin/server /app/bin/server
CMD ["bin/server"]
I'm working on article about this issue. You can find draft with this solution here http://kefblog.com/2017-07-04/Golang-ang-docker .
What did the trick for me was enabling static linking in the linker options:
$ go build -ldflags '-linkmode external -w -extldflags "-static"'
The -linkmode option tells Go to use the external linker, the -extldflags option sets options to pass to the linker and the -w flag disables DWARF debug info to improve binary size.
See go tool link and Statically compiled Go programs, always, even with cgo, using musl
for more details
I had an app that required CGO_ENABLED=1.
The fix for me to run the compiled go binary in a debian-slim container was to build the binary using RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -o goapp
And run the following commands in the debian slim
RUN apt-get update && apt-get install -y musl-dev
RUN ln -s /usr/lib/x86_64-linux-musl/libc.so /lib/libc.musl-x86_64.so.1
Made me able to run the goapp afterwards
TIP: ldd goapp showed that libc.musl-x86_64 was missing in the container.
While executing a go binary inside a debian docker container, faced this issue:
/bin/bash: line 10: /my/go/binary: No such file or directory
The binary was built by using docker-in-docker (dind) from an alpine container using command:
GOOS=linux GOARCH=amd64 go build
Fixed it by using following env while building the binary:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build

getting "cannot find package" trying to build my application in a docker container

Here is my Dockerfile.
FROM ubuntu
MAINTAINER me <my#email.com>
RUN apt-get update && apt-get install -y \
build-essential \
curl \
git \
make
# Get and compile go
RUN curl -s https://go.googlecode.com/files/go1.2.1.src.tar.gz | tar -v -C /usr/local -xz
RUN cd /usr/local/go/src && ./make.bash --no-clean 2>&1
ENV PATH /usr/local/go/bin:/go/bin:$PATH
ENV GOPATH /go
RUN go get github.com/gorilla/feeds
WORKDIR /go
CMD go version && go install feed && feed
It builds just fine:
sudo docker build -t ubuntu-go .
but when I run it I get a package error:
sudo docker run -v /home/rbucker/go:/go --name go ubuntu-go
The error looks like:
src/feed/feed.go:7:2: cannot find package "github.com/gorilla/feeds" in any of:
/usr/local/go/src/pkg/github.com/gorilla/feeds (from $GOROOT)
/go/src/github.com/gorilla/feeds (from $GOPATH)
It's odd because "go install" is not installing the dependencies and while the previous "go get github.com/gorilla/feeds" completes without errors. So presumably I have a path or environment problem but all of the examples look just like this one.
PS: my code is located in /go/src/feed (feed.go)
package main
import (
"net/http"
"time"
"github.com/gorilla/feeds"
)
. . .
UPDATE: when I performed the "go get" manually and then launched the "run" it seemed to work. So it appears that the "RUN go get" is storing my file in the ether instead of my host's volume.
sudo docker run -v /home/rbucker/go:/go --name go ubuntu-go /bin/bash
then
sudo docker run -v /home/rbucker/go:/go --name go ubuntu-go
(the files were located in my ~/go/src/githum.com and ~/go/pkg folders.)
UPDATE: It occurs to me that during the BUILD step the /go volume has not been attached to the docker image. So it's essentially assigned to nil. But then during the run the "get install" should have retrieved it's deps.
FINALLY: this works but is clearly not the preferred method:
CMD go get github.com/gorilla/feeds && go version && go install feed && feed
notice that I performed the "go get" in the CMD rather than a RUN.
I solved something similar to this by using
go get ./...
Source:
https://coderwall.com/p/arxtja/install-all-go-project-dependencies-in-one-command

Resources