Overview
SFTPGo is an SFTP server whose storage backend is object storage rather than a disk. Clients speak standard SFTP on port2022; 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.
--gvc GVC_NAME at install time.What Gets Created
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.
Create the admin credentials secret
username and password:admin.secretName to the name you used.Read it back later
-o yaml; a bare cpln secret reveal prints only a summary table, not the values:Object Storage
Choose a backend withstorage.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.
- AWS S3
- Google Cloud Storage
- S3-compatible
Create a bucket
storage.aws.bucket to its name and storage.aws.region to its region.Create a cloud account
storage.aws.cloudAccountName to its name.Create a bucket-scoped IAM policy
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: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
CLI
Terraform
Pulumi
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
image, stay on the same drakkan/sftpgo distroless image family.
Admin
admin.secretName empty.
Storage Backend
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 inpublicKeys, or both. - Each user is confined to the bucket folder
{keyPrefix}{username}/, wherekeyPrefixis the backend’s bucket-wide prefix; a per-userkeyPrefixreplaces that folder entirely. users[].passwordis 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 thechange-me-sftp-userdefault, or better, omitpasswordand usepublicKeys, 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
Reaching the Web Admin
The public endpoint is a raw TCP address on port2022, 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:
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
Inscale_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.idleHoldafter the last connection, so the retry connects immediately.
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:Restoring a Backup
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
Version1.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.
Create the admin credentials secret
Drop the removed keys from your values
admin.username and admin.password, and set admin.secretName instead. Leave users and the storage block as they are.Upgrade the release
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
usersin your values and runcpln helm upgrade, then force a redeployment ofRELEASE_NAME-sftpgo(inscale_to_zeromode 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.accessKeyandstorage.minio.accessSecretand runcpln helm upgrade, then force a redeployment ofRELEASE_NAME-sftpgo(inscale_to_zeromode the change applies at the next wake).
Switching Modes
Changingmode 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 withresources — 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
Deployment never starts and cpln logs returns nothing
Deployment never starts and cpln logs returns nothing
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:cpln workload force-redeployment RELEASE_NAME-sftpgo --gvc GVC_NAME.Install fails saying every users entry requires a username
Install fails saying every users entry requires a username
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.Upgrade fails saying admin.password was removed in 1.1.0
Upgrade fails saying admin.password was removed in 1.1.0
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.Render fails with mode scale_to_zero requires internalAccess.type other than none
Render fails with mode scale_to_zero requires internalAccess.type other than none
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.SFTP client times out on the first connection after idle
SFTP client times out on the first connection after idle
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.Changes made to a user in the web admin are reverted
Changes made to a user in the web admin are reverted
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.Web admin is unreachable
Web admin is unreachable
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-deploymentsnames it. - Change or remove the default
users[].password. It is used exactly as written and stays a Helm value; preferpublicKeys. - 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_zeroclients need generous timeouts. Use 120-second timeouts or retries, or choosealways_warm.- Switching modes changes the public SFTP address. Plan a client cutover.
- The SFTPGo image has no shell.
cpln workload execandcpln workload connectcannot run commands in it; usecpln logsand the web admin.