An open API service indexing awesome lists of open source software.

https://github.com/caracolazuldev/d-composer

A Gnu Make Makefile include to manage complex docker-compose definitions.
https://github.com/caracolazuldev/d-composer

docker docker-compose make makefile

Last synced: 11 months ago
JSON representation

A Gnu Make Makefile include to manage complex docker-compose definitions.

Awesome Lists containing this project

README

          

# Decomposer

Welcome to Decomposer, the Docker-Compose Configuration Manager. As a Makefile include, it easily integrates into your Makefile-based or shell-script build and deployment tools.

This Makefile facilitates dynamically generating `docker-compose.yml` files from reusable service declarations. You might want to do this to test your application on different deployment targets or environments without duplicating common service definitions. Or, more easily re-use service definitions from one project to the next. Other use-cases might be: having different stacks for development, unit testing, integration and QA testing, or generating production builds.

To generate a `docker-compose.yml` file and an `.env` file, decomposer looks in the environment variables, `STACK_SERVICES` and `ENV_INCLUDES`, to generate a list of file includes. You can easily switch between stacks using the `activate` and `deactivate` commands. You must first set the `STACK` environment variable to the name of the stack you want to activate. Using the stack name, additional files are automatically discovered and included in the `docker-compose.yml` and `.env` files.

For lazy typers, decomposer aliases `docker compose` commands. Rather than typing `docker compose` commands directly, you will use `make` followed by the docker-compose command you want to run, e.g. `make up`, `make down`, `make exec`, etc. See the [Aliases and Custom Commands](#aliases-and-custom-commands) section for additional commands not provided by `docker compose`.

In addition to wrapping `docker compose`, decomposer smooths-out some rough-edges in the `docker-compose` cli. For example, automatically passing the `--rm` flag to `docker compose run`, bringing up applications in detached mode by default, or cleanly removing a task by implicitly calling `docker-compose rm --force --stop`.

The command wrappers also facilitate extending your development environment with ad hoc commands in your main Makefile. For example, you can run `make TASK=shell` to run a shell in the active stack, or `make TASK=php8-apache RUN_CMD='php -i'` to run `php -i` in the PHP 8 Apache container.

Decomposer need not be adopted by an entire team because it does not break classic `docker-compose` usage. For those team members that do not need to switch between stacks, you can commit fully-generated `docker-compose.yml` files to your repository, and they can use `docker-compose` as they always have.

Gain deeper insights into Decomposer on folder structure, environment variables, and configuration files:

- see [docs/Orientation](docs/Orientation.md)

## Installation

Makefile global includes are typically installed in `/usr/local/include`. To install Decomposer as a global include, clone the repository and run `make install` with admin permissions. You can override the install location with `INSTALL_LOCATION`. But really, "installation" is just copying the `decomposer.mk` file to a location where you can include it in your top-level Makefile.

## Decomposing Compose Definitions

Docker Compose definitions are decomposed into smaller, modular files for better maintainability and flexibility. When you set the `STACK` environment variable and run `make activate`, a `docker-compose.yml` and a `.env` file are generated. The `docker/` directory contains service definitions in the form of docker-compose service declaration fragments, using `docker compose config` to unify the fragments.

The stack is defined by the `STACK_SERVICES` environment variable, each word will automatically have the `.yml` extension appended to it. The `docker-compose.yml` file is generated by pattern-matching on the stack-name in the project-root directory, any corresponding `.yml` files for each service declared in the stack, and any additional files specified in the `STACK_INCLUDES` environment variable. You can include any arbitrary file by adding it to the `STACK_INCLUDES` environment variable, as long as it is in the `docker/` directory.

Then, each of your services in the `docker/` directory will start with a `service` stanza, and one service definition.
```yaml
services:
:
image:
build:
args:
LOGIN_UID: ${LOGIN_UID:-1000}
LOGIN_GID: ${LOGIN_GID:-1000}
FROM_IMAGE: ${FROM_IMAGE:-php:8-apache}
# ...
```

This takes advantage of the fact that `docker compose` can take multiple configuration files, and compose them. Rather than passing a list of files on each invocation, we use the `config` command to pre-generate a single `docker-compose.yml` file. This is why you must `activate` a stack before running `docker compose` commands.

The `.env` file is concatenated from files discovered by pattern-matching on the stack-name in the project-root directory, any corresponding `.env` files for each service declared in the stack, and any additional files specified in the `ENV_INCLUDES` environment variable.

## Environment Variables

The Makefile utilizes the following environment variables:

- `STACK`: Defines the active stack.
- `STACK_SERVICES`: Specifies the list of services within the stack.
- `ENV_INCLUDES`: Additional files used to generate the `.env` file.
- `COMPOSER_PROJECT_NAME`: Determines the project's network name if you don't want to use the default.
- `DK_CMP_OPTS`: Options passed to `docker-compose` commands.
- `TASK`: Specifies a docker-compose service, used to run ad hoc commands.
- `RUN_CMD`: Command to execute in the specified service.
- `CMD_ARGS`: Additional options for `RUN_CMD`.

## Examples

Here are some common usage examples:

- `STACK=lamp make up`: Bring up the LAMP stack.
- `STACK=lamp TASK=shell make run`: Run a shell in the LAMP stack.
- `make TASK=mysqld top`: View the top processes in the MySQL service.
- `make config CMD_ARGS=--services`: Review the generated `docker-compose.yml`.
- `make build TASK=php8-apache DK_CMP_OPTS='--no-cache'`: Build the PHP 8 Apache image with no cache.
- `make exec TASK=php8-apache RUN_CMD='php -i'`: Execute `php -i` in the PHP 8 Apache container.
- `make rund TASK=shell RUN_CMD='php' CMD_ARGS="-r 'phpinfo();'"`: Run PHP with `phpinfo()` in the shell container.

## Troubleshooting

If you are having trouble defining commands, you can set the environment variable `DEBUG` to be non-empty, and the Makefile will print the constructed command.

## Aliases and Custom Commands

Any `docker-compose` command can be run with `make` by prefixing the command with `make`. For example, `docker compose up` becomes `make up`. In addition to the `docker-compose` commands, the Makefile provides some additional commands:

- `make services`: List the services in the active stack. Alias of `docker compose config --services`.
- `make config`: Review the generated `docker-compose.yml` file. Alias of `docker compose config`.
- `make up`: Bring up the active stack, and detach. Alias of `docker compose up -d`.
- `make down`: Stop and remove the active stack. When a TASK is specified, alias of `docker-compose rm --force --stop`.
- `make run`: Run a command in the specified service (`TASK`) and remove it when stopped. Alias of `docker compose run --rm`.
- `make rund`: Like `run`, but runs detached (like in background). Alias of `docker compose run -d`.
- `make orphans`: Remove orphaned containers. Alias of `docker compose down --remove-orphans`.

> **NOTE:** some newer `docker-compose` commands are not yet aliased. You can still run them with `make` by prefixing the compose command with `dkc-`, e.g. `make dkc-images`, or `make dkc-copy`.

**Bonus for lazy-typers:** recommended aliases to add to your shell profile:
``` sh
alias dk='docker'
alias dkc='docker compose'
alias dki='docker image'
alias dkl='docker ps -a --format '\''table {{if .ID}}{{slice .ID 0 4}}{{end}}\t{{.Names}}\t{{if .Status}}{{slice .Status 0 2}}{{end}}\t{{.Image}}\t{{.Command}}'\'''
alias dkll='dkl --no-trunc'
alias dkr='docker run --rm'
alias dke='docker exec -it'
```

## Getting Started with Docker Compose

If you're new to Docker Compose and are not familiar with project names, networks, volumes, tasks, and common Docker Compose commands, see our [docs/Compose Quick-start](docs/Compose Quick-start.md) for some sign-posts to start your journey.

For more detailed explanations and references, feel free to explore Docker Compose documentation:

- [Docker Compose Reference](https://docs.docker.com/compose/reference/envvars/)
- [Compose File Reference](https://docs.docker.com/compose/compose-file/compose-file-v3/)
- [Docker Compose Documentation](https://docs.docker.com/compose/reference/)

Enjoy managing your Docker Compose configurations with ease using this Makefile!