diff --git a/.gitea/workflows/dfi.bash b/.gitea/workflows/dfi.bash
index e73b40c..940de22 100755
--- a/.gitea/workflows/dfi.bash
+++ b/.gitea/workflows/dfi.bash
@@ -85,7 +85,7 @@ function client::install()
function client::finance::gen()
{
local -r _tags=("micro" "tiny" "slim" "default")
- local -r _types=("env" "build" "superscript" "env,build,superscript")
+ local -r _types=("env" "build" "compose" "superscript" "env,build,compose,superscript")
for _tag in "${_tags[@]}"; do
for _type in "${_types[@]}"; do
@@ -112,10 +112,16 @@ function client::finance::edit()
types+=("env")
types+=("shell" "superscript")
types+=("build" "dockerfile")
+ types+=("compose")
types+=("env,shell,build")
- types+=("env,superscript,dockerfile")
+ types+=("env,superscript,dockerfile,compose")
declare -r types
+ # The expected default path for default finance image
+ local _path
+ _path="${HOME:?}/docker-finance/conf.d/client/$(uname -s)-$(uname -m)/archlinux/default"
+ declare -r _path
+
for _tag in "${tags[@]}"; do
for _type in "${types[@]}"; do
local _edit="dfi archlinux/${USER}:${_tag} edit"
@@ -127,12 +133,25 @@ function client::finance::edit()
# Valid
"${ci_shell[@]}" "$_edit type=${_type} & wait ; kill -9 %1"
done
- # Build: uncomment all optional packages and plugin dependencies
+
if [[ "$_tag" == "default" ]]; then
local _file
- _file="${HOME:?}/docker-finance/conf.d/client/$(uname -s)-$(uname -m)/archlinux/default/Dockerfiles/${USER:?}@$(uname -n)"
+
+ # Build: uncomment all optional packages and plugin dependencies from custom build file
+ _file="${_path}/Dockerfiles/${USER:?}@$(uname -n)"
[ ! -f "$_file" ] && exit 1
sed -i '18,56s/#//' "$_file"
+
+ # Build: uncomment custom compose merge file
+ _file+=".yml"
+ [ ! -f "$_file" ] && exit 1
+ sed -i '8,13s/#//' "$_file"
+
+ # env: add variables used in custom compose merge file
+ _file="${_path}/env/${USER:?}@$(uname -n)"
+ [ ! -f "$_file" ] && exit 1
+ echo "DOCKER_FINANCE_CLIENT_TESTING=/tmp/testing" >>$_file
+ echo "DOCKER_FINANCE_CONTAINER_TESTING=/tmp/testing" >>$_file
fi
done
}
@@ -722,7 +741,7 @@ function container::finance::root()
function client::dev-tools::gen()
{
local -r _tags=("micro" "tiny" "slim" "default")
- local -r _types=("env" "build" "superscript" "env,build,superscript")
+ local -r _types=("env" "build" "compose" "superscript" "env,build,compose,superscript")
# TODO: 'default' should only be supported
for _tag in "${_tags[@]}"; do
@@ -747,7 +766,8 @@ function client::dev-tools::edit()
_types+=("env")
_types+=("shell" "superscript")
_types+=("build" "dockerfile")
- _types+=("env,shell,build")
+ _types+=("compose")
+ _types+=("env,shell,build,compose")
_types+=("env,superscript,dockerfile")
declare -r _types
diff --git a/client/conf.d/client/Dockerfiles/dev-tools/docker-compose.yml.dev-tools.in b/client/conf.d/client/Dockerfiles/dev-tools/docker-compose.yml.dev-tools.in
new file mode 100644
index 0000000..408901c
--- /dev/null
+++ b/client/conf.d/client/Dockerfiles/dev-tools/docker-compose.yml.dev-tools.in
@@ -0,0 +1,32 @@
+# docker-finance | modern accounting for the power-user
+#
+# Copyright (C) 2021-2024,2026 Aaron Fiore (Founder, Evergreen Crypto LLC)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# docker-finance @DOCKER_FINANCE_VERSION@
+
+## This is a custom compose file that will be *merged* with the base compose file
+## See https://docs.docker.com/compose/how-tos/multiple-compose-files/merge/ for details
+
+## An example of adding a custom volume and environment variables
+## NOTE: *MUST* also add these variables to the env file (`edit type=env`)
+#services:
+# docker-finance:
+# volumes:
+# - ${DOCKER_FINANCE_CLIENT_TESTING}:${DOCKER_FINANCE_CONTAINER_TESTING}
+# environment:
+# - DOCKER_FINANCE_CONTAINER_TESTING=${DOCKER_FINANCE_CONTAINER_TESTING}
+
+# vim: sw=2 sts=2 si ai et
diff --git a/client/conf.d/client/Dockerfiles/finance/docker-compose.yml.archlinux.in b/client/conf.d/client/Dockerfiles/finance/docker-compose.yml.archlinux.in
new file mode 100644
index 0000000..408901c
--- /dev/null
+++ b/client/conf.d/client/Dockerfiles/finance/docker-compose.yml.archlinux.in
@@ -0,0 +1,32 @@
+# docker-finance | modern accounting for the power-user
+#
+# Copyright (C) 2021-2024,2026 Aaron Fiore (Founder, Evergreen Crypto LLC)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# docker-finance @DOCKER_FINANCE_VERSION@
+
+## This is a custom compose file that will be *merged* with the base compose file
+## See https://docs.docker.com/compose/how-tos/multiple-compose-files/merge/ for details
+
+## An example of adding a custom volume and environment variables
+## NOTE: *MUST* also add these variables to the env file (`edit type=env`)
+#services:
+# docker-finance:
+# volumes:
+# - ${DOCKER_FINANCE_CLIENT_TESTING}:${DOCKER_FINANCE_CONTAINER_TESTING}
+# environment:
+# - DOCKER_FINANCE_CONTAINER_TESTING=${DOCKER_FINANCE_CONTAINER_TESTING}
+
+# vim: sw=2 sts=2 si ai et
diff --git a/client/conf.d/client/Dockerfiles/finance/docker-compose.yml.ubuntu.in b/client/conf.d/client/Dockerfiles/finance/docker-compose.yml.ubuntu.in
new file mode 100644
index 0000000..408901c
--- /dev/null
+++ b/client/conf.d/client/Dockerfiles/finance/docker-compose.yml.ubuntu.in
@@ -0,0 +1,32 @@
+# docker-finance | modern accounting for the power-user
+#
+# Copyright (C) 2021-2024,2026 Aaron Fiore (Founder, Evergreen Crypto LLC)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# docker-finance @DOCKER_FINANCE_VERSION@
+
+## This is a custom compose file that will be *merged* with the base compose file
+## See https://docs.docker.com/compose/how-tos/multiple-compose-files/merge/ for details
+
+## An example of adding a custom volume and environment variables
+## NOTE: *MUST* also add these variables to the env file (`edit type=env`)
+#services:
+# docker-finance:
+# volumes:
+# - ${DOCKER_FINANCE_CLIENT_TESTING}:${DOCKER_FINANCE_CONTAINER_TESTING}
+# environment:
+# - DOCKER_FINANCE_CONTAINER_TESTING=${DOCKER_FINANCE_CONTAINER_TESTING}
+
+# vim: sw=2 sts=2 si ai et
diff --git a/client/src/docker/lib/internal/lib_docker.bash b/client/src/docker/lib/internal/lib_docker.bash
index 581962c..caf92a3 100644
--- a/client/src/docker/lib/internal/lib_docker.bash
+++ b/client/src/docker/lib/internal/lib_docker.bash
@@ -66,6 +66,8 @@ function lib_docker::__docker()
# Generate docker-compose.yml
#
+ # NOTE: custom compose file merging happens at runtime
+
local _path="${global_repo_dockerfiles}/docker-compose.yml"
lib_utils::print_debug "Generating '${_path}'"
@@ -83,12 +85,16 @@ function lib_docker::__docker_compose()
{
[ -z "$global_env_file" ] && lib_utils::die_fatal
[ -z "$global_repo_dockerfiles" ] && lib_utils::die_fatal
+ [ -z "$global_custom_composefile" ] && lib_utils::die_fatal
[ ! -f "$global_env_file" ] \
- && lib_utils::die_fatal "$global_env_file not found! Run the gen command!"
+ && lib_utils::die_fatal "$global_env_file not found! Run the \`gen\` command!"
+
+ [ ! -f "$global_custom_composefile" ] \
+ && lib_utils::die_fatal "$global_custom_composefile not found! Run \`gen type${global_arg_delim_2}compose\`"
pushd "$global_repo_dockerfiles" 1>/dev/null || return $?
- docker compose -f docker-compose.yml --env-file "$global_env_file" "$@" || return $?
+ docker compose -f docker-compose.yml -f "$global_custom_composefile" --env-file "$global_env_file" "$@" || return $?
popd 1>/dev/null || return $?
}
@@ -546,7 +552,7 @@ function lib_docker::__parse_args_edit()
Configuration type:
- type${global_arg_delim_2}
+ type${global_arg_delim_2}
\e[32mExamples:\e[0m
@@ -556,11 +562,11 @@ function lib_docker::__parse_args_edit()
\e[37;2m# Edit client/container shell (superscript) \e[0m
$ $global_usage type${global_arg_delim_2}shell
- \e[37;2m# Edit client's custom Dockerfile (appended to final Dockerfile) \e[0m
- $ $global_usage type${global_arg_delim_2}build
+ \e[37;2m# Edit client's custom Dockerfile (appended to final Dockerfile) and custom docker-compose.yml \e[0m
+ $ $global_usage type${global_arg_delim_2}build${global_arg_delim_3}compose
\e[37;2m# Previous commands with alternate wordings\e[0m
- $ $global_usage type${global_arg_delim_2}superscript${global_arg_delim_3}dockerfile${global_arg_delim_3}env
+ $ $global_usage type${global_arg_delim_2}superscript${global_arg_delim_3}dockerfile${global_arg_delim_3}env${global_arg_delim_3}compose
"
if [ $# -ne 1 ]; then
@@ -593,7 +599,7 @@ function lib_docker::__parse_args_edit()
read -ra _read <<<"$_arg_type"
for _type in "${_read[@]}"; do
- if [[ ! "$_type" =~ ^env$|^shell$|^superscript$|^build$|^dockerfile$ ]]; then
+ if [[ ! "$_type" =~ ^env$|^shell$|^superscript$|^build$|^dockerfile$|^compose$ ]]; then
lib_utils::die_usage "$_usage"
fi
done
@@ -638,6 +644,11 @@ function lib_docker::__edit()
_paths+=("$global_custom_dockerfile")
;;
+ compose)
+ [ -z "$global_custom_composefile" ] && lib_utils::die_fatal
+
+ _paths+=("$global_custom_composefile")
+ ;;
esac
done
diff --git a/client/src/docker/lib/internal/lib_env.bash b/client/src/docker/lib/internal/lib_env.bash
index 2f5ec38..8f69ca5 100644
--- a/client/src/docker/lib/internal/lib_env.bash
+++ b/client/src/docker/lib/internal/lib_env.bash
@@ -208,6 +208,12 @@ function lib_env::__set_client_globals()
&& lib_utils::die_fatal "Missing default custom Dockerfile '${global_repo_custom_dockerfile}'"
lib_utils::print_debug "global_repo_custom_dockerfile=${global_repo_custom_dockerfile}"
+ # Base custom end-user .in docker-compose.yml
+ declare -g global_repo_custom_composefile="${global_repo_conf_dir}/client/Dockerfiles/${global_platform_image}/docker-compose.yml.${global_platform}.in"
+ [ ! -f "$global_repo_custom_composefile" ] \
+ && lib_utils::die_fatal "Missing default custom docker-compose.yml '${global_repo_custom_composefile}'"
+ lib_utils::print_debug "global_repo_custom_composefile=${global_repo_custom_composefile}"
+
#
# Client-side env
#
@@ -226,12 +232,18 @@ function lib_env::__set_client_globals()
global_env_file="${_client_env_dir}/${global_conf_filename}"
lib_utils::print_debug "global_env_file=${global_env_file}"
- # Custom Dockerfile (if available)
+ # Custom docker files (docker related) location
local _client_dockerfile_dir="${DOCKER_FINANCE_CLIENT_CONF}/${global_tag_dir}/Dockerfiles"
[ ! -d "$_client_dockerfile_dir" ] && mkdir -p "$_client_dockerfile_dir"
+
+ # Custom Dockerfile
global_custom_dockerfile="${_client_dockerfile_dir}/${global_conf_filename}"
lib_utils::print_debug "global_custom_dockerfile=${global_custom_dockerfile}"
+ # Custom docker-compose.yml
+ global_custom_composefile="${_client_dockerfile_dir}/${global_conf_filename}.yml"
+ lib_utils::print_debug "global_custom_composefile=${global_custom_composefile}"
+
# NOTE:
#
# Client env tag format is avoided because:
diff --git a/client/src/docker/lib/internal/lib_gen.bash b/client/src/docker/lib/internal/lib_gen.bash
index 09091b8..213b4e7 100644
--- a/client/src/docker/lib/internal/lib_gen.bash
+++ b/client/src/docker/lib/internal/lib_gen.bash
@@ -64,7 +64,7 @@ function lib_gen::__parse_args()
Category type:
- type${global_arg_delim_2}
+ type${global_arg_delim_2}
Flow (only):
@@ -111,11 +111,11 @@ function lib_gen::__parse_args()
\e[37;2m# Generate only the Docker environment\e[0m
$ $global_usage type${global_arg_delim_2}env
- \e[37;2m# Generate custom Dockerfile and joint client/container superscript\e[0m
- $ $global_usage type${global_arg_delim_2}build${global_arg_delim_3}superscript
+ \e[37;2m# Generate custom Dockerfile, docker-compose.yml and joint client/container superscript\e[0m
+ $ $global_usage type${global_arg_delim_2}build${global_arg_delim_3}compose${global_arg_delim_3}superscript
\e[37;2m# Generate all client related data\e[0m
- $ $global_usage type${global_arg_delim_2}env${global_arg_delim_3}build${global_arg_delim_3}superscript
+ $ $global_usage type${global_arg_delim_2}env${global_arg_delim_3}build${global_arg_delim_3}compose${global_arg_delim_3}superscript
\e[37;2m#\e[0m
\e[37;2m# Flow: Profile -> Configs / Accounts\e[0m
@@ -279,7 +279,7 @@ function lib_gen::__parse_args()
if [ ! -z "$_arg_type" ]; then
read -ra _read <<<"$_arg_type"
for _arg in "${_read[@]}"; do
- if [[ ! "$_arg" =~ ^env$|^build$|^flow$|^superscript$ ]]; then
+ if [[ ! "$_arg" =~ ^env$|^build$|^compose$|^flow$|^superscript$ ]]; then
lib_utils::die_usage "$_usage"
fi
done
@@ -440,6 +440,9 @@ function lib_gen::__gen_client()
fi
+ # Filter to de-clutter output file (license cleanup)
+ local -r _filter="1,17d"
+
#
# Custom (optional) Dockerfile
#
@@ -467,9 +470,6 @@ function lib_gen::__gen_client()
lib_utils::print_debug "$global_custom_dockerfile"
fi
- # Filter to de-clutter output file (license cleanup)
- local -r _filter="1,17d"
-
sed \
-e "$_filter" \
-e "s:@DOCKER_FINANCE_VERSION@:${global_client_version}:g" \
@@ -479,6 +479,42 @@ function lib_gen::__gen_client()
lib_gen::__gen_edit "$global_custom_dockerfile"
fi
+ #
+ # Custom (optional) docker-compose.yml
+ #
+
+ if [[ -z "${global_arg_type[*]}" || "${global_arg_type[*]}" =~ compose ]]; then
+
+ [ -z "$global_custom_composefile" ] && lib_utils::die_fatal
+ [ -z "$global_repo_custom_composefile" ] && lib_utils::die_fatal
+
+ # Backup existing custom compose file
+ if [ -f "$global_custom_composefile" ]; then
+ lib_utils::print_custom " \e[32m│\e[0m\n"
+ lib_utils::print_custom " \e[32m├─\e[34;1m Custom docker-compose.yml found, backup then generate new one? [Y/n] \e[0m"
+
+ [ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
+ local _confirm="${_read:-y}"
+ if [[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]]; then
+ cp -a "$global_custom_composefile" "${global_custom_composefile}_${global_suffix}" || lib_utils::die_fatal
+ fi
+ else
+ lib_utils::print_custom " \e[32m│\e[0m\n"
+ lib_utils::print_custom " \e[32m├─\e[34;1m Generating new custom docker-compose.yml\e[0m\n"
+
+ lib_utils::print_debug "$global_repo_custom_composefile"
+ lib_utils::print_debug "$global_custom_composefile"
+ fi
+
+ sed \
+ -e "$_filter" \
+ -e "s:@DOCKER_FINANCE_VERSION@:${global_client_version}:g" \
+ "$global_repo_custom_composefile" >"$global_custom_composefile" || lib_utils::die_fatal
+
+ lib_utils::print_custom " \e[32m│ └─\e[34m Edit file now? [Y/n] \e[0m"
+ lib_gen::__gen_edit "$global_custom_composefile"
+ fi
+
#
# Generate client-side `plugins` layout (custom)
#