Make 2 volumes in docker gcc and java - gcc

I have a docker volume set up in a gcc container. I need to compile the code and give it some stdin through a text file. I'm able to do that using the following command.
docker run \
-v /home/usr/workspace/proj/WebContent/files:/mycode \
gcc:4.9 \
sh -c 'cd mycode; gcc -o myapp ./mycode.c; ./myapp < ./test.txt'
now my question is, I need to make a separate folder for each of my users with their username, but the text.txt stays in the same folder as above. How do I give them their own paths. because right now i get an error that test.txt is not found, and of course it wouldn't. I tried making a separate volume for the test.txt but I guess making two volumes in one container isn't possible or I'm doing it wrong.
What I've tried (please don't judge, i'm just learning :P)
docker run \
-v /home/usr/workspace/proj/WebContent/file/username:/mycode \
-v /home/usr/workspace/proj/WebContent/file/:/tst \
gcc:4.9 \
sh -c 'cd mycode; gcc -o myapp ./mycode.c; cd tst; ./myapp < ./test.txt'

Have a close look at this command:
sh -c 'cd mycode; gcc -o myapp ./mycode.c; cd tst; ./myapp < ./test.txt'
Because you first cd mycode and then cd tst inside the same shell, you're trying to cd mycode/tst, whereas your mount is at /tst.
Similarly, myapp is in /mycode, not in tst, so you can't run ./myapp inside the tst directory and expect it to work.
Instead:
sh -xc 'cd /mycode && gcc -o myapp ./mycode.c && cd /tst && /mycode/myapp < ./test.txt'

Related

Impossible to start a script into my docker container

I am trying to create my own image based on Centos.
I don't understand why when I use CMD command in my docker file to execute a script at startup, it's impossible to start my image (Exited (0) immediatly).
If build without the CMD command and then I connect to the container and I execute "sh /opt/jbossEAP/Mock/scripts/mock_start.sh". I have no issue
I have tryied to use entrypoint command but same result :(
FROM centos:7
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
RUN yum update -y
RUN mkdir -p /opt/jbossEAP/Mock/scripts/
ADD ./scripts /opt/jbossEAP/Mock/scripts/
RUN chmod +x /opt/jbossEAP/Mock/scripts/mock_start.sh
### START SCRIPT ###
CMD sh /opt/jbossEAP/Mock/scripts/mock_start.sh
mock_start.sh
#!/bin/sh
############################################
echo "hello"
I suspect your CMD or ENTRYPOINT does work, but that the container simply finishes after outputting hello
You can check your docker's output even after it has been stopped with:
docker logs <container-id>
Read https://stackoverflow.com/a/28214133/4486184 for more information on how it works and how to avoid that.
My guesses could be wrong, so please always add to your question:
How you start your docker image
docker ps -a's output
the relevant part of docker logs <container-id>'s output
You're right!!!
I just add and now it's ok.
CMD sh /opt/jbossEAP/Mock/scripts/mock_start.sh && tail -f /dev/null
Thank you very much

Dockerfile - ARG SHA and Curl

I am newbie to Docker. I can create a docker image for Java and Maven from https://github.com/carlossg/docker-maven/blob/master/jdk-13/Dockerfile . I can understand most of the commands there inside dockerfile, there are some that I could not find sufficient info on net. Can someone please help me ?
(1) What does below ARG SHA do. If I understand it right, SHA is immutable identifier that is associated with image, so I am downloading image with that identifier, I mean specific image with changes I want and stored with that SHA, is this right?
ARG SHA=c35a1803a6e70a126e80b2b3ae33eed961f83ed74d18fcd16909b2d44d7dada3203f1ffe726c17ef8dcca2dcaa9fca676987befeadc9b9f759967a8cb77181c0
(2) I know what RUN, echo does and how the variable works. But not sure what is happening below with curl command . No idea what below lines of code does for sure.
RUN mkdir -p /usr/share/maven /usr/share/maven/ref \
&& curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
&& echo "${SHA} /tmp/apache-maven.tar.gz" | sha512sum -c - \
&& tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 \
&& rm -f /tmp/apache-maven.tar.gz \
&& ln -s /usr/share/maven/bin/mvn /usr/bin/mvn```
You have to read it like a shell script.
1.
SHA is SHA512 hash
function used in line 10 to
check if downloaded /tmp/apache-maven.tar.gz is what we expect. It
has nothing to do with Docker image ID, if you mean that. You can
reproduce the check locally on your system:
$ SHA=c35a1803a6e70a126e80b2b3ae33eed961f83ed74d18fcd16909b2d44d7dada3203f1ffe726c17ef8dcca2dcaa9fca676987befeadc9b9f759967a8cb77181c0
$ BASE_URL=https://apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binaries
$ curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz
$ echo "${SHA} /tmp/apache-maven.tar.gz" | sha512sum -c -
/tmp/apache-maven.tar.gz: OK
(Notice that $ here is a command line
prompt
used to indicate start of a new line, not a part of the
command).
curl here downloads
https://apache.osuosl.org/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
to /tmp/apache-maven.tar.gz.
2.
Again, read it like a shell script. && is used for chaining commands and \ is used to concatenate lines.
RUN mkdir -p /usr/share/maven /usr/share/maven/ref
Create /usr/share/maven and /usr/share/maven/ref directories.
curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz
Download temporary apache-maven tarball to /tmp/apache-maven.tar.gz.
echo "${SHA} /tmp/apache-maven.tar.gz" | sha512sum -c -
Check if the downloaded tarball has the correct checksum.
tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1
Extract /tmp/apache-maven.tar.gz to /usr/share/maven.
rm -f /tmp/apache-maven.tar.gz
Remove temporary tarball after extracting it.
ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
Create /usr/bin/mvn that points to /usr/share/maven/bin/mvn. This
is done because /usr/bin directory is typically in $PATH so that
mvn can be run without providing a full path to it.

How can I set Bash aliases for docker containers in Dockerfile?

I am new to Docker. I found that we can set environment variables using the ENV instruction in the Dockerfile. But how does one set Bash aliases for long commands in Dockerfile?
Basically like you always do, by adding it to the user's .bashrc file:
FROM foo
RUN echo 'alias hi="echo hello"' >> ~/.bashrc
As usual this will only work for interactive shells:
docker build -t test .
docker run -it --rm --entrypoint /bin/bash test hi
/bin/bash: hi: No such file or directory
docker run -it --rm test bash
$ hi
hello
For non-interactive shells you should create a small script and put it in your path, i.e.:
RUN echo -e '#!/bin/bash\necho hello' > /usr/bin/hi && \
chmod +x /usr/bin/hi
If your alias uses parameters (ie. hi Jim -> hello Jim), just add "$#":
RUN echo -e '#!/bin/bash\necho hello "$#"' > /usr/bin/hi && \
chmod +x /usr/bin/hi
To create an alias of an existing command, might also use ln -s:
ln -s $(which <existing_command>) /usr/bin/<my_command>
If you want to use aliases just in Dockerfile, but not inside a container then the shortest way is the ENV declaration:
ENV update='apt-get update -qq'
ENV install='apt-get install -qq'
RUN $update && $install apt-utils \
curl \
gnupg \
python3.6
And for use in a container the way like already described:
RUN printf '#!/bin/bash \n $(which apt-get) install -qq $#' > /usr/bin/install
RUN chmod +x /usr/bin/install
Most of the time I use aliases just in the building stage and do not go inside containers, so the first example is quicker, clearer and simpler for every day use.
I just added this to my app.dockerfile file:
# Set up aliases
ADD ./bashrc_alias.sh /usr/sbin/bashrc_alias.sh
ADD ./initbash_profile.sh /usr/sbin/initbash_profile
RUN chmod +x /usr/sbin/initbash_profile
RUN /bin/bash -C "/usr/sbin/initbash_profile"
And inside the initbash_profile.sh file which just appends my custom aliases and no need to source the .bashrc file:
# Add the Bash aliases
cat /usr/sbin/bashrc_alias.sh >> ~/.bashrc
It worked a treat!
Another option is to just use the "docker exec -it <container-name> command" from outside the container and just use your own .bashrc or the .bash_profile file (what ever you prefer).
E.g.,
docker exec -it docker_app_1 bash
I think the easiest way would be to mount a file into your container containing your aliases, and then specify where Bash should find it:
docker run \
-it \
--rm \
-v ~/.bash_aliases:/tmp/.bash_aliases \
[image] \
/bin/bash --init-file /tmp/.bash_aliases
Sample usage:
echo 'alias what="echo it works"' > my_aliases
docker run -it --rm -v ~/my_aliases:/tmp/my_aliases ubuntu:18.04 /bin/bash --init-file /tmp/my_aliases
alias
Output:
alias what='echo it works'
what
Output:
it works
You can use ENTRYPOINT, but it will not work for aliases, in your Dockerfile:
ADD dev/entrypoint.sh /opt/entrypoint.sh
ENTRYPOINT ["/opt/entrypoint.sh"]
Your entrypoint.sh file:
#!/bin/bash
set -e
function dev_run()
{
}
export -f dev_run
exec "$#"
Here is a Bash function to have your aliases in every container you use interactively.
ducker_it() {
docker cp ~/bin/alias.sh "$1":/tmp
docker exec -it "$1" /bin/bash -c "[[ ! -f /tmp/alias.sh.done ]] \
&& [[ -w /root/.bashrc ]] \
&& cat /tmp/alias.sh >> /root/.bashrc \
&& touch /tmp/alias.sh.done"
docker exec -it "$1" /bin/bash
}
Required step before:
grep ^alias ~/.zshrc > ~/bin/alias.sh
Used some of the previous solutions, but the aliases are not recognised still.
I'm trying to set aliases and use them both within later Dockerfile steps and in the container at runtime.
RUN echo "alias model-downloader='python3 ${MODEL_DL_PATH}/downloader.py'" >> ~/.bash_aliases && \
echo "alias model-converter='python3 ${MODEL_DL_PATH}/converter.py'" >> ~/.bash_aliases && \
source ~/.bash_aliases
# Download the model
RUN model-downloader --name $MODEL_NAME -o $MODEL_DIR --precisions $MODEL_PRECISION;
The solution for me was to use ENV variables that held folder paths and then add the exact executable. I could have use ARG too, but for more of my scenarios I needed the aliases in both the build stage and later in the runtime.
I used the ENV variables in conjunction with a Bash script that runs once dependencies have ponged and sets the Bash source, sets some more env variables, and allows for further commands to pipe through.
#ErikDannenberg's answer did the trick, but in my case, some adjustments were needed.
It didn't work with aliases cause apparently there's an issue with interactive shells.
I reached for his second solution, but it still didn't really work. I checked existing shell scripts in my project and noticed the head comment (first line = #!/usr/bin/env sh) differs a bit from #!/usr/bin/bash. After changing it accordingly it started working for my t and tc "aliases", but I had to use the addendum to his second solution for getting tf to work.
Here's the complete Dockerfile
FROM php:8.1.1-fpm-alpine AS build
RUN apk update && apk add git
RUN curl -sS https://getcomposer.org/installer | php && mv composer.phar /usr/local/bin/composer
RUN apk add --no-cache $PHPIZE_DEPS \
&& pecl install xdebug \
&& docker-php-ext-enable xdebug \
&& touch /usr/local/etc/php/conf.d/99-xdebug.ini \
&& echo "xdebug.mode=coverage" >> /usr/local/etc/php/conf.d/99-xdebug.ini \
&& echo -e '#!/usr/bin/env sh\nphp artisan test' > /usr/bin/t \
&& chmod +x /usr/bin/t \
&& echo -e '#!/usr/bin/env sh\nphp artisan test --coverage' > /usr/bin/tc \
&& chmod +x /usr/bin/tc \
&& echo -e '#!/usr/bin/env sh\nphp artisan test --filter "$#"' > /usr/bin/tf \
&& chmod +x /usr/bin/tf
WORKDIR /var/www

docker run -i -t image /bin/bash - source files first

This works:
# echo 1 and exit:
$ docker run -i -t image /bin/bash -c "echo 1"
1
# exit
# echo 1 and return shell in docker container:
$ docker run -i -t image /bin/bash -c "echo 1; /bin/bash"
1
root#4c064f2554de:/#
Question: How could I source a file into the shell? (this does not work)
$ docker run -i -t image /bin/bash -c "source <(curl -Ls git.io/apeepg) && /bin/bash"
# content from http://git.io/apeepg is sourced and shell is returned
root#4c064f2554de:/#
In my case, I use RUN source command (which will run using /bin/bash) in a Dockerfile to install nvm for node.js
Here is an example.
FROM ubuntu:14.04
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
...
...
RUN source ~/.nvm/nvm.sh && nvm install 0.11.14
I wanted something similar, and expanding a bit on your idea, came up with the following:
docker run -ti --rm ubuntu \
bash -c 'exec /bin/bash --rcfile /dev/fd/1001 \
1002<&0 \
<<<$(echo PS1=it_worked: ) \
1001<&0 \
0<&1002'
--rcfile /dev/fd/1001 will use that file descriptor's contents instead of .bashrc
1002<&0 saves stdin
<<<$(echo PS1=it_worked: ) puts PS1=it_worked: on stdin
1001<&0 moves this stdin to fd 1001, which we use as rcfile
0<&1002 restores the stdin that we saved initially
You can use .bashrc in interactive containers:
RUN curl -O git.io/apeepg.sh && \
echo 'source apeepg.sh' >> ~/.bashrc
Then just run as usual with docker run -it --rm some/image bash.
Note that this will only work with interactive containers.
I don't think you can do this, at least not right now. What you could do is modify your image, and add the file you want to source, like so:
FROM image
ADD my-file /my-file
RUN ["source", "/my-file", "&&", "/bin/bash"]

How to generate a Dockerfile from an image?

Is it possible to generate a Dockerfile from an image? I want to know for two reasons:
I can download images from the repository but would like to see the recipe that generated them.
I like the idea of saving snapshots, but once I am done it would be nice to have a structured format to review what was done.
How to generate or reverse a Dockerfile from an image?
You can. Mostly.
Notes: It does not generate a Dockerfile that you can use directly with docker build; the output is just for your reference.
alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm alpine/dfimage"
dfimage -sV=1.36 nginx:latest
It will pull the target docker image automatically and export Dockerfile. Parameter -sV=1.36 is not always required.
Reference: https://hub.docker.com/r/alpine/dfimage
Now hub.docker.com shows the image layers with detail commands directly, if you choose a particular tag.
Bonus
If you want to know which files are changed in each layer
alias dive="docker run -ti --rm -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive"
dive nginx:latest
On the left, you see each layer's command, on the right (jump with tab), the yellow line is the folder that some files are changed in that layer
(Use SPACE to collapse dir)
Old answer
below is the old answer, it doesn't work any more.
$ docker pull centurylink/dockerfile-from-image
$ alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm centurylink/dockerfile-from-image"
$ dfimage --help
Usage: dockerfile-from-image.rb [options] <image_id>
-f, --full-tree Generate Dockerfile for all parent layers
-h, --help Show this message
To understand how a docker image was built, use the
docker history --no-trunc command.
You can build a docker file from an image, but it will not contain everything you would want to fully understand how the image was generated. Reasonably what you can extract is the MAINTAINER, ENV, EXPOSE, VOLUME, WORKDIR, ENTRYPOINT, CMD, and ONBUILD parts of the dockerfile.
The following script should work for you:
#!/bin/bash
docker history --no-trunc "$1" | \
sed -n -e 's,.*/bin/sh -c #(nop) \(MAINTAINER .*[^ ]\) *0 B,\1,p' | \
head -1
docker inspect --format='{{range $e := .Config.Env}}
ENV {{$e}}
{{end}}{{range $e,$v := .Config.ExposedPorts}}
EXPOSE {{$e}}
{{end}}{{range $e,$v := .Config.Volumes}}
VOLUME {{$e}}
{{end}}{{with .Config.User}}USER {{.}}{{end}}
{{with .Config.WorkingDir}}WORKDIR {{.}}{{end}}
{{with .Config.Entrypoint}}ENTRYPOINT {{json .}}{{end}}
{{with .Config.Cmd}}CMD {{json .}}{{end}}
{{with .Config.OnBuild}}ONBUILD {{json .}}{{end}}' "$1"
I use this as part of a script to rebuild running containers as images:
https://github.com/docbill/docker-scripts/blob/master/docker-rebase
The Dockerfile is mainly useful if you want to be able to repackage an image.
The thing to keep in mind, is a docker image can actually just be the tar backup of a real or virtual machine. I have made several docker images this way. Even the build history shows me importing a huge tar file as the first step in creating the image...
I somehow absolutely missed the actual command in the accepted answer, so here it is again, bit more visible in its own paragraph, to see how many people are like me
$ docker history --no-trunc <IMAGE_ID>
A bash solution :
docker history --no-trunc $argv | tac | tr -s ' ' | cut -d " " -f 5- | sed 's,^/bin/sh -c #(nop) ,,g' | sed 's,^/bin/sh -c,RUN,g' | sed 's, && ,\n & ,g' | sed 's,\s*[0-9]*[\.]*[0-9]*\s*[kMG]*B\s*$,,g' | head -n -1
Step by step explanations:
tac : reverse the file
tr -s ' ' trim multiple whitespaces into 1
cut -d " " -f 5- remove the first fields (until X months/years ago)
sed 's,^/bin/sh -c #(nop) ,,g' remove /bin/sh calls for ENV,LABEL...
sed 's,^/bin/sh -c,RUN,g' remove /bin/sh calls for RUN
sed 's, && ,\n & ,g' pretty print multi command lines following Docker best practices
sed 's,\s*[0-9]*[\.]*[0-9]*\s*[kMG]*B\s*$,,g' remove layer size information
head -n -1 remove last line ("SIZE COMMENT" in this case)
Example:
~  dih ubuntu:18.04
ADD file:28c0771e44ff530dba3f237024acc38e8ec9293d60f0e44c8c78536c12f13a0b in /
RUN set -xe
&& echo '#!/bin/sh' > /usr/sbin/policy-rc.d
&& echo 'exit 101' >> /usr/sbin/policy-rc.d
&& chmod +x /usr/sbin/policy-rc.d
&& dpkg-divert --local --rename --add /sbin/initctl
&& cp -a /usr/sbin/policy-rc.d /sbin/initctl
&& sed -i 's/^exit.*/exit 0/' /sbin/initctl
&& echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup
&& echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean
&& echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean
&& echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean
&& echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages
&& echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes
&& echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests
RUN rm -rf /var/lib/apt/lists/*
RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list
RUN mkdir -p /run/systemd
&& echo 'docker' > /run/systemd/container
CMD ["/bin/bash"]
Update Dec 2018 to BMW's answer
chenzj/dfimage - as described on hub.docker.com regenerates Dockerfile from other images. So you can use it as follows:
docker pull chenzj/dfimage
alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage"
dfimage IMAGE_ID > Dockerfile
This is derived from #fallino's answer, with some adjustments and simplifications by using the output format option for docker history. Since macOS and Gnu/Linux have different command-line utilities, a different version is necessary for Mac. If you only need one or the other, you can just use those lines.
#!/bin/bash
case "$OSTYPE" in
linux*)
docker history --no-trunc --format "{{.CreatedBy}}" $1 | # extract information from layers
tac | # reverse the file
sed 's,^\(|3.*\)\?/bin/\(ba\)\?sh -c,RUN,' | # change /bin/(ba)?sh calls to RUN
sed 's,^RUN #(nop) *,,' | # remove RUN #(nop) calls for ENV,LABEL...
sed 's, *&& *, \\\n \&\& ,g' # pretty print multi command lines following Docker best practices
;;
darwin*)
docker history --no-trunc --format "{{.CreatedBy}}" $1 | # extract information from layers
tail -r | # reverse the file
sed -E 's,^(\|3.*)?/bin/(ba)?sh -c,RUN,' | # change /bin/(ba)?sh calls to RUN
sed 's,^RUN #(nop) *,,' | # remove RUN #(nop) calls for ENV,LABEL...
sed $'s, *&& *, \\\ \\\n \&\& ,g' # pretty print multi command lines following Docker best practices
;;
*)
echo "unknown OSTYPE: $OSTYPE"
;;
esac
It is not possible at this point (unless the author of the image explicitly included the Dockerfile).
However, it is definitely something useful! There are two things that will help to obtain this feature.
Trusted builds (detailed in this docker-dev discussion
More detailed metadata in the successive images produced by the build process. In the long run, the metadata should indicate which build command produced the image, which means that it will be possible to reconstruct the Dockerfile from a sequence of images.
If you are interested in an image that is in the Docker hub registry and wanted to take a look at Dockerfile?.
Example:
If you want to see the Dockerfile of image "jupyter/datascience-notebook" type the word "Dockerfile" in the address bar of your browser as shown below.
https://hub.docker.com/r/jupyter/datascience-notebook/
https://hub.docker.com/r/jupyter/datascience-notebook/Dockerfile
Note:
Not all the images have Dockerfile, for example, https://hub.docker.com/r/redislabs/redisinsight/Dockerfile
Sometimes this way is much faster than searching for Dockerfile in Github.
docker pull chenzj/dfimage
alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm chenzj/dfimage"
dfimage image_id
Below is the output of the dfimage command:
$ dfimage 0f1947a021ce
FROM node:8
WORKDIR /usr/src/app
COPY file:e76d2e84545dedbe901b7b7b0c8d2c9733baa07cc821054efec48f623e29218c in ./
RUN /bin/sh -c npm install
COPY dir:a89a4894689a38cbf3895fdc0870878272bb9e09268149a87a6974a274b2184a in .
EXPOSE 8080
CMD ["npm" "start"]
it is possible in just two step. First pull the image then run docker history command. also, shown in SS.
docker pull kalilinux/kali-rolling
docker history --format "{{.CreatedBy}}" kalilinux/kali-rolling --no-trunc
What is image2df
image2df is tool for Generate Dockerfile by an image.
This tool is very useful when you only have docker image and need to generate a Dockerfile whit it.
How does it work
Reverse parsing by history information of an image.
How to use this image
# Command alias
echo "alias image2df='docker run -v /var/run/docker.sock:/var/run/docker.sock --rm cucker/image2df'" >> ~/.bashrc
. ~/.bashrc
# Excute command
image2df <IMAGE>
See help
docker run --rm cucker/image2df --help
For example
$ echo "alias image2df='docker run -v /var/run/docker.sock:/var/run/docker.sock --rm cucker/image2df'" >> ~/.bashrc
$ . ~/.bashrc
$ docker pull mysql
$ image2df mysql
========== Dockerfile ==========
FROM mysql:latest
RUN groupadd -r mysql && useradd -r -g mysql mysql
RUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*
ENV GOSU_VERSION=1.12
RUN set -eux; \
savedAptMark="$(apt-mark showmanual)"; \
apt-get update; \
apt-get install -y --no-install-recommends ca-certificates wget; \
rm -rf /var/lib/apt/lists/*; \
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
export GNUPGHOME="$(mktemp -d)"; \
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
gpgconf --kill all; \
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
apt-mark auto '.*' > /dev/null; \
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
chmod +x /usr/local/bin/gosu; \
gosu --version; \
gosu nobody true
RUN mkdir /docker-entrypoint-initdb.d
RUN apt-get update && apt-get install -y --no-install-recommends \
pwgen \
openssl \
perl \
xz-utils \
&& rm -rf /var/lib/apt/lists/*
RUN set -ex; \
key='A4A9406876FCBD3C456770C88C718D3B5072E1F5'; \
export GNUPGHOME="$(mktemp -d)"; \
gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
gpg --batch --export "$key" > /etc/apt/trusted.gpg.d/mysql.gpg; \
gpgconf --kill all; \
rm -rf "$GNUPGHOME"; \
apt-key list > /dev/null
ENV MYSQL_MAJOR=8.0
ENV MYSQL_VERSION=8.0.24-1debian10
RUN echo 'deb http://repo.mysql.com/apt/debian/ buster mysql-8.0' > /etc/apt/sources.list.d/mysql.list
RUN { \
echo mysql-community-server mysql-community-server/data-dir select ''; \
echo mysql-community-server mysql-community-server/root-pass password ''; \
echo mysql-community-server mysql-community-server/re-root-pass password ''; \
echo mysql-community-server mysql-community-server/remove-test-db select false; \
} | debconf-set-selections \
&& apt-get update \
&& apt-get install -y \
mysql-community-client="${MYSQL_VERSION}" \
mysql-community-server-core="${MYSQL_VERSION}" \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \
&& chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \
&& chmod 1777 /var/run/mysqld /var/lib/mysql
VOLUME [/var/lib/mysql]
COPY dir:2e040acc386ebd23b8571951a51e6cb93647df091bc26159b8c757ef82b3fcda in /etc/mysql/
COPY file:345a22fe55d3e6783a17075612415413487e7dba27fbf1000a67c7870364b739 in /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 3306 33060
CMD ["mysqld"]
reference

Resources