2
1
I'm running minikube as a local test environment and using docker multi-stage builds to build my containers. Minikube runs a version of docker that doesn't support multi-stage builds. Minikube suggests you use the built-in docker environment to build containers as follows:
#!/usr/bin/env bash
eval $(minikube docker-env)
docker build
Because I need to use the local docker instance to build, I've found docker save/load. This means I need to do the following:
#!/usr/bin/env bash
docker build
docker save $IMG > /tmp/container.tar
eval $(minikube docker-env) # set up docker env vars
docker load -i /tmp/container.tar
eval $(minikube docker-env -u) # clean up env
However, docker load can read a file from stdin. If I could pipe the output from my docker host to a remote docker host I could do this without modifying/polluting my users' environments. So I was wondering whether there was some way to load the minikube env within a pipe environment. I've found the following works, but of course both docker hosts are the same:
docker save $IMG | env -i docker load
But I'd like something like the following (psuedo-code, I guess)
docker save $IMG | env -i side_effects(eval $(minikube docker-env)) docker load
I've tried simply inserting the command (didn't really expect this to work):
docker save $IMG | env -i eval $(minikube docker-env) docker load
And making a function to load the values:
function load_env { eval $(minikube docker-env) }
docker save $IMG | env -i load_env() docker load
Neither worked. I'm not that sure, but I presume eval was receiving the piped data. And eval doesn't use stdin. The latter caused a syntax error.
Finally, I could do something like this:
#/usr/bin/env bash
hostenv=$(minikube docker-env | grep DOCKER_HOST | cut -f2 -d'='
certpath=$(minikube docker-env | grep DOCKER_CERT_PATH | cut -f2 -d'='
docker save $IMG | docker -H=$hostenv --tls=true --tlsverify=true \
--tlscacert=$certpath/ca.pem --tlscert=$certpath/cert.pem \
--tlskey=$certpath/key.pem
But as this has a lot of interacting interfaces, it will likely begin to fail as soon as one of them changes.
Edit: I've found an improvement on the above, I'd argue it's probably less fragile, but still more so than ideal:
dockerenv=$(minikube docker-env | sed 's/export//g' | sed 's/^#.*$//g' | sed 's/"//g')
docker save $IMG | env -i $dockerenv docker load
So really what I'm asking is: is there a robust way to avoid any temporary files or environment pollution on my users' machines? (If anyone has a better title for this question please change it- it's only one way to solve my problem).
Re-reading my question, I can't believe how off-target my title was. What state of mind was I in?! Anyway, if anyone wants to test if this will work minimally, the following will help:
echo "blah" | (eval $(touch side_effect) && tr -d '\n')
– mkingston – 2017-10-26T16:11:43.417