I need to extract the filesystem of a debian image onto the host, modify it, then repackage it back into a docker image. I'm using the following commands:
docker export container_name > archive.tar
tar -xf archive.tar -C debian/
modifying the file system here
tar -cpjf archive-modified.tar debian/
docker import archive-modified.tar debian-modified
docker run -it debian-modified /bin/bash
After I try to run the new docker image I get the following error:
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/bin/bash": stat /bin/bash: no such file or directory: unknown.
ERRO[0000] error waiting for container: context canceled
I've tried the above steps without modifying the file system at all and I get the same behavior. I've also tried importing the output of docker export directly, and this works fine. This probably means I'm creating the new tar archive incorrectly. Can anyone tell me what I'm doing wrong?
Take a look at the archive generated by docker export:
# tar tf archive.tar | sort | head
bin/
bin/bash
bin/cat
bin/chgrp
bin/chmod
bin/chown
bin/cp
bin/dash
bin/date
bin/dd
And then at the archive you generate with your tar -cpjf ... command:
# tar tf archive-modified.tar | sort | head
debian/
debian/bin/
debian/bin/bash
debian/bin/cat
debian/bin/chgrp
debian/bin/chmod
debian/bin/chown
debian/bin/cp
debian/bin/dash
debian/bin/date
You've moved everything into a debian/ top-level directory, so there is no /bin/bash in the image (it would be /debian/bin/bash, and probably wouldn't work anyway because your shared libraries aren't in the expected location, either.
You probably want to create the updated archive like this:
# tar -cpjf archive-modified.tar -C debian/ .
Related
I'm building a docker image as follows:
TEMP_FILE="/home/username/any/directory/temp"
touch $TEMP_FILE
<secrets> > $TEMP_FILE
export DOCKER_BUILDKIT=1
pushd $PROJECT_ROOT
docker build -t $DOCKER_IMAGE_NAME \
--secret id=netrc,src=$TEMP_FILE \
--build-arg=<...> \
-f Dockerfile .
rm $TEMP_FILE
Currently this works.
I'd now like to use $(mktemp) to create the TEMP_FILE in the /tmp directory. However, when I point TEMP_FILE outside of /home, I get the following error:
could not parse secrets: [id=netrc,src=/tmp/temp-file-name]: failed to stat /tmp/temp-file-name: stat /tmp/temp-file-name: no such file or directory
The script itself has no issue, I can easily find and view the temporary file for example with cat $TEMP_FILE.
How do I give docker build access to /tmp?
I'm trying to create a docker image using this command (removed the address as it's a company address):
docker build -f Dockerfile.web --build-arg _env=MTP-uat1 . -t Company/address:NlLogDownloadAl
But I keep getting this error:
failed to solve with frontend dockerfile.v0: failed to read dockerfile: open /var/lib/docker/tmp/buildkit-mount745508724/Dockerfile.web: no such file or directory
Now I've gone through like 30 similar questions and followed what they say would fix it but it does no difference.
I have done the following:
Changed the docker engine script buildkit from true to false.
Made sure the directory I'm referring to has the Dockerfile.web file.
Removed some things mentioned from the .dockerignore file.
I still get the same error all the time. Why?
The last part of the command has to be context (the directory where Docker should look for files / "the dot"):
Usage: docker build [OPTIONS] PATH | URL | -
Try this one:
docker build \
-f Dockerfile.web \
--build-arg _env=MTP-uat1 \
-t Company/address:NlLogDownloadAl \
.
You are getting no such file or directory because you haven't specified the context properly, thus it probably cut off the last argument of the command Company/address:NlLogDownloadAl (or its part), treated it as a folder which probably doesn't even exist and then it tried to look up for Dockerfile.web which wouldn't exist too either due to invalid folder or just because of the wrong folder specified.
I am doing this tutorial to load batch data using Apache Hadoop and I try to run this command to build a Docker image named "druid-hadoop-demo" with version tag "2.8.5" :
docker build -t druid-hadoop-demo:2.8.5 .
but it gives me this error
Step 14/53 : RUN curl -s https://archive.apache.org/dist/hadoop/core/hadoop-2.8.3/hadoop-2.8.3.tar.gz | tar -xz -C /usr/local/
---> Running in 7baa699ccc29
gzip: stdin: unexpected end of file
tar: Child returned status 1
tar: Error is not recoverable: exiting now
The command '/bin/sh -c curl -s https://archive.apache.org/dist/hadoop/core/hadoop-2.8.3/hadoop-2.8.3.tar.gz | tar -xz -C /usr/local/' returned a non-zero code: 2
Any help is appreciated.
That's a network error, indicating the file you downloaded was either corrupted in transit (it downloaded correctly for me, so unlikely to be the source), or the connection was dropped before finishing the curl command. Check for network proxies, intermittent network failures, or anything else that could interrupt the connection. You can also try to manually run curl from within a container to see if it's successful, e.g.
curl -o hadoop.tgz https://archive.apache.org/dist/hadoop/core/hadoop-2.8.3/hadoop-2.8.3.tar.gz
tar -tvzf hadoop.tgz
i am doing a build inside a docker container of Alpine Linux on Docker-On-Mac. inside the tarball there is a symlink to a local file (README -> README.md) that is failing the untaring:
tar: tarname.tar.gz/README: Cannot utime: No such file or directory
two interesting facts:
When running the same on Linux (Docker-on-Ubuntu running Alpine) it works flawlessly.
when running twice it succeeds, because README.md is already in the partially-created dir.
unfortunately on (2) above, it is untarring as park of a build program (Alpine's abuild) so i cannot just run the tar command twice.
any thoughts?
tar tries to get the 'file modified time', which fails for some files. As I don't know the contents of the archive, I cannot say why this happens.
But you can circumvent this problem by using the -m a.k.a. --touch flag, which let's tar ignore/not query the modification time:
tar -m -xzvf tarname.tar.gz
In a build process I need to call zipalign which is on a certain path in the docker container that I'm using:
$ docker run nathansamson/flutter-builder-docker:v0.7.3 find . -iname zipalign
./opt/android-sdk-linux/build-tools/28.0.1/zipalign
This path can change, if the docker container is updated and there is a new android sdk. For example this could be the path in the future:
$ docker run nathansamson/flutter-builder-docker:v0.9.9 find . -iname zipalign
./opt/android-sdk-linux/build-tools/42.0.0/zipalign
So instead of hardcoding the call to
docker run nathansamson/flutter-builder-docker:v0.7.3 \
/opt/android-sdk-linux/build-tools/28.0.1/zipalign -h
I would like a generic solution that finds the path to zipalign automatically. I have tried it with a subshell
$ docker run nathansamson/flutter-builder-docker:v0.7.3 $(find . -iname zipalign) -h
docker: Error response from daemon: OCI runtime create failed:
container_linux.go:348: starting container process caused "exec: \"-h\":
executable file not found in $PATH": unknown.
ERRO[0001] error waiting for container: context canceled
and with a wildcard for the folder:
$ docker run nathansamson/flutter-builder-docker:v0.7.3 /opt/android-sdk-linux/build-tools/*/zipalign -h
docker: Error response from daemon: OCI runtime create failed:
container_linux.go:348: starting container process caused "exec:
\"/opt/android-sdk-linux/build-tools/*/zipalign\": stat /opt/android-
sdk-linux/build-tools/*/zipalign: no such file or directory": unknown.
ERRO[0001] error waiting for container: context canceled
So subshells and wildcard don't work in Docker. Any ideas how I can find the path to zipalign whenever I'm calling it?
In your Dockerfile you control the entire environment. It's often easiest to cause things to appear in their "natural" places, like /usr/bin. You also have the advantage that, within a single Docker image, there will only be one version of the tools installed.
I might do something like this:
RUN for f in $PWD/opt/android-sdk-linux/build-tools/*/*; do \
ln -s $f /usr/local/bin; \
done
CMD ["zipalign", "-h"]
Another approach that might work is to use a build argument or an environment variable to hold the version number. If you do that then you can set up a known path name.
ARG version
RUN curl -LO http://.../android-sdk-linux-${version}.tar.gz \
&& tar xzf android-sdk-linux-${version}.tar.gz \
&& rm -f android-sdk-linux-${version}.tar.gz \
&& cd opt/android-sdk-linux-build-tools \
&& ln -s ${version} current
CMD ["./opt/android-sdk-linux/build-tools/current/zipalign"]
find can execute something by using the -exec option.
find . -name zipalign -exec bash -c '"$0"' {} \;
In your example:
docker run nathansamson/flutter-builder-docker:v0.7.3 find . -name zipalign -exec bash -c '"$0"' {} \;
If there is nothing that can give you any hints, and you need to just find it, then find will probably do it. Something like:
find /opt -name zipalign -type f
If you can give it more specific starting point, instead of just /opt, then it will run faster.
If you want to execute it (and pass in "-h") in one line, you could do:
$(find /opt -name zipalign -type f) -h