Skip to content

Configuring sources

A source tells deckctl where to look for templates. Sources live in ~/.config/deckctl/config.yaml and are referenced by name with --source.

sources:
- name: local
type: local
path: /home/you/templates
- name: work
type: gitlab
url: https://gitlab.mycompany.com
group: platform/templates
token_env: DECKCTL_WORK_TOKEN
cache_ttl: 24h
- name: public
type: gitlab
url: https://gitlab.com
group: my-public-group
default_source: local

Full field-by-field details are in the configuration reference.

Terminal window
# Add non-interactively
deckctl source add --name local --type local --path ~/templates
deckctl source add --name work --type gitlab \
--url https://gitlab.mycompany.com \
--group platform/templates \
--env DECKCTL_WORK_TOKEN
# Add interactively (prompts for each field)
deckctl source add
# Inspect
deckctl source list
deckctl source get work
deckctl source list -o json
# Remove
deckctl source remove --name work
deckctl source remove --name work --auto-approve # skip the confirmation

A local source points at a directory whose immediate subdirectories are templates. A subdirectory only counts as a template if it contains a deckctl.yaml:

~/templates/
go-service/ ← template
deckctl.yaml
main.go.tpl
helm-chart/ ← template
deckctl.yaml
Chart.yaml
scratch/ ← ignored, no deckctl.yaml
notes.txt

Local sources are read straight from disk: nothing is cached, --tag is ignored, and cache_ttl is rejected at config load.

If the tree is large, --concurrency N fans the scan out across a bounded worker pool:

Terminal window
deckctl template list --source local --concurrency 8

The default is 1 (sequential). The result is identical either way — this is purely a throughput knob.

A GitLab source points at a group. Every non-archived project in that group is one template, and the template’s files are the project’s files at the root:

group: platform/templates
├── go-service/ ← project → template "go-service"
│ ├── deckctl.yaml
│ ├── main.go.tmpl ← rendered, suffix stripped
│ ├── README.md ← copied verbatim
│ └── media/logo.png ← copied verbatim (binary)
├── helm-chart/ ← project → template "helm-chart"
└── retired-thing (archived) ← filtered out

Nested group paths work: group: platform/templates/backend.

Tokens are never stored in config.yaml. token_env holds the name of an environment variable, and deckctl reads its value at runtime:

Terminal window
export DECKCTL_WORK_TOKEN=glpat-xxxxxxxxxxxx
deckctl template list --source work
Group visibilityToken needed?
Public group on gitlab.comNo
Private groupYes
Internal group on a self-hosted instanceYes

Create the token at User Settings → Access Tokens. Scopes:

  • read_api — listing projects and tags
  • read_repository — downloading archives from private projects

If token_env is set but the variable is empty or unset, deckctl prints a warning to stderr and continues unauthenticated rather than failing. If token_env is omitted entirely, no warning is printed.

token_env must look like an environment variable name — uppercase letters, digits and underscores — or config validation rejects it.

GitLab-backed templates can be applied at a specific git tag:

Terminal window
# Pin explicitly — non-interactive, the right choice for CI
deckctl template apply go-service ./out --source work --tag v1.2.3
# Omit --tag to pick from the project's tags interactively
deckctl template apply go-service ./out --source work

What deckctl fetches:

You runProject has tags?Result
apply X (no --tag)yesInteractive picker over all tags
apply X (no --tag)noThe project’s default branch
apply X --tag v1.2.3tag existsv1.2.3
apply X --tag v1.2.3tag missingWarning on stderr, falls back to the default branch

Notes:

  • The picker lists every tag, in the order the GitLab API returns them — there is no semver or date sorting.
  • Each ref is cached as its own entry, so v1.2.3 and v1.3.0 of the same template coexist. See Caching.
  • deckctl template variables does not take --tag; it always inspects the default branch.
SymptomLikely cause
404 Not Found when listingWrong group path (check nesting), or the token can’t see it — GitLab returns 404 for both
Empty list, no errorGroup exists but has no projects, or all of them are archived
401 UnauthorizedToken set but invalid or expired
403 ForbiddenToken valid but missing a scope (read_api, read_repository)
--tag silently ignoredTag doesn’t exist (check stderr), or the source is local
No tag picker appearsThe project has no tags — the default branch is used

More in Troubleshooting.