5

I have a Go service that references a C library, and I am getting the following error when trying to run my docker image:

standard_init_linux.go:228: exec user process caused: no such file or directory

This is not a duplicate of standard_init_linux.go:190: exec user process caused "no such file or directory" - Docker as I do not have an entrypoint shell script with CR line endings. Some others on this site suggested setting CGO_ENABLED=0 at compile time, but I of course can't do that as this is a CGO project.

The C library is installed under /usr/local/lib/sgp4 in the directories Linux/IFORT and Linux/GFORTRAN, which contain a bunch of .so files.

An environment variable LD_LIBRARY_PATH is set to /usr/local/lib/sgp4/Linux/IFORT.

Within my project, there is a set of wrapper .h files, and the CGO comments as follows:

go setup

My Dockerfile is as follows:

FROM [redacted]/alpine-base:3.17

RUN apk update && \
    apk add curl jq

COPY etc/cfg/propagator.properties /usr/local/[redacted]/etc/cfg/
COPY bin/sgp4 /usr/local/[redacted]/bin/sgp4
COPY propagator/wrappers /usr/local/[redacted]/bin/wrappers

# Download library files
RUN mkdir -p /usr/local/sgp4/lib
RUN curl --output /usr/local/sgp4/lib/SGP4.tar [redacted]/SGP4.tar
RUN tar -xf /usr/local/sgp4/lib/SGP4.tar -C /usr/local/sgp4/lib
RUN rm /usr/local/sgp4/lib/SGP4.tar
RUN export LD_LIBRARY_PATH=/usr/local/sgp4/lib/Linux/IFORT

RUN chmod a+rx /usr/local/[redacted]/bin/sgp4

RUN addgroup [redacted] && adduser -D -H -G [redacted] [redacted]
USER [redacted]:[redacted]

HEALTHCHECK NONE

ENTRYPOINT ["/usr/local/[redacted]/bin/sgp4", "-config-file-path=/usr/local/[redacted]/etc/cfg/propagator.properties"]

Wondering if my library files contained CR line endings, I tried adding these commands to my Dockerfile, but no luck:

RUN for filey in $(find /usr/local/sgp4/lib/Linux -type f); do echo $filey; sed -i 's/\r$//g' $filey; done
RUN for filey in $(find /usr/local/sgp4/lib/Linux -type f); do echo $filey; tr -d \r < $filey > tmp.so; mv tmp.so $filey; done

Note: I compiled the binary on debian, but am constrained to using Alpine for the Docker image. Issues I encountered when compiling are discussed here: cgo compiler error, missing library links, librt.so.1 not found

robbieperry22
  • 1,753
  • 1
  • 18
  • 49
  • 1
    Check that you have all `.so` dependencies. Replace the entrypoint with `ldd /usr/local/[redacted]/bin/sgp4` and study if there are unmapped libs. And then check each `.so` from those dependencies since they do have dependencies themselves. – Pak Uula Jul 27 '23 at 00:24
  • 1
    I had such issues with alpine - by default it has no `glibc` and go-produced binaries fail. Installing `gcompat` helped: https://wiki.alpinelinux.org/wiki/Running_glibc_programs – Pak Uula Jul 27 '23 at 00:28
  • 1
    `RUN export` doesn't do anything; do you need to `ENV LD_LIBRARY_PATH=...`? (Also see [docker ENV vs RUN export](https://stackoverflow.com/questions/33379393/docker-env-vs-run-export).) If the system can't find the C shared libraries that will result in a "no such file or directory" error. – David Maze Jul 27 '23 at 00:57
  • @PakUula Interesting, I installed `gcompat` and now the `no such file or directory` log is gone. Now there are no logs at all, just immediate crash loop. – robbieperry22 Jul 27 '23 at 18:44
  • @PakUula Running `ldd` on the binary gives a `bash: ./sgp4: cannot execute: required file not found` error. – robbieperry22 Jul 27 '23 at 22:23
  • 2
    I'd recommend using a Debian, e.g. `debian:11-slim`. Alpine is a very specific image, a lot was sacrificed for the minimal footprint. Slim debian is just 80 Mb, and it is the real Linux server. – Pak Uula Jul 28 '23 at 07:24

1 Answers1

4

A way to solve the runtime issue would be to switch to a glibc-based Docker image such as Debian slim or jeanblanchard/docker-alpine-glibc, because your Go binary and its CGO dependencies were built against glibc.

Using jeanblanchard/alpine-glibc, since it is still based on Alpine:

FROM jeanblanchard/alpine-glibc:3.18

RUN apk update && \
    apk add curl jq

COPY etc/cfg/propagator.properties /usr/local/[redacted]/etc/cfg/
COPY bin/sgp4 /usr/local/[redacted]/bin/sgp4
COPY propagator/wrappers /usr/local/[redacted]/bin/wrappers

# Download library files
RUN mkdir -p /usr/local/sgp4/lib
RUN curl --output /usr/local/sgp4/lib/SGP4.tar [redacted]/SGP4.tar
RUN tar -xf /usr/local/sgp4/lib/SGP4.tar -C /usr/local/sgp4/lib
RUN rm /usr/local/sgp4/lib/SGP4.tar
ENV LD_LIBRARY_PATH=/usr/local/sgp4/lib/Linux/IFORT

RUN chmod a+rx /usr/local/[redacted]/bin/sgp4

RUN addgroup [redacted] && adduser -D -H -G [redacted] [redacted]
USER [redacted]:[redacted]

HEALTHCHECK NONE

ENTRYPOINT ["/usr/local/[redacted]/bin/sgp4", "-config-file-path=/usr/local/[redacted]/etc/cfg/propagator.properties"]

This base image maintains the small footprint of Alpine but also has the compatibility of glibc, which should make it compatible with your CGO binary.

Switching to this Dockerfile and rebuilding your image should solve the "exec user process caused: no such file or directory" error, as well as the "required file not found" error from ldd.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250