Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A GitHub action to deploy a stack to a Docker Swarm Mode cluster.

License

NotificationsYou must be signed in to change notification settings

matchory/docker-swarm-deployment-action

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

Lint CodebaseContinuous IntegrationCheck DistCodeQL AdvancedCoverage

A powerful GitHub Action to deploy your applications to a Docker Swarmcluster. It automatically reconciles features from the newer ComposeSpecification usually not available in Docker Swarm, rotates configs andsecrets for you, and can optionally monitor stacks for any post-deploymentissues (e.g., restart cycles or rollbacks) and let the deployment failaccordingly.
Designed to "do the right thing" out of the box, with flexible options forcustomization.

Docker Swarm Deployments

✨ Features

  • Easy Setup: The action usesthe same environment variablesas the Docker CLI, so you can connect to your Docker Swarm cluster using acontext, and via all transports supported by Docker (e.g., HTTP, TCP, SSH,etc.).
  • Smart Compose Handling: It automatically discovers your Compose file andsupports both the Compose Specification and Compose File v3, so you don't haveto worry about incompatibilities.
  • Automatic Config & Secret Management: It rotates secrets and configsautomatically and can even transform their data on-the-fly (e.g., base64encode/decode).
  • Reliable Deployments: Validates your configuration before deploying usingdocker stack config.
  • Optional Post-Deployment Monitoring: Ensures your services are stableafter deployment.
  • Fully Tested: An extensive test suite ensures the action works asexpected.

🚀 Getting Started

Prerequisites

  • A Docker Swarm cluster accessible in the GitHub Actions environment
  • A Docker Compose file

Simple Usage

In most cases, you don't need to explicitly tell the action where your Composefile is. If your file is named commonly (likecompose.yaml,compose.yml,docker-compose.yaml, ordocker-compose.production.yml) and is in yourrepository's root or a standard location, the action will find it automatically.

Here's a basic workflow example:

name:Deploy to Docker Swarmon:push:branches:      -mainjobs:deploy:steps:      -name:Checkout codeuses:actions/checkout@v4      -name:Deploy to Docker Swarmuses:matchory/deployment@v1environment:DOCKER_HOST:tcp://my-swarm-host:2375

You could also leverage a Docker context to connect to your Swarm cluster. Thisis the recommended way to connect to a remote Docker host, as it allows you touse SSH or TLS for secure connections:

name:Deploy to Docker Swarmon:push:branches:      -mainjobs:deploy:steps:      -name:Checkout codeuses:actions/checkout@v4      -uses:arwynfr/actions-docker-context@v2with:context_name:"swarm"docker_host:"ssh://someone@example.domain.tld"ssh_cert:${{ secrets.SSH_CERT }}ssh_key:${{ secrets.SSH_KEY }}      -name:Deploy to Docker Swarmuses:matchory/deployment@v1env:DOCKER_CONTEXT:swarm

⚙️ Configuration

Inputs

To configure the action, you can use the following inputs:

InputDefaultDescription
stack-nameRepository nameThe name of the stack to deploy. If not specified, the repository name (without the "user/" part) will be used.
versionTag Name / Commit SHAThe version of the stack to deploy. If not specified, the action will use the tag name or commit SHA of the build.
compose-fileThe path to the compose file. If not specified, the action willautomatically search for it.
env-var-prefixDEPLOYMENT_Prefix to resolve variables intended forauto-configuration of variables.
manage-variablestrueWhether to automaticallymanage configs and secrets.
strict-variablesfalseWhether to throw an error if a variable specified in the compose spec is not defined.
variablesVariables as KEY=value pairs, newline-separated, or JSON object (e.g.,${{ toJSON(vars) }}). Applies to environment.
secretsSecrets as KEY=value pairs, newline-separated, or JSON object (e.g.,${{ toJSON(secrets) }}). Higher priority than variables.
exclude-variablesList of variable names to exclude from deployment, separated by newlines. Applies to all variable sources.
extra-variablesAdditional variables as KEY=value pairs, separated by newlines. Highest priority, overrides all other sources.
monitorfalseWhether tomonitor the stack after deployment.
monitor-timeout300The maximum time in seconds to wait for the stack to stabilize.
monitor-interval10The interval in seconds to check the stack status.

Outputs

OutputDescription
statusThe status of the deployment. Possible values:success,failure.
stack-nameThe name of the stack that was deployed.
versionThe version of the stack that was deployed.
compose-specThe final compose specification used for the deployment.
service-logsLogs of a failed service after deployment.

📖 Reference

How Compose File Detection Works

If thecompose-file input is not specified, the action automatically searchesfor your Compose File(s) in the following common locations and names, indescending order:

  1. compose.production.yaml
  2. compose.production.yml
  3. compose.prod.yaml
  4. compose.prod.yml
  5. compose.yaml
  6. compose.yml
  7. docker-compose.production.yaml
  8. docker-compose.production.yml
  9. docker-compose.prod.yaml
  10. docker-compose.prod.yml
  11. docker-compose.yaml
  12. docker-compose.yml
  13. .docker/compose.yaml
  14. .docker/compose.yml
  15. .docker/docker-compose.yaml
  16. .docker/docker-compose.yml
  17. docker/compose.yaml
  18. docker/compose.yml
  19. docker/docker-compose.yaml
  20. docker/docker-compose.yml

The first file found will be used. Moderncompose.* files take priority overlegacydocker-compose.* files, following theCompose Specification standardized in 2021. Thiscovers most standard project structures while maintaining full backwardcompatibility.

Using environment variables

The action also respects theCOMPOSE_FILE environment variable if set, andmultiple files specified there or via thecompose-file input can be separatedby theCOMPOSE_FILE_SEPARATOR environment variable (defaults to:).

Specifying a Custom Compose File, or Multiple Files

If your Compose File doesn't follow the automatic detection pattern, or you needto use multiple Compose Files (which will be merged), use the compose-fileinput:

-name:Deploy with Custom Compose Fileuses:your-github-username/your-repo-name@v1with:stack-name:my-applicationcompose-file:path/to/your/custom-compose.yaml

To use multiple files:

-name:Deploy with Multiple Compose Filesuses:your-github-username/your-repo-name@v1with:stack-name:my-applicationcompose-file:compose.yaml:compose.override.yaml# Using default separator ':'# Or with a different separator:# compose-file: compose.yaml,compose.override.yaml# env:#   COMPOSE_FILE_SEPARATOR: ','

How Compose Files Are Processed

The action is designed to be flexible and robust when it comes to your Composefiles. It doesn't strictly require either the old v3 format or the new ComposeSpecification. Instead, it:

  • Reads your specified (or detected) Compose File(s).
  • Applies internal transformations to handle known differences between formatsfor Swarm compatibility.
  • Usesdocker stack config to validate the resulting configuration and mergemultiple files into a single, canonical Compose Specification.

This ensures that regardless of the exact format you use (even mixing them), thefinal configuration passed todocker stack deploy is valid and correctlyinterpreted by Docker Swarm.

Variable interpolation

All environment variables inside the Compose Spec(s) will be interpolatedautomatically according to theCompose Specification rules,with one optional improvement: If you enable thekey-interpolation input, theaction will also replace environment variables in all keys in your Compose Spec,not just in values. This is useful for dynamic service names or other keys thatdepend on environment variables.

The following syntax is supported for variable interpolation:

-"$VARIABLE_NAME"-"${VARIABLE_NAME}"-"${VARIABLE_NAME-default if not set}"-"${VARIABLE_NAME:-default if not set or empty}"-"${VARIABLE_NAME+alternative if set}"-"${VARIABLE_NAME:+alternative if set and not empty}"-"${VARIABLE_NAME?error if not set}"-"${VARIABLE_NAME:?error if not set or empty}"

In contrast to the legacy Compose File v3 format, the Compose Specification (andthe implementation in this action) do allow for unlimited recursiveinterpolation, meaning that the following will work as expected:

-"${FOO:-${BAR:-${BAZ}}}"

In addition to all variables in the process environment and thosepassed in thevariables input, thefollowing variables derived from the inputs are also available:

  • MATCHORY_DEPLOYMENT_STACK: The name of the stack being deployed.
  • MATCHORY_DEPLOYMENT_VERSION: The version of the stack being deployed.

Configuring Secrets and Configs

Loading Environment Variables or inline Content

Docker Swarm only supports reading configs and secrets from files, but theCompose Specification allows you to use theenvironmentandcontentproperties to load them from environment variables or inline content,respectively. This action automatically converts these properties to files, soyou can use them in your Compose File without worrying about the deployment.

For example, if you have a Compose File with the following configs:

configs:app_url:environment:APP_URLdatabase_username:content:root

The action will automatically create files for these configs, and the resultingspecification file passed to the actualdocker stack deploy call will looklike this:

configs:app_url:file:./app_url.1740e753-0a19-446a-ba6e-361b24f5d9e1.generated.secret# omitting rest for brevitydatabase_username:file:./database_username.c95397dc-c300-4125-b95e-e2ce43821d72.generated.secret# omitting rest for brevity

The action will create the files in the same directory as the Compose File andappend a unique identifier to the filename to avoid conflicts. The files will beremoved after the deployment is complete, so you don't have to worry aboutleaving temporary files behind to the next action.

Smart Variable Resolution

You don't have to specify the data source (file,environment, orcontent)manually: In fact, you don't have to add any properties at all! The followingexample will work just as well:

configs:# Pass an empty object, …app_url:{}# …or even a YAML-null value for brevity!database_username:~

The action will attempt to resolve the variable content automatically, andpopulate thefile property with that. This is done by the following rules:

  1. If a file with the name of the variable exists in working directory namedlike the variable key with the suffix ".secret" (e.g../app_url.secret), itwill be used as the file source.
  2. If an environment variable with one of the following name patterns exists, itwill be used as the environment source:n
    • Exact variable key (e.g.app_url)
    • Uppercase variable key (e.g.APP_URL)
    • Variable key prefixed with theenvVarPrefix (e.g.DEPLOYMENT_app_url)
    • Uppercase variable key prefixed with theenv var prefix setting(e.g.DEPLOYMENT_APP_URL)
    • Variable key prefixed with thestack name (e.g.my_repo_app_url)
    • Uppercase variable key prefixed with thestack name (e.g.MY_REPO_APP_URL)
  3. If neither of the above is found, an error will be thrown and the action willfail.

Providing GitHub Secrets and Variables

You can use GitHub Secrets and Variables to provide the values for your configs.This action supports multiple ways to pass variables, making it easy to work withboth individual variables and bulk repository configuration.

Using JSON input (Recommended)

The easiest way to pass all repository secrets and variables is using JSON input.This approach eliminates the need to list each variable individually:

-name:Deploy to Docker Swarmuses:matchory/deployment@v1with:stack-name:my-application# Pass all repository variables as JSONvariables:${{ toJSON(vars) }}# Pass all repository secrets as JSONsecrets:${{ toJSON(secrets) }}# Optionally exclude specific variablesexclude-variables:|      SOME_INTERNAL_VAR      CI_TOKEN# Add extra runtime variables if neededextra-variables:|      DEPLOYMENT_ID=${{ github.run_id }}      BUILD_URL=${{ github.repository }}/actions/runs/${{ github.run_id }}
Using key-value pairs

You can also use the traditional approach with explicit key-value pairs.This gives you fine-grained control over which variables to include:

-name:Deploy to Docker Swarmuses:matchory/deployment@v1with:stack-name:my-applicationvariables:|      # Lines starting with '#' are ignored as comments      APP_URL=https://myapp.example.com      DATABASE_USERNAME=${{ vars.DATABASE_USERNAME }}      DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}
Variable priority and merging

When using multiple input sources, variables are merged with the following priority(later sources override earlier ones):

  1. Environment variables (lowest priority)
  2. variables input (JSON or key-value)
  3. secrets input (JSON or key-value)
  4. extra-variables input (highest priority)

Theexclude-variables filter is applied after all merging is complete.

Setting multi-line variables

Multi-line variables (e.g., PEM keys or certificates) are supported in key-valueinputs using HEREDOC syntaxsimilar to$GITHUB_ENV:

variables:|  APP_URL=https://myapp.example.com  NODE_LIST<<EOF  node-1.example.com  node-2.example.com  node-3.example.com  EOF  DATABASE_USERNAME=${{ vars.DATABASE_USERNAME }}
Mixed usage examples

You can mix JSON and key-value formats as needed:

# Example: Use JSON for bulk config, key-value for specific overrides-name:Deploy to Docker Swarmuses:matchory/deployment@v1with:variables:${{ toJSON(vars) }}# All repository variablessecrets:${{ toJSON(secrets) }}# All repository secretsextra-variables:|# Runtime-specific variables      DEPLOYMENT_TIME=${{ github.event.head_commit.timestamp }}      GIT_SHA=${{ github.sha }}exclude-variables:|# Remove sensitive CI variables      GITHUB_TOKEN      RUNNER_TOKEN

Automatic Rotation

A major pain point deploying applications to Docker Swarm is managing secretsand configs (henceforth called"variables"), which are designed to beimmutable and cannot be updated in place. This action automates the process ofcreating new variables when deploying and updating the stack to use them.
To make this work, the action detects changes to thecontent of variablesreferenced in the Compose File by storing their SHA256 hash in a label on thevariable and appending it to the full name. For example, given the followingconfig in the Compose File:

configs:database_username:content:root

The action will transform it to:

configs:database_username:name:YOUR_STACK-database_username-53175bcfile:./database_username.36934723-0a0b-4eb6-ab9d-d3a4e5e3cb34.generated.secretlabels:com.matchory.deployment.name:database_usernamecom.matchory.deployment.hash:53175bcc0524f37b47062fafdda28e3f8eb91d519ca0a184ca71bbebe72f969acom.matchory.deployment.stack:YOUR_STACKcom.matchory.deployment.version:VERSION

(YOUR_STACK andVERSION are placeholders for the actual stack name andversion as defined in the settings)

This has two notable implications:

  1. As the short SHA256 hash is appended to the variable name, it will staystable if the content doesn't change across deployments, which avoidsunnecessary updates to the stack. If the database username stays root, thestack will continue to use the variable created in the initial deployment,even if other variables or settings are updated.
  2. After the deployment is complete, the action will prune any unused variablesby checking the labels. If a variable is not referenced in the Compose Fileanymore, it will be safely removed from the cluster. This is important tokeep the cluster clean and avoid cluttering it with old variables.

Configuring the Variable Name

The deployment action will automatically construct the variable name from thefollowing template:

`${stackName}-${variableName}-${hash.slice(0,7)}`;

As the name must be globally unique, this includes the stack name, the name ofthe variable (the key in the Compose File), and the first seven characters ofthe hash. This ensures that even if two stacks use the same variable name, theywill not conflict.
If you provide a custom name for the variable, it will be used verbatim, butthe hash will still be appended. This is necessary to enable automaticchange detection and pruning.

Disabling Automatic Variable Management

If you want to manage your variables manually, you can either disable theautomatic variable management altogether by setting themanage-variables inputtofalse, or you can add thecom.matchory.deployment.ignore label to thevariable:

configs:dotenv:file:.envlabels:com.matchory.deployment.ignore:"true"

This will prevent the action from touching the variable, and it will not bepruned after the deployment. Note that this will also disable the automaticconversion of compose-spec-style inputs fromcontent orenvironment.

Data Transformation

You can optionally transform the data of your configs and secrets during thedeployment process using labels in your Compose File. This is useful forhandling sensitive data that might be stored in an encoded format.
Add either thecom.matchory.deployment.encode orcom.matchory.deployment.decode label to your config or secret definition,specifying one of the supported formats:

  • base64
  • base64url
  • hex
  • url

For example, to load a base64-encoded environment variable:

configs:my_config:environment:BASE64_ENCODED_PEM_KEYlabels:com.matchory.deployment.decode:"base64"

This will decode the variable before passing it to the container, resulting in aproperly formatted, multi-line PEM key in the container file system.

Do you have a different encoding in mind? Feel free to open an issue or PR, andwe can add it to the action.

How the stack is deployed

To deploy the final specification, the action uses thedocker stack deploycommand effectively like this:

echo$final_schema| docker stack deploy \     --resolve-image=always \     --with-registry-auth \     --compose-file"-" \     --detach \     --prune \$stack_name

Post-Deployment Monitoring

The action can optionally monitor your stacks for any post-deployment issues(e.g., restart cycles or rollbacks) and fail the deployment accordingly. This isdone by checking the status of the services in the stack after the deployment,waiting until all services are running and stable.
Especially for bigger deployments, this can take a while, so the monitoringfeature is disabled by default. You can enable it by setting themonitor inputtotrue.

Note that a monitoring failure willnot automatically roll back the stack.Swarm takes care of that itself. Stack Monitoring solves a different problem: Itmakes sure an update to a stack is not only successful, but also stable, thatis, it doesn't roll back or restart any services after the deployment. If thathappens, and the stack does not stabilize, monitoring will fail the action andnotify you of the issue.

Monitoring Timeout & Interval

The action will wait for a configurable maximum ofmonitor-timeout seconds forthe services to stabilize, checking their status everymonitor-intervalseconds. The default values are 5 minutes and 10 seconds, respectively.

You can adjust these values to suit your needs. For example, if you want to waitfor 10 minutes and check every 30 seconds, you can set the following inputs:

jobs:deploy:steps:      -name:Deploy to Docker Swarmuses:matchory/deployment@v1uses:matchory/deployment@v1with:monitor:truemonitor-timeout:600# 10 minutesmonitor-interval:30# 30 seconds

🔨 Contributing

Contributions are welcome! If you have any ideas, suggestions, or bug reports,please open an issue or a pull request.

About

A GitHub action to deploy a stack to a Docker Swarm Mode cluster.

Topics

Resources

License

Stars

Watchers

Forks

Contributors3

  •  
  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp