Skip to content

Instantly share code, notes, and snippets.

@efrecon
Last active Dec 1, 2021
Embed
What would you like to do?
`docker inspect` template to regenerate the `docker run` command that created a container
docker run \
--name {{printf "%q" .Name}} \
{{- with .HostConfig}}
{{- if .Privileged}}
--privileged \
{{- end}}
{{- if .AutoRemove}}
--rm \
{{- end}}
{{- if .Runtime}}
--runtime {{printf "%q" .Runtime}} \
{{- end}}
{{- range $b := .Binds}}
--volume {{printf "%q" $b}} \
{{- end}}
{{- range $v := .VolumesFrom}}
--volumes-from {{printf "%q" $v}} \
{{- end}}
{{- range $l := .Links}}
--link {{printf "%q" $l}} \
{{- end}}
{{- if .PublishAllPorts}}
--publish-all \
{{- end}}
{{- if .UTSMode}}
--uts {{printf "%q" .UTSMode}} \
{{- end}}
{{- with .LogConfig}}
--log-driver {{printf "%q" .Type}} \
{{- range $o, $v := .Config}}
--log-opt {{$o}}={{printf "%q" $v}} \
{{- end}}
{{- end}}
{{- with .RestartPolicy}}
--restart "{{.Name -}}
{{- if eq .Name "on-failure"}}:{{.MaximumRetryCount}}
{{- end}}" \
{{- end}}
{{- range $e := .ExtraHosts}}
--add-host {{printf "%q" $e}} \
{{- end}}
{{- range $v := .CapAdd}}
--cap-add {{printf "%q" $v}} \
{{- end}}
{{- range $v := .CapDrop}}
--cap-drop {{printf "%q" $v}} \
{{- end}}
{{- range $d := .Devices}}
--device {{printf "%q" (index $d).PathOnHost}}:{{printf "%q" (index $d).PathInContainer}}:{{(index $d).CgroupPermissions}} \
{{- end}}
{{- end}}
{{- with .NetworkSettings -}}
{{- range $p, $conf := .Ports}}
{{- with $conf}}
--publish "
{{- if $h := (index $conf 0).HostIp}}{{$h}}:
{{- end}}
{{- (index $conf 0).HostPort}}:{{$p}}" \
{{- end}}
{{- end}}
{{- range $n, $conf := .Networks}}
{{- with $conf}}
--network {{printf "%q" $n}} \
{{- range $a := $conf.Aliases}}
--network-alias {{printf "%q" $a}} \
{{- end}}
{{- end}}
{{- end}}
{{- end}}
{{- with .Config}}
{{- if .Hostname}}
--hostname {{printf "%q" .Hostname}} \
{{- end}}
{{- if .Domainname}}
--domainname {{printf "%q" .Domainname}} \
{{- end}}
{{- range $p, $conf := .ExposedPorts}}
--expose {{printf "%q" $p}} \
{{- end}}
{{- range $e := .Env}}
--env {{printf "%q" $e}} \
{{- end}}
{{- range $l, $v := .Labels}}
--label {{printf "%q" $l}}={{printf "%q" $v}} \
{{- end}}
{{- if not (or .AttachStdin (or .AttachStdout .AttachStderr))}}
--detach \
{{- end}}
{{- if .AttachStdin}}
--attach stdin \
{{- end}}
{{- if .AttachStdout}}
--attach stdout \
{{- end}}
{{- if .AttachStderr}}
--attach stderr \
{{- end}}
{{- if .Tty}}
--tty \
{{- end}}
{{- if .OpenStdin}}
--interactive \
{{- end}}
{{- if .Entrypoint}}
{{- /* Since the entry point cannot be overridden from the command line with an array of size over 1,
we are fine assuming the default value in such a case. */ -}}
{{- if eq (len .Entrypoint) 1 }}
--entrypoint "
{{- range $i, $v := .Entrypoint}}
{{- if $i}} {{end}}
{{- $v}}
{{- end}}" \
{{- end}}
{{- end}}
{{printf "%q" .Image}} \
{{range .Cmd}}{{printf "%q " .}}{{- end}}
{{- end}}
@efrecon

This comment has been minimized.

Copy link
Owner Author

@efrecon efrecon commented Jun 28, 2016

This does not support --links so far, nor a number of less-often used options. Any taker?

@efrecon

This comment has been minimized.

Copy link
Owner Author

@efrecon efrecon commented Jun 28, 2016

To run, save this to a file, e.g. run.tpl and do docker inspect --format "$(<run.tpl)" name_or_id_of_running_container

@efrecon

This comment has been minimized.

Copy link
Owner Author

@efrecon efrecon commented Jul 30, 2016

Now with properly working entrypoint (as long as it's a single command, restriction from the command line) and export of devices.

@soleil0-0

This comment has been minimized.

Copy link

@soleil0-0 soleil0-0 commented Aug 15, 2016

wow, this way is so cool

@epishan

This comment has been minimized.

Copy link

@epishan epishan commented Nov 1, 2016

simple and works out of the box... great hack, man!

@grownseed

This comment has been minimized.

Copy link

@grownseed grownseed commented Nov 15, 2016

@efrecon Thanks a lot for putting this together!

Using your exact command and template, I'm running into two issues, and unfortunately I don't know Go templates (or Go for that matter), so my attempts at fixing them aren't particularly fruitful.

First issue:

I end up with the output being duplicated within itself, e.g.:

docker run \
    --name=/teamcity-server \
    --env="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
    --env="JRE_HOME=/usr/lib/jvm/oracle-jdk/jre" \
    --env="TEAMCITY_DATA_PATH=/data/teamcity_server/datadir" \
    -p 0.0.0.0:8111:8111/tcp \
    --volume="/teamcity:/data/teamcity_server/datadir" \
    --volume="/teamcity/logs:/opt/teamcity/logs" \
    docker run \
    --name=/teamcity-server \
    --env="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
    --env="JRE_HOME=/usr/lib/jvm/oracle-jdk/jre" \
    --env="TEAMCITY_DATA_PATH=/data/teamcity_server/datadir" \
    -p 0.0.0.0:8111:8111/tcp \
    --volume="/teamcity:/data/teamcity_server/datadir" \
    --volume="/teamcity/logs:/opt/teamcity/logs" \
    --log-driver="json-file" \
    --restart="no" \
    --detach=true \
    jetbrains/teamcity-server \
    /run-services.sh

(I tried other containers just in case, still getting the same issue).

Second issue:

Some of my containers have no exposed port (e.g. "9090/tcp": {}), which throws:

-p reflect: call of reflect.Value.Type on zero Value

Any help would be appreciated, and my apologies in advance if I'm missing something completely obvious. Thank you!

@hervenicol

This comment has been minimized.

Copy link

@hervenicol hervenicol commented Dec 21, 2016

Hi @efrecon. I have an improved version here: https://gist.github.com/hervenicol/ee5fd66d42d6f301f6ecd5008049df07.
Feel free to merge it.

@gamesbook

This comment has been minimized.

Copy link

@gamesbook gamesbook commented Mar 6, 2017

I get an error:

docker run \
>     --name={{.Name}} \
>     {{range $e := .Config.Env}}--env="{{$e}}" \
>     {{end}}{{range $p, $conf := .NetworkSettings.Ports}}-p {{(index $conf 0).HostIp}}:{{(index $conf 0).HostPort}}:{{$p}} \
bash: syntax error near unexpected token `('
@efrecon

This comment has been minimized.

Copy link
Owner Author

@efrecon efrecon commented Feb 22, 2018

Merged current version from @hervenicol. Thanks for carrying further the flag!

@awltux

This comment has been minimized.

Copy link

@awltux awltux commented Jan 30, 2019

Nice! Appreciate your work.
Small fix (missing a separating colon)
{{if eq .Name "on-failure"}}:{{.MaximumRetryCount}}{{end}}

@yjst2012

This comment has been minimized.

Copy link

@yjst2012 yjst2012 commented Jan 30, 2019

Great, man, this is just what I'm looking for!

@efrecon

This comment has been minimized.

Copy link
Owner Author

@efrecon efrecon commented Feb 20, 2019

Thank you @awltux, fixed.

@wal5hy

This comment has been minimized.

Copy link

@wal5hy wal5hy commented Mar 23, 2019

Really useful script, thanks! What I can't figure out is how to ignore settings which are a part of the image, and only take settings which are applied in addition to the default image settings. Any ideas?

@mcgyver83

This comment has been minimized.

Copy link

@mcgyver83 mcgyver83 commented Mar 24, 2019

Great job man!
Works like a charme!

@ptrouvin

This comment has been minimized.

Copy link

@ptrouvin ptrouvin commented Jun 9, 2019

Very elegant and simple solution! Many thanks.

@efrecon

This comment has been minimized.

Copy link
Owner Author

@efrecon efrecon commented Jun 10, 2019

@wal5hy no, unfortunately no ideas. Did you figure it out?

@ictus4u

This comment has been minimized.

Copy link

@ictus4u ictus4u commented May 19, 2020

Glad to find your solution, @efrecon. I wanted to give it a twist and ended with this version I share with you. Here the properties are sorted in the main property (eg. HostConfig, NetworkSettings, Config). Also, support is added for --links and some other settings. Could you please review it?

@efrecon

This comment has been minimized.

Copy link
Owner Author

@efrecon efrecon commented May 20, 2020

@ictus4u Thank you! I took in your changes into the main gist. Maybe is this time to migrate the "code" into a real project, it has received a number of contributions and community interaction would work much better as a real project.

@ictus4u

This comment has been minimized.

Copy link

@ictus4u ictus4u commented May 25, 2020

@efrecon I refactored again the code. It now looks longer, but it's for sure more readable and easier to peer review and maintain. I hope this will encourage more people to get collaborative, and also, to understand and be safer about what is being done by this template. I took advantage of the left-trimming {{- feature for being able to format the template without affecting the output. No added features, but some typos came to light and were fixed in the way. Cheers!

@efrecon

This comment has been minimized.

Copy link
Owner Author

@efrecon efrecon commented May 31, 2020

@ictus4u: This is just... beautiful. It makes it so much more approachable. Very nice refactoring!

@kforner

This comment has been minimized.

Copy link

@kforner kforner commented Jul 22, 2020

very very cool indeed! Chapeau!

@jeanspector

This comment has been minimized.

Copy link

@jeanspector jeanspector commented Oct 27, 2020

This is beautiful indeed! Thank you!

@dgoguerra

This comment has been minimized.

Copy link

@dgoguerra dgoguerra commented Jan 5, 2021

Thank you! This is really useful! To use directly the most recent version of the template:

docker inspect \
  --format "$(curl -s https://gist.githubusercontent.com/efrecon/8ce9c75d518b6eb863f667442d7bc679/raw/run.tpl)" \
  name_or_id_of_running_container
@ikucheryavenkov

This comment has been minimized.

Copy link

@ikucheryavenkov ikucheryavenkov commented Sep 18, 2021

I do sooo love this!!!

@barl0g

This comment has been minimized.

Copy link

@barl0g barl0g commented Nov 6, 2021

If exists volume declaration I receive an error. Check this (mailu_mailstate):

# docker inspect --format "$(curl -s https://gist.githubusercontent.com/efrecon/8ce9c75d518b6eb863f667442d7bc679/raw/run.tpl)" 55a319b7e124
docker run \
  --name "/mail" \
  --runtime "runc" \
  --volume "mailu_mailstate:/var/mail-state:rw" \ # ERROR!
  --volume "/root/mailu/config:/tmp/docker-mailserver:rw" \
  --volume "mailu_maildata:/var/mail:rw" \ # ERROR!
# docker inspect 55a319b7e124 | less
            {
                "Type": "volume",
                "Name": "mailu_mailstate",
                "Source": "/var/lib/docker/volumes/mailu_mailstate/_data",
                "Destination": "/var/mail-state",
                "Driver": "local",
                "Mode": "rw",
                "RW": true,
                "Propagation": ""
            }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment