Skip to main content

Overview

SFTPGo is an SFTP server whose storage backend is object storage rather than a disk. Clients speak standard SFTP on port 2022; uploaded files land in your own S3, Google Cloud Storage or S3-compatible bucket, one folder per user, with the user list declared in your values. The template runs SFTPGo as a single stateful replica in one of two modes. scale_to_zero (the default) suspends SFTPGo while idle behind a small always-on proxy that wakes it on the next connection; always_warm keeps SFTPGo running with its own public endpoint. The administrator login for the web admin and REST API comes from a secret you create before installing.
This template deploys into an existing GVC that you already have. It does not create or manage a GVC. Pass the GVC with --gvc GVC_NAME at install time.

What Gets Created

The files your users upload are not stored on the volume set — they go to your bucket, which the template never creates or deletes.

Prerequisites

Two things must exist before you install: the administrator secret, and a bucket in one of the supported backends with its access setup.

Admin Credentials Secret

The SFTPGo administrator login guards the web admin and REST API, so it comes from a secret rather than a Helm value. Secrets are org-level, so no --gvc flag is involved.
1

Create the admin credentials secret

A dictionary secret holding exactly the keys username and password:
Set admin.secretName to the name you used.
2

Read it back later

Pass -o yaml; a bare cpln secret reveal prints only a summary table, not the values:
SFTPGo uses this secret only when its embedded database has no administrator yet, which means on the first boot of a fresh volume set. Editing the secret later does not change an existing administrator’s password.
A missing prerequisite secret wedges the install rather than failing it. cpln helm install reports success and the resources are created, but SFTPGo never starts. Because the container never ran, cpln logs returns zero lines, which looks like a platform fault rather than a missing step.The only place the missing secret is named is status.versions[].message:
Use get-deployments — plain cpln workload get has no versions key. Once the secret exists the deployment recovers on its own after several minutes, or immediately with a forced redeployment:

Object Storage

Choose a backend with storage.type and complete its setup. AWS and GCP are keyless: SFTPGo’s workload identity receives temporary credentials through a Control Plane cloud account, and no keys are stored. An S3-compatible server takes static keys.
1

Create a bucket

Create an S3 bucket. Set storage.aws.bucket to its name and storage.aws.region to its region.
2

Create a cloud account

If you do not already have one for this AWS account, create a cloud account. Set storage.aws.cloudAccountName to its name.
3

Create a bucket-scoped IAM policy

In AWS IAM, create a policy from the JSON below, replacing YOUR_BUCKET with your bucket name. Set storage.aws.policyName to the policy’s bare name, not its ARN.

Installation

With the admin secret and your bucket in place, install into your existing GVC. This example uses the default AWS backend and replaces the default SFTP user, whose shipped password is a placeholder:
Setting any users[...] entry with --set replaces the whole default list, so always pass username with it. For more than one user, or for public-key users, put users in a values file instead.

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations

Pulumi

Declare templates in your Pulumi programs

Configuration

Mode and Scale to Zero

idleHold must be a duration such as 90s, 5m or 1h; the chart refuses to render otherwise. In scale_to_zero mode the dedicated load balancer, not the proxy’s compute, is most of the idle cost.

SFTPGo Server

The volume set keeps SFTPGo’s SSH host keys stable across restarts and wakes, so clients do not see a changed host key. The template prepares the volume for the image’s non-root user, so if you change image, stay on the same drakkan/sftpgo distroless image family.

Admin

The secret must exist before install — see Prerequisites. The chart refuses to render with admin.secretName empty.

Storage Backend

Only the block matching storage.type is used. The my-… defaults are placeholders for resources you own and must replace. For minio, use the fully qualified internal hostname shown in Prerequisites rather than the short name in the default.

Users

  • At least one user is required, usernames must be unique, and every user needs a password, at least one entry in publicKeys, or both.
  • Each user is confined to the bucket folder {keyPrefix}{username}/, where keyPrefix is the backend’s bucket-wide prefix; a per-user keyPrefix replaces that folder entirely.
  • users[].password is a Helm value used exactly as written — it cannot be moved into a secret, because SFTPGo reads it from a file that does not resolve secret references. Change the change-me-sftp-user default, or better, omit password and use publicKeys, which needs no credential in your values at all.
  • The list is re-applied every time SFTPGo starts or wakes. Edits made to a declared user through the web admin or REST API are overwritten; users created there are left alone.

Access

publicAccess.enabled: true gives the client-facing workload — the proxy in scale_to_zero mode, SFTPGo itself in always_warm — a dedicated load balancer serving raw TCP on port 2022. With false, there is no public endpoint and clients reach SFTP from inside the GVC. In scale_to_zero mode SFTPGo itself is never public; only the proxy is. webAdmin.enabled: true declares port 8080 for the web admin and REST API. Reach it with a port-forward as shown in Connecting. Access changes can take a few minutes to take effect.

Connecting

Find the public endpoint on the client-facing workload (the proxy in the default mode):
Then connect with any SFTP client, using the host part of that endpoint and one of your declared users:
A newly created public endpoint can take a few minutes before its DNS name resolves.

Reaching the Web Admin

The public endpoint is a raw TCP address on port 2022, so the web admin is not served there. With webAdmin.enabled: true, open a tunnel instead — it works whether or not the workload is public:
Then open http://localhost:8080 and sign in with the administrator login from your admin secret. In scale_to_zero mode SFTPGo must be awake for the tunnel to reach it; connect once over SFTP first if it is suspended.

Client Timeouts in Scale to Zero Mode

In scale_to_zero mode the first connection after an idle period waits while SFTPGo wakes. The proxy holds the connection open, so nothing is refused, but clients with a short SSH banner timeout give up before the server answers. Configure clients generously:
  • paramiko — connect(..., banner_timeout=120, timeout=120)
  • WinSCP — set the session timeout to at least 120 seconds
  • OpenSSH sftp — works with its defaults
  • Unattended jobs — retry with backoff. Even a failed first attempt starts the wake, and SFTPGo then stays up for scaleToZero.idleHold after the last connection, so the retry connects immediately.
Right after a fresh install, the very first connection may time out once and then succeed on retry. For third-party clients you cannot configure, use mode: always_warm.

Operations

Backing Up

Uploaded files live in your bucket, so back them up with your storage provider’s own tools (versioning, replication or bucket snapshots). The template never creates or deletes the bucket, and uninstalling leaves every file in place. The volume set holds only SFTPGo’s embedded database — the administrator and any users created through the web admin — and the SSH host keys. Declared users are rebuilt from your values on every start. Take an on-demand snapshot of the volume set with:
A final snapshot is also taken automatically when the volume set is deleted, and kept for 7 days.

Restoring a Backup

Restoring a volume set snapshot onto this template has not been verified. Restoring it into a running release has not been exercised on this chart. See the volume set reference for the platform’s snapshot commands, and rehearse a restore yourself before relying on it.
If the volume set is lost, a fresh install still serves every file in the bucket: declared users are recreated from your values and the administrator from your admin secret. What is lost is any user created through the web admin, and the SSH host keys — clients that pinned the old host key will warn about a changed key and must accept the new one.

Upgrading from 1.0.0

Version 1.1.0 moved the administrator login out of Helm values. 1.0.0 took admin.username and admin.password as values, used exactly as written.
An upgrade that still carries either removed key is refused at render time, before anything is applied. The running release is left untouched:
1

Create the admin credentials secret

Follow Prerequisites, putting the username and password you already use into it. Your existing administrator keeps working either way — the secret only seeds a database that has no administrator yet.
2

Drop the removed keys from your values

Remove admin.username and admin.password, and set admin.secretName instead. Leave users and the storage block as they are.
3

Upgrade the release

Run cpln helm upgrade with --version 1.1.0 and your updated values, as described in the CLI guide. In scale_to_zero mode an upgrade wakes a suspended server; it suspends again after the next connection comes and goes.

Changing Credentials

  • Administrator password — change it in the web admin or through the REST API. Editing the admin secret has no effect on an install that has already booted.
  • SFTP user passwords and keys — edit users in your values and run cpln helm upgrade, then force a redeployment of RELEASE_NAME-sftpgo (in scale_to_zero mode the change applies at the next wake). The declared-users file is re-applied when SFTPGo restarts, and the upgrade alone does not restart it.
  • S3-compatible access keys — edit storage.minio.accessKey and storage.minio.accessSecret and run cpln helm upgrade, then force a redeployment of RELEASE_NAME-sftpgo (in scale_to_zero mode the change applies at the next wake).

Switching Modes

Changing mode on a live install moves the client-facing endpoint between RELEASE_NAME-sftpgo-proxy and RELEASE_NAME-sftpgo, so the public address changes. Plan a client cutover, and read the new address from status.endpoint as shown in Connecting.

Scaling and Availability

The template runs one SFTPGo replica and exposes no replica count. A restart, upgrade or reschedule interrupts SFTP sessions until the replica is back; files already in the bucket are unaffected. Scale vertically with resources — CPU governs transfer throughput and how quickly a suspended server wakes. In scale_to_zero mode, all SFTP traffic flows through the proxy, so raise scaleToZero.proxy.resources for heavy transfer volumes.

Troubleshooting

Symptom: cpln helm install succeeded, but SFTPGo never starts and cpln logs '{gvc="GVC_NAME", workload="RELEASE_NAME-sftpgo"}' --limit 50 --since 10m returns no lines at all.Cause: The admin secret named by admin.secretName does not exist, so the container is never started. The deployment message names it:
Fix: Create the secret as shown in Prerequisites. The deployment recovers on its own after several minutes, or immediately with cpln workload force-redeployment RELEASE_NAME-sftpgo --gvc GVC_NAME.
Symptom: The install stops at render time with sftpgo: every users[] entry requires a username, or with sftpgo: user 'NAME' needs a password or at least one entry in publicKeys.Cause: Setting users[0].password alone with --set replaces the default user list, dropping its username. Or a user has neither a password nor a public key.Fix: Pass --set 'users[0].username=...' alongside the password, or define users in a values file with a password or publicKeys for every entry.
Symptom: The upgrade stops at render time naming admin.username or admin.password, and no revision is created.Cause: Your values still carry a key that 1.1.0 removed.Fix: Follow the steps under Upgrading from 1.0.0 above.
Symptom: The install or upgrade stops with sftpgo: mode 'scale_to_zero' requires internalAccess.type other than 'none'.Cause: The proxy reaches SFTPGo over the GVC network, which internalAccess.type: none forbids.Fix: Use same-gvc, same-org or workload-list (the proxy is added to the list automatically), or switch to mode: always_warm.
Symptom: In scale_to_zero mode the first connection after a quiet period fails with a timeout, and a retry a little later connects at once.Cause: SFTPGo was suspended and the client gave up while it woke.Fix: Raise the client’s connect and banner timeouts to 120 seconds or add retries, as described under Client Timeouts in Scale to Zero Mode. For clients you cannot configure, use mode: always_warm.
Symptom: A password, key or permission edited in the web admin is back to its old value after a restart or wake.Cause: That user is declared in users, and the declared list is re-applied every time SFTPGo starts.Fix: Change declared users in your values and run cpln helm upgrade, then force a redeployment of RELEASE_NAME-sftpgo (in scale_to_zero mode the change applies at the next wake). Or manage that user only through the web admin by removing it from users.
Symptom: http://localhost:8080 does not load through the port-forward, or the public endpoint does not serve the web admin.Cause: webAdmin.enabled is false, so port 8080 is not declared; or SFTPGo is suspended in scale_to_zero mode. The public endpoint serves SFTP on port 2022 only.Fix: Set webAdmin.enabled: true, connect once over SFTP to wake the server if needed, and use cpln port-forward RELEASE_NAME-sftpgo 8080:8080 --gvc GVC_NAME.

Important Notes

  • Create the admin secret before installing. A missing secret wedges the deployment silently; cpln workload get-deployments names it.
  • Change or remove the default users[].password. It is used exactly as written and stays a Helm value; prefer publicKeys.
  • The admin secret seeds the first boot only. Change an existing administrator’s password in the web admin or REST API.
  • Declared users are authoritative. Web admin edits to them are overwritten on the next restart or wake.
  • scale_to_zero clients need generous timeouts. Use 120-second timeouts or retries, or choose always_warm.
  • Switching modes changes the public SFTP address. Plan a client cutover.
  • The SFTPGo image has no shell. cpln workload exec and cpln workload connect cannot run commands in it; use cpln logs and the web admin.

External References

SFTPGo Documentation

Official SFTPGo documentation

S3 Storage Backend

SFTPGo S3-compatible storage backend guide

Environment Variables

SFTPGo environment variables reference

Scale-to-Zero Proxy

Source for the always-on TCP activator proxy

SFTPGo Template

View the source files, default values, and chart definition