-
-
Save Gems/a40d7eb45f46c82f990aa7e8845d7e7a to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash | |
TMP_FILE=/tmp/docker-compose.$$.yaml | |
finish() { | |
rm ${TMP_FILE} ${TMP_FILE}.tmp 2>/dev/null | |
} | |
trap finish EXIT | |
compose-config() { | |
mv -f ${TMP_FILE} ${TMP_FILE}.tmp | |
docker-compose -f ${1} -f ${TMP_FILE}.tmp config >${TMP_FILE} | |
rm -f ${TMP_FILE}.tmp 2>/dev/null | |
} | |
args=() | |
files=() | |
while [ -n "$1" ]; do | |
case "$1" in | |
-f) | |
shift; files+=($1) | |
;; | |
*) | |
args+=($1) | |
;; | |
esac | |
shift | |
done | |
echo 'version: "3"' >${TMP_FILE} | |
for f in ${files[@]}; do | |
compose-config ${f} | |
done | |
docker-compose -f ${TMP_FILE} ${args[@]} | |
exit $? |
Great script, provides a great workaround for docker/compose#3874
For me, it did not accepting --scale my-service=2
, so I modified it:
#!/usr/bin/env bash
TMP_FILE=/tmp/docker-compose.$$.yaml
finish() {
rm ${TMP_FILE} ${TMP_FILE}.tmp 2>/dev/null
}
trap finish EXIT
compose-config() {
mv -f ${TMP_FILE} ${TMP_FILE}.tmp
docker-compose -f ${1} -f ${TMP_FILE}.tmp config > ${TMP_FILE}
rm -f ${TMP_FILE}.tmp 2>/dev/null
}
args=''
files=()
while :; do
getopts ":" opt
case $OPTARG in
f) files+=(${!OPTIND})
;;
esac
((OPTIND++))
[ $OPTIND -gt $# ] && break
done
echo 'version: "3"' > ${TMP_FILE}
args=$@
for f in ${files[@]}; do
compose-config ${f}
args=`echo $args | sed -E "s#-f +${f}##"`
done
docker-compose -f ${TMP_FILE} $args
exit $?
Thanks for the heads-up @bimlas
I fixed the arguments parsing section and it works on my OS X. AFAIR, I tested this script on WSL, so it might have been some quirks that made it work there.
Would appreciate it if you check the new version in your environment βπ»
@Gems: It's accepting --scale my-service=2
and exec -it
but it removes -T
(uppercase flags) from exec -T
Thanks for checking and reporting @bimlas
It appears that I got to learn getopts
better π
though anyway the arguments parsing problem here isn't quite for getopts
, so I replaced it with a simpler solution. I checked with the failing arguments line using exec -T
and it seems to be working.
Cheers!
@Gems, seems to work fine, thanks!
Thanks for your collaboration, @bimlas ππ»
@Gems Thanks for sharing your script. Since I personally prefer using verbose flags when using scripts, I added support for --file
:
while [ -n "$1" ]; do
case "$1" in
-f | --file)
shift; files+=($1)
;;
*)
args+=($1)
;;
esac
shift
done
Maybe others find that useful, as well. π
PS: Also, it seems that one should now use docker compose
instead docker-compose
.
UPDATE
Here is my final version which also
- correctly prefixes
version: "3"
- uses a more secure tempfile
- avoids missing project name
- correctly override previous config items
#!/usr/bin/env bash
PROJECT_NAME=$(basename `pwd`)
# Create temp file securely
TMP_FILE=`mktemp /tmp/docker-compose.XXXXXX` || exit 1
mv ${TMP_FILE} ${TMP_FILE}.yml
TMP_FILE=${TMP_FILE}.yml
# Clean up
finish() {
rm ${TMP_FILE} ${TMP_FILE}.tmp 2>/dev/null
}
trap finish EXIT
# Prepend given file to config in order to keep the file's relative context
compose-config() {
mv -f ${TMP_FILE} ${TMP_FILE}.tmp
# Add the file twice: 1st for the context, 2nd for config overrides
docker compose -p ${PROJECT_NAME} -f ${1} -f ${TMP_FILE}.tmp -f ${1} config > ${TMP_FILE}
rm -f ${TMP_FILE}.tmp 2>/dev/null
}
# Separate -f/--file arguments from the rest
args=()
files=()
while [ -n "$1" ]; do
case "$1" in
-f | --file)
shift; files+=($1)
;;
*)
args+=($1)
;;
esac
shift
done
# Generate config
for f in ${files[@]}; do
compose-config ${f}
done
# Prepend version
mv -f ${TMP_FILE} ${TMP_FILE}.tmp
echo 'version: "3"' > ${TMP_FILE}
cat ${TMP_FILE}.tmp >> ${TMP_FILE}
rm -f ${TMP_FILE}.tmp 2>/dev/null
echo -e "
FINAL CONFIG
------------
"
docker compose -f ${TMP_FILE} config
docker compose -f ${TMP_FILE} ${args[@]}
exit $?
Thank you for sharing your version @jneuendorf-i4h , I bet many people find it even more useful than the original one ππ»
I adapted this idea and I am now using a similar script to start all of my personal infrastructure.