A Dagger module for managing and deploying Docker Compose manifests through SSH connection.
- Initiate a dagger project.
- Create
manifestsdirectory under root fo the project directory and puts all docker compose and all related files there. You can create as many subfolder as needed. - Create
.sshfolder that at minimum contains ssh private key namedid_rsa. - Import and unify the
#DDCompose.planwithdagger.#Plan - Fill
#DDCompose.manifestswith information related to all manifests inmanifestsdirectory. See #Manifest for all avaialable fields. - Execute
dagger do deployto deploy all defined manifests.
Suppose there is an awesome-service with the following docker compose related files:
$ find manifests
manifests
manifests/host1.example.test/awesome-service
manifests/host1.example.test/awesome-service/settings.conf
manifests/host1.example.test/awesome-service/docker-compose.ymlTo deploy this manifest to host1.example.test and put all the manifest files inside /opt/docker/awesome-service, the cue file should look like this
package main
import (
"dagger.io/dagger"
"github.com/telkomindonesia/ddcompose"
)
dagger.#Plan & (ddcompose.#DDCompose & { manifests: [
{
name: "awesome-service"
path: "host1.example.test/awesome-service"
remoteHost: "host1.example.test"
remotePath: "/opt/docker/awesome-service"
},
]}).planCheckout examples for more sample on how to use this module.
The deploy actions is composed with sub-actions structured in the following manner:
deploy:<manifest name>:<manifest remoteHost>:<manifest remotePath>:<manifest>
This allow for controlling which manifest(s) to be deployed. For example:
dagger do deploy awesome-servicewill deploy all manifest namedawesome-service.dagger do deploy awesome-service host1.example.testwill deploy all manifest namedawesome-serviceonly tohost1.example.test.dagger do deploy awesome-service host1.example.test /opt/docker/awesome-servicewill deploy all manifest namedawesome-serviceonly tohost1.example.testand only to path/opt/docker/awesome-service.
Since 0.8.0, synchronization is done using rsync with --delete flag. Exclusion is possible by creating .rsync-exclude file inside the root dir of each manifest path, which will be passed as argument to --exclude-from flag.
Under the hood, the deploy action wraps docker compose command to deploy the manifest. To add additional config for the docker client (such as authentication for remote registry), set #DDCompose.docker.config to true and put the config inside .docker/config.json.
It is also possible to deploy the manifest to the local host where the command is executed. To do this, do not set the remoteHost remotePath attribute of the manifest.
In this mode, a docker volume will be generated that will contain the modified manifest filesß. This volume can then be used in docker-compose by using DDCOMPOSE_MANIFEST_VOLUME env variable, for example
services:
certain-service:
volumes:
- ${DDCOMPOSE_MANIFEST_VOLUME:-.}:/srcThe fenvname action is used to generate a text file containing a list of files or folders inside manifests folders with their respective generated-variable name. This variable name can be included in docker compose file to force recreate the related container when the content of the correlated file or folder changes. See examples for more detail on how to include the fenv inside docker compose file.
The module support automatic file decryption for all files with __sops__ prefix encountered inside manifests dir using sops and age encryption. To enable this feature, set #DDCompose.sops.age to true and put the private key inside .sops/age/keys.txt file.
An optional action named build can be enabled by setting #DDCompose.builders to true which allow an execution of terraform scripts inside builders folder. During execution, the terraform scripts will have access to the manifests directory whose path can be accessed by defining a variable named manifests_dir.
If #DDCompose.sops.config is set to true (which require .sops.yaml file to be available on the root directory), then terraform.tfstate will be encrypted as __sops__terraform.tfstate after each execution and the original terraform.tfstate will be deleted. See examples for more detail.