-
-
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
doneMaybe 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.