2

The following post it too long , please be patient while going through

Hi , i'm quite new to docker and dds .

i am creating a simple code using rti-dds and docker . The code will provide me two exes one for publishing the data and other for subscribing the data.

I want to use FROM scratch in my Dockerfile as i don't need bash nor any os.

Now if i use FROM scratch do i need to have my exes statically build with the g++ -static flag or can it be done dynamically , that is without the static flag.

Which one is preferred or is there a rule to it?

Docker Verion

Client: Docker Engine - Community
Version: 19.03.2
API version: 1.40
Go version: go1.12.8
Git commit: 6a30dfc
Built: Thu Aug 29 05:29:11 2019
OS/Arch: linux/amd64
Experimental: false

Dockerfile when exe files are build with -static flag

FROM scratch

COPY rti_license.dat /
COPY USER_QOS_PROFILES.xml /
COPY /objs/x64Linux3gcc4.8.2/DynamicTest_publisher /
COPY /objs/x64Linux3gcc4.8.2/DynamicTest_subscriber /

CMD ["/DynamicTest_publisher"]

The docker image gets successfully build and runs without any error

BUT

Dockerfile when exe files are build dynamically (without static flag)

figuring all the dependencies were to be copied as well checked the dependencies using

ldd on the exe

FROM scratch

COPY rti_license.dat /
COPY USER_QOS_PROFILES.xml /
COPY /lib/x86_64-linux-gnu/libdl.so.2 /
COPY /lib/x86_64-linux-gnu/libnsl.so.1 /
COPY /lib/x86_64-linux-gnu/libpthread.so.0 /
COPY /lib/x86_64-linux-gnu/librt.so.1 /
COPY /usr/lib/x86_64-linux-gnu/libstdc++.so.6 /
COPY /lib/x86_64-linux-gnu/libc.so.6 /
COPY /lib/x86_64-linux-gnu/libgcc_s.so.1 /
COPY /objs/x64Linux3gcc4.8.2/DynamicTest_publisher /
COPY /objs/x64Linux3gcc4.8.2/DynamicTest_subscriber /
COPY /lib64/ld-linux-x86-64.so.2 /

CMD ["/DynamicTest_publisher"]

Build the docker image

docker build --tag dynamictest .

But when i try to run this i get the following error

docker run --rm -it dynamictest

Error
standard_init_linux.go:211: exec user process caused "no such file or directory

So , am i missing something here or is it that "FROM scratch only works with static builds"

i4nk1t
  • 419
  • 1
  • 6
  • 16
  • In theory what you're trying to do is possible. Remember that you can only `COPY` files from within the current directory (`/lib64/ld-linux-x86-64.so.2` is interpreted relative to the `docker build` directory). You might try `/lib/ld-linux-x86-64.so.2 --list /DynamicTest_publisher` as the container command, as a long manual form of `ldd`, and see if it finds everything. – David Maze Oct 03 '19 at 11:41
  • Hi @DavidMaze , thanks for looking into it , i tried changing the Dockerfile CMD to CMD /lib/ld-linux-x86-64.so.2 --list /DynamicTest_publisher , still no luck. `docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"/lib64/ld-linux-x86-64.so.2 --list /DynamicTest_publisher\": stat /lib64/ld-linux-x86-64.so.2 --list /DynamicTest_publisher: no such file or directory": unknown.` – i4nk1t Oct 03 '19 at 11:58
  • Why aren't you copying all ndds libraries in a dynamic build? – Johnny Willemsen Oct 04 '19 at 07:15
  • @JohnnyWillemsen I did copy all the required libraries , the catch was since i was using scratch i had to ldd on the exe to see what all dynamic libraries were required , and i copied them along with the folder structure, after that i had to copy them in the container too using COPY command in docker file and finally it worked. – i4nk1t Oct 18 '19 at 09:36

1 Answers1

3

THIS WORKED OUT BEST FOR ME - Dynamic Build

The very first thing was to find out all the dependencies for your exe file

    $ldd dytest_publisher

    linux-vdso.so.1 =>  (0x00007ffec3df9000)
    libdl.so.2 => /usr/lib64/libdl.so.2 (0x00007ffb0e740000)
    libnsl.so.1 => /usr/lib64/libnsl.so.1 (0x00007ffb0e526000)
    libpthread.so.0 => /usr/lib64/libpthread.so.0 (0x00007ffb0e30a000)
    librt.so.1 => /usr/lib64/librt.so.1 (0x00007ffb0e102000)
    libstdc++.so.6 => /usr/local/lib64/libstdc++.so.6 (0x00007ffb0dd28000)
    libm.so.6 => /usr/lib64/libm.so.6 (0x00007ffb0da26000)
    libc.so.6 => /usr/lib64/libc.so.6 (0x00007ffb0d665000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ffb0e945000)
    libgcc_s.so.1 => /usr/local/lib64/libgcc_s.so.1 (0x00007ffb0d44c000)

Copy the above libraries along with the folder structure in your project folder and create a docker file with name Dockerfile

Dockerfile

FROM scratch

COPY rti_license.dat / 
COPY USER_QOS_PROFILES.xml /     
COPY /objs/x64Linux3gcc4.8.2/DynamicTest_publisher /     
COPY /objs/x64Linux3gcc4.8.2/DynamicTest_subscriber /     
COPY /lib64/* /lib64/     
COPY /usr/lib64/* /usr/lib64/      

ENV LD_LIBRARY_PATH=/usr/lib64/:/lib64/     

CMD ["/dytest_publisher"]   

Note: project folder must have the directory: /usr/lib64/ and /lib64/ along with all the depended libraries. Depended libraries can be checked by the following command :

$ldd "your exe file" 

Build the docker image

docker build --tag dynamictest .

Running the created image

docker run --rm -it dynamictest

To see the running container

docker container ls

PS : thanks to everyone for their help on this

i4nk1t
  • 419
  • 1
  • 6
  • 16
  • Made my day! Thank you very much! – mavogel Jul 17 '20 at 07:40
  • The LD_LIBRARY_PATH line gives a hint that you might not need the complicated structure. – Adrian May Apr 15 '22 at 06:43
  • For someone coming here -- this is not enough, e.g. you need nsswitch and a couple of other files for DNS to work. Then you'll want locale, local users and so on. Some of these extras can be produced by stracing openat and execve syscalls, but not all. – nponeccop Aug 12 '22 at 01:05