The Stack Manager script helps you manage multiple stack environments by facilitating initialization, environment variable merging, Docker Compose file rendering, and managing stack deployment lifecycles. The Stack Manager provides commands for creating stack templates, merging environment variables, building and running stacks, and stopping them.
The Stack Manager script is implemented in shell rather than using other tools like Taskfile due to a specific bug in Taskfile's shell implementation. This bug affects the handling of associative arrays, making it necessary to use external shell scripting for reliability. Additionally, using shell provides greater flexibility for environment management tasks.
The gomplate
templating tool is required for rendering configuration files. Please ensure it is installed before using the Stack Manager.
This setup allows for stack-specific customization, which often includes the need for templating environment variables and configuration files. The Stack Manager ensures that common and stack-specific settings can be easily managed and applied across different environments.
The init
command initializes the environment setup by creating necessary directories, configuration files, and templates.
./stackman.sh init
- Prompts:
- Application data directory (default:
app_data
). - Stacks directory (default:
stacks
).
- Application data directory (default:
- Creates:
app.conf
: Configuration file containingAPP_DIR
andSTACKS_DIR
paths..gitignore
: Configured to ignore runtime directories (APP_DIR
andSTACKS_DIR
).global.env
: Global environment variables template..stackignore
: File to ignore certain stacks during operations.docker-compose.yml.tmpl
: Default Docker Compose template for creating stack-specific configurations.
The create_template
command generates a prototype directory in STACKS_DIR
for a stack. The user can manually modify this directory before deployment.
./stackman.sh create_template -s <STACK>
- Creates:
- Stack-specific design template directory in
STACKS_DIR
. - Template files such as
.env.tmpl
,docker-compose.yml.tmpl
,.gitignore
, andREADME.md
.
- Stack-specific design template directory in
The merge
command merges global.env
variables into each stack's .env
file.
./stackman.sh merge -s <STACK>
- Global Variables: Reads all key-value pairs in
global.env
into an associative array,global_vars
, excluding comments and empty lines. - Existing Stack Variables: Reads each line of the stack's
.env
file (OUTPUT_ENV
) into an array,env_lines
. - Backup: If
.env
exists and--force
is set, a backup (.env.backup
) is created. - Merge Process:
- Global Variables Addition: Appends all key-value pairs from
global.env
to the top of the new.env
, marking them as global. - Stack-Specific Variables: Iterates through
env_lines
, preserving stack-specific entries. If a key in.env
exists inglobal.env
, it is commented out with#
and noted as "Existed in global.env."
- Global Variables Addition: Appends all key-value pairs from
- No Nested Variable Expansion: Variables in
global.env
that reference others (e.g.,DOMAIN2=$DOMAIN
) are not expanded. - Duplicate Keys: If
global.env
and the stack.env
file share keys, the stack’s.env
version is retained and commented out. - No Live Updates: The merged
.env
file is static and reflects the state at merge time. Changes inglobal.env
require re-runningmerge
for updates.
The build
command creates or updates the Docker Compose configuration (docker-compose.yml
) and other stack-specific template files based on global.env
and each stack's .env
.
./stackman.sh build -s <STACK>
- Environment Merge: Runs the
merge
command to ensure the latest global and stack-specific environment variables are present in the stack’s.env
file. - Docker Compose Rendering:
- Checks if
docker-compose.yml.tmpl
exists in the stack directory. - If it exists and
docker-compose.yml
does not, it usesgomplate
to renderdocker-compose.yml
fromdocker-compose.yml.tmpl
, substituting variables defined in.env
. - The output file,
docker-compose.yml
, contains resolved variables for Docker Compose to use directly.
- Checks if
- Data Template Rendering:
- If a
data.tmpl
directory exists, each.tmpl
file within it is processed individually. gomplate
renders each.tmpl
file, outputting the result into adata
directory with the same filename but without the.tmpl
extension.- Variable substitution is based on values in
.env
.
- If a
- Force Option:
- When
--force
is specified, it overwrites any existingdocker-compose.yml
and rendered files indata/
.
- When
- Static Rendering: Files are rendered at build time, so changes in
.env
orglobal.env
require re-runningbuild
to updatedocker-compose.yml
and data templates. - Missing Templates: If no
.env
or template files are present,build
generates nothing but completes without errors, requiring correct setup beforehand. - Gomplate Not Tested: The use of
gomplate
for rendering has not been thoroughly tested in all use cases.
-
Run a Stack: Starts the Docker Compose services for a specific stack or all stacks that are not ignored.
./stackman.sh run -s <STACK>
-
Stop a Stack: Stops the running services for a specific stack or all stacks.
./stackman.sh stop -s <STACK>
The ignore
command adds a stack to .stackignore
, ensuring that it is ignored in future operations like merge
, build
, run
, or stop
.
./stackman.sh ignore -s <STACK>
The list
command lists all runtime stacks in APP_DIR
, indicating whether each stack is ignored or not.
./stackman.sh list
init
: Initializes directories, configuration files, and templates.create_template
: Creates a prototype stack directory inSTACKS_DIR
.merge
: Merges global environment variables into each stack’s.env
file.build
: Builds Docker Compose and other templates based on merged environment variables.run
: Starts Docker Compose services for one or all stacks.stop
: Stops running Docker Compose services.ignore
: Adds a stack to.stackignore
to be ignored in operations.list
: Lists all stacks inAPP_DIR
and their ignore status.
# Initialize environment
./stackman.sh init
# Create a new stack template
./stackman.sh create_template -s my_stack
# Merge environment variables
./stackman.sh merge -s my_stack
# Build the stack
./stackman.sh build -s my_stack
# Run the stack
./stackman.sh run -s my_stack
# Stop the stack
./stackman.sh stop -s my_stack
# Ignore the stack
./stackman.sh ignore -s my_stack
# List all stacks
./stackman.sh list
- Proxy Implementation:
- Implement a proxy setup with Authentik, Traefik, and Whoami to handle authentication and reverse proxy needs effectively.
- Per-Stack Customization:
- Implement per-stack customization using a Taskfile for managing stack-specific actions.
- Shell Script for Workaround: The customization logic uses a shell script instead of a Taskfile due to a bug with associative arrays in Taskfile's Go shell, making shell scripting a more reliable choice for this functionality.
- Static Environment Files:
- The
.env
files can be modified manually and are dynamic in that sense. However, changes inglobal.env
or the need for additional flexibility may require re-runningmerge
or other commands to propagate updates.
- The
- Gomplate Not Tested:
- The use of
gomplate
for rendering templates has not been extensively tested and may need further validation in different environments.
- The use of
networks:
network1:
external: true
name: "${NETWORK_ID}"