No description
  • JavaScript 100%
Find a file
2026-05-31 22:12:23 +09:30
deploy-portainer deploy-portainer: create/update Portainer stack via API (idempotent, SHA-pinned), keep webhook fallback 2026-05-31 22:12:23 +09:30
README.md deploy-portainer: create/update Portainer stack via API (idempotent, SHA-pinned), keep webhook fallback 2026-05-31 22:12:23 +09:30

ci-actions

Shared Forgejo Actions for building and deploying containerised apps.

deploy-portainer

Composite action that builds a Docker image, pushes it to a registry, and deploys to Portainer — either by creating/updating a stack via the Portainer API (preferred), or by triggering an existing stack's redeploy webhook.

jobs:
  build-push-deploy:
    runs-on: docker            # a runner label with Docker + Node 18+
    steps:
      - uses: actions/checkout@v4
      - uses: Adam/ci-actions/deploy-portainer@main
        with:
          registry:          ${{ vars.REGISTRY_HOST }}      # e.g. git.example.com
          password:          ${{ secrets.REGISTRY_TOKEN || github.token }}
          # --- API-managed stack (Forgejo creates & updates it) ---
          portainer_url:     ${{ vars.PORTAINER_URL }}      # https://portainer.example.com
          portainer_api_key: ${{ secrets.PORTAINER_API_KEY }}
          stack_name:        myapp
          stack_file:        docker-compose.yml
          image_env_var:     IOT_IMAGE                      # compose var pinned to image:sha

For the simpler webhook mode, omit the portainer_* inputs and pass webhook: ${{ secrets.PORTAINER_WEBHOOK_URL }} instead (the stack must already exist in Portainer).

Inputs

Input Required Default Description
registry yes Registry host, e.g. git.example.com
image no ${{ github.repository }} (lowercased) Image repo path without host/tag
username no ${{ github.actor }} Registry username
password yes Registry password/token (pass a secret)
context no . Docker build context
dockerfile no Dockerfile Path to the Dockerfile
portainer_url no "" Portainer base URL — enables API-managed deploy
portainer_api_key no "" Portainer API key (pass a secret)
stack_name no repo name (lowercased) Portainer stack name
stack_file no docker-compose.yml Compose file deployed as the stack
endpoint_id no first endpoint Portainer environment id
image_env_var no "" Compose env var set to image:sha (e.g. IOT_IMAGE)
portainer_insecure no "false" "true" skips TLS verify (self-signed certs)
webhook no "" Redeploy webhook; used only when no portainer_api_key

The action tags every build as both :latest and :<commit-sha> and pushes both. With the API, it injects image_env_var=<image>:<sha> so the stack is pinned to the exact commit; the create route falls back to the legacy route for Portainer < 2.19.

Requirements

  • The runner must have Docker (host socket, or a dind service) and, for the API deploy step, Node 18+ (standard on act runner images).
  • Each calling repo provides its own Dockerfile and docker-compose.yml — only the build/push/deploy logic is shared here.
  • Secrets can't be read inside a composite action, so the caller passes password, portainer_api_key, and webhook as inputs (from its own secrets).

Referencing from another instance

If your act_runner doesn't resolve bare uses: against your Forgejo instance, use the full URL form:

      - uses: https://git.app.oreilly.bz/Adam/ci-actions/deploy-portainer@main