NodeMCU Build in Docker results in "exec format error" - docker

I'm trying the NodeMCU Docker build in Ubuntu 16.04.4 LTS for the first time.
I have read the tagged articles here for Docker and NodeMCU, but don't see this particular error.
"docker run hello-world" has no problems.
I have tried the NodeMCU build command in both forms:
$ docker run --rm -ti -v `pwd`:/opt/nodemcu-firmware marcelstoer/nodemcu-build
and the explicit path variation:
$ docker run --rm -it -v /home/tim/nodemcu-firmware:/opt/nodemcu-firmware marcelstoer/nodemcu-build
In both cases, I get this error:
standard_init_linux.go:187: exec user process caused "exec format error"
I have searched on this error, and most solutions are related to a missing shebang.
However, I'm not sure what script would need the shebang, or why it would be not working in my case but correct for others.
Has anyone else run across this error?

Speaking without deep technical details, this error means that the kernel can not recognize the format of the executable file, thus, it can not run this file. In your case this error is about the executable file which is started when the container is launched. According to the Cmd entry in the output of docker inspect marcelstoer/nodemcu-build, it is a file /bin/sh, which is an ELF executable.
When Linux can not execute ELF binary and returns such an error (about the file format), it usually is related to the system architecture. More specifically, the image marcelstoer/nodemcu-build contains ELF64 executables (i.e. for amd64 architecture), and your system does not support it (is it i386 or even some flavor of arm?). Running docker run hello-world, however, works fine for you, because hello-world image exists for all architectures supported by Docker.
According to the Dockerfile of marcelstoer/nodemcu-build image, it is built from ubuntu, which exists for different architectures, thus, you may try building the marcelstoer/nodemcu-build image on your system rather than pulling it from the dockerhub.
P.S.: regarding the solution you have linked to your question. This is not about your case (ELF binary), rather it is about a script. In case of script, the executable format is recognized by the shebang (#!) at the very beginning of the file, thus, the script must start with #!, not with the newline. That's why the author got the same error: the kernel could not detect that this is a script and failed to start it. Different (but similar) reasons, same error.

Related

Trying to port application to docker nanoserver container. Running exe fails with exit code -1073741515 (Dependency missing)

I'm currently trying to port my image optimizer application to a NanoServer docker image. One of the tools my image optimizer uses is truepng.exe. (Can be downloaded here: http://x128.ho.ua/clicks/clicks.php?uri=TruePNG_0625.zip)
I simply created a nanoserver container and mounted a folder that contained truepng.exe:
docker run --rm -it -v C:\data:C:\data mcr.microsoft.com/windows/nanoserver:2004-amd64
When I now run truepng.exe I expect some output regarding command line arguments missing:
C:\MyLocalWindowsMachine>truepng
TruePNG 0.6.2.5 : PNG Optimizer
by x128 (2010-2017)
x128#ua.fm
...
However when I call this from inside the nanoserver docker container I basically see no output:
C:\data>truepng
C:\data>echo %ERRORLEVEL%
-1073741515
As you can see above, the exit code is set to -1073741515. According to this it typically means that there's a dependency missing.
I then downloaded https://github.com/lucasg/Dependencies to see the dependencies of truepng:
It seems it has some dependencies on 5 DLL's. Looking these up I found that there's apparently something called 'Reverse Forwarders': https://cloudblogs.microsoft.com/windowsserver/2015/11/16/moving-to-nano-server-the-new-deployment-option-in-windows-server-2016/
According to the following post though they should already be included in nanoserver: https://social.technet.microsoft.com/Forums/en-US/5b36a6d3-84c9-4940-8b7a-9e2a38468291/reverse-forwarders-package-in-tp5?forum=NanoServer
After all this investigation I've also been playing around with manually copying over the DLL's from my local machine (system32) to the docker machine without any success (it just kept breaking other things like the copy command which required me to recreate the container). Next to that I've also copied the files from SysWOW64, but this didn't help either.
I'm currently quite stranded on how to proceed further as I'm not even sure if the tool is missing dependencies or if something else is going on. Is there a way to investigate what DLL's are missing once a tool is starting?
Kind regards,
Devedse
Edit 1: Idea from #CherryDT
I tried running gflags (https://social.msdn.microsoft.com/Forums/en-US/f004a7e5-9024-4555-9ada-e692fbc3160d/how-to-start-quotloader-snapsquot?forum=vcgeneral) which gave the following output:
C:\data>"C:\data\gflags.exe" /i TruePNG.exe +sls
Current Registry Settings for TruePNG.exe executable are: 00000000
After this I tried running Dbgview.exe, this however never resulted in a log file being written:
C:\data>"C:\data\DebugView\Dbgview.exe" /v /l debugview-log.txt /g /n
C:\data>
I also started TruePNG.exe again, but again, no log file was written.
I tried querying the EventLogs using a dotnet core application, but this resulted in the following exception:
Unhandled exception. System.InvalidOperationException: Cannot open log Application on computer '.'. This function is not supported on this system.
at System.Diagnostics.EventLogInternal.OpenForRead(String currentMachineName)
at System.Diagnostics.EventLogInternal.GetEntryAtNoThrow(Int32 index)
at System.Diagnostics.EventLogEntryCollection.GetEntryAtNoThrow(Int32 index)
at System.Diagnostics.EventLogEntryCollection.EntriesEnumerator.MoveNext()
at EventLogReaderTest.ConsoleApp.Program.Main(String[] args) in C:\data\EventLogReaderTest.ConsoleApp\Program.cs:line 22
Windows Nano Server is tiny and only supports 64-bit applications, tools, and agents. The missing dependency in this case is the entire x86 emulation layer (WoW64), as TruePNG is a 32-bit application.
Windows Server Core contains WoW64 and other components missing from Nano Server. Use a Windows Server Core image instead.
Example command:
docker run --rm -it -v C:\Temp:C:\Temp mcr.microsoft.com/windows/servercore:2004 C:\Temp\TruePNG.exe
Yields the expected output:
TruePNG 0.6.2.5 : PNG Optimizer
by x128 (2010-2017)
x128#ua.fm
TruePNG {options} files
options:
/f# PNG delta filters 0=None, 1=Sub, 2=Up, 3=Average, 4=Paeth, 5=Mixed
/fe PNG extra filters, overrides /f switch
/i# PNG interlace method 0=None, 1=Adam7 (default input)
/g# PNG gamma 0=Remove, 1=Apply & Remove, 2=Keep (default)
[...]

Snakemake + Docker Volumes - "Missing Rule Exception"

I'm trying to use snakemake with a docker image, but am having trouble with the docker volume. Unfortunately, there are no details on how to use 'singularity-args' to do this.
My snakemake file is:
rule all:
input:
'a/file3.txt'
rule step1:
output:
touch('a/file1.txt')
rule step2:
input:
rules.step1.output[0]
output:
'a/file2.txt'
params:
text = 'this is a test',
path = '/data/file2.txt'
singularity:
"docker://XXX/test"
shell:
"python test.py {params.text} {params.path}"
rule step3:
input:
rules.step2.output[0]
output:
touch('a/file3.txt')
The docker image is basically a python file that writes a string to file (for testing purposes). I'm trying to mount my home directory to the docker /data directory. With docker, I'm able to mount a volume using '-v'.
What is the correct way of doing this with snakemake?
I've tried the following commands (on MacOS and Ubuntu 18.04) and both have failed.
snakemake -s pipeline.py --use-singularity --singularity-args “-B /home/XXX/snakemake/a:/data”
snakemake -s pipeline.py --use-singularity --singularity-args “-B /home/XXX/snakemake/a”
The error message is:
No rule to produce /home/XXX/snakemake/a:/data” (if you use input functions make sure that they don't raise unexpected exceptions).
Am I missing a step?
Thanks in advance!
Just a trivial check... In your command lines you have tilted double quotes (“) instead of the straight ones ("), e.g.:
snakemake -s pipeline.py --use-singularity --singularity-args “-B /home/XXX/snakemake/a”
Maybe you are are copying and pasting from a text editor that uses the tilted quotes? I would use straight quotes as the other type would probably be interpreted in the wrong way.
I was able to get it working on Ubuntu 18.04 with the following command:
SINGULARITY_BINDPATH=“/home/XXX/snakemake/a:/data”; snakemake -s pipeline.py --latency-wait 10 --use-singularity
Unfortunately I wasn’t able to get the flag “--singularity-args” to work. Regardless of using ‘--bind’ or ‘-B’, I got the error “No rule to produce /Users/XXX/Devel/snakemake/a:/data”.
I’m using Snakemake 5.6.0 inside a Python3 virtual environment.
Also, on a side note, I don’t believe the MacOS singularity binary works. It had issues with Snakemake.
This work-around is good enough for now.
UPDATE
While this solution worked, the real solution (typo) was provided by #dariober.

Unable to run a Docker image with a Rust executable

I am trying to create an image with my binary file (written in Rust) but I get different errors. This is my Dockerfile:
FROM scratch
COPY binary /
COPY .env /
COPY cert.pem /etc/ssl/
ENV RUST_BACKTRACE 1
CMD /binary
Building finishes fine but when I try to run it I get this:
$ docker run binary
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"/bin/sh\": stat /bin/sh: no such file or directory": unknown.
ERRO[0000] error waiting for container: context canceled
And this:
$ docker run binary /binary
standard_init_linux.go:195: exec user process caused "no such file or directory"
I have no idea what to do. The error message looks very odd to me. According to the official Docker documentation it must work.
System info: latest Arch Linux and Docker:
Docker version 18.02.0-ce, build fc4de447b5
I tested with a C++ program and it works fine, with both clang and gcc.
It does not work with scratch, alpine, busybox ,or bash-based images, but it does work with postgresql, ubuntu, and debian images. The exact problem is something related to Rust and lightweight docker images - everything works okay otherwise.
As #Oleg Sklyar pointed out, the problem is that the Rust binary is dynamically-linked.
This may be a bit confusing because many people who have heard of Rust have also heard that Rust binaries are statically-linked, but this refers to the Rust code in crates: crates are linked statically because they are all known at the moment of compilation. This does not refer to existing C dynamic libraries that the program may link to, such as libc and other must-have libraries. Often times, these libraries can also be built as statically-linked artifacts (see the end of this post). To check whether your program or library is dynamically-linked, you can use ldd utility:
$ ldd target/release/t
linux-vdso.so.1 (0x00007ffe43797000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007fa78482d000)
librt.so.1 => /usr/lib/librt.so.1 (0x00007fa784625000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fa784407000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007fa7841f0000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007fa783e39000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fa784ca2000)
You'll need these libraries in your Docker image. You will also need the interpreter; to get its path you can use objdump utility:
$ LANG=en objdump -s -j .interp target/release/t
target/release/t: file format elf64-x86-64
Contents of section .interp:
0270 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-linux-
0280 7838362d 36342e73 6f2e3200 x86-64.so.2.
Copy the files into the expected directories and everything works okay.
There is also a second option which is to use the rust-musl-builder docker image. There are some problems with postgresql and diesel but for most of projects it would be good. It works by producing a statically-linked executable which you may just copy and use. This option is much more preferred than using an interpreter and dynamic libraries if you want to provide a docker image with less size and without having all that useless extra data such as interpreter, unused libraries and so on.
In my case, the issue was that I was passing an invalid executable name:
CMD ["liquidator"]
liquidator was the name of the Docker image, but I needed this:
CMD ["hifi-liquidator"]
Basically the CMD must be the same as the "name" field in the Cargo.toml file.

How to run Bazel container images on OSX?

According to the documentation at bazelbuild/rules_docker, it should be possible to work with these container images on OSX, and it also claims that it's possible to do so without docker.
These rules do not require / use Docker for pulling, building, or pushing images. This means:
They can be used to develop Docker containers on Windows / OSX without boot2docker or docker-machine installed.
They do not require root access on your workstation.
How do I do that? Here's a simple rule:
go_image(
name = "helloworld_image",
importpath = "github.com/nictuku/helloworld",
library = ":go_default_library",
visibility = ["//visibility:public"],
)
I can build the image with bazel build :helloworld_image. It produces a tar ball in blaze-bin, but it won't run it:
INFO: Running command line: bazel-bin/helloworld_image
Loaded image ID: sha256:08d312b529d30431c68741fd3a31468a02533f27a8c2c29eedc969dae5a39852
Tagging 08d312b529d30431c68741fd3a31468a02533f27a8c2c29eedc969dae5a39852 as bazel:helloworld_image
standard_init_linux.go:185: exec user process caused "exec format error"
ERROR: Non-zero return code '1' from command: Process exited with status 1.
It's trying to run the linux this is OSX, which is silly.
I also tried doing a "docker load" on the .tar content but it doesn't seem to like that format.
$ docker load -i bazel-bin/helloworld_image-layer.tar
open /var/lib/docker/tmp/docker-import-330829602/app/json: no such file or directory
Help? Thanks!
You are building for your host platform by default so you need to build for the container platform if you want to do that.
Since you are using a go binary, you can do cross compilation by specifying --cpu=k8 on the command line. Ideally we would be able to just say that the docker image needs a linux binary (so no need to specify the --cpu command-line flag) but this is still a work in progress in Bazel.

Running C/C++ binary executable as a docker container

I am new to container world and exploring options to run my application on a container.Here are the things that I am seeing:
When I include compiling and building the C/C++ binary as part of docker image itself, it works fine with out any problems. Container starts and everything works fine.
If I try to run an already compiled and existing binary using CMD ["./helloworld"] in a container It throws me this error
standard_init_linux.go:185: exec user process caused “exec format error”.
Any ideas of how to get out of this problem? This seems like a basic problem that would have been solved already
Here is my dockerfile:
FROM ubuntu
COPY . /Users/test//Documents/CPP-Projects/HelloWorld-Static
WORKDIR /Users/test/Documents/CPP-Projects/HelloWorld-Static
CMD ["./build/exe/hellostatic/hellostatic"]
Hers is my exe:
gobjdump -a build/exe/hellostatic/hellostatic
build/exe/hellostatic/hellostatic: file format mach-o-x86-64
build/exe/hellostatic/hellostatic
Here is the error:
docker run test
standard_init_linux.go:185: exec user process caused “exec format error”
The problem is that you are trying to run an incompatible binary format in your container...
You are running an Ubuntu-based container (FROM ubuntu) line, but you are trying to run a Mach-O binary. By default, Linux will not run mach-o binaries.
Build your binary for the target platform (Ubuntu/Linux) and it will work well. It appears that you are running Mac OS X, so you could install an Ubuntu VM to compile your binary and transfer it to be used by the container.
When you build it inside the container, it works because it will be built to the right platform.

Resources