Deploy SFTP Gateway as a container
Overview
In this article we'll walk through deploying SFTP Gateway as a containerized application. This involves downloading a zip file containing our backend & admin-ui docker images, and loading them into your local docker image list, which we then use to create a new SFTP Gateway deployment using a custom docker compose file.
Afterwards, you're able to access your deployment by navigating to your web browser and creating your initial Web Admin account.
These instructions were written working with Docker Desktop. Download and install Docker Desktop from the official Docker website: Docker Desktop Download
Create local docker image
The first step involves downloading our docker image zip files in the form of an S3 link.
SFTP Gateway backend
image zip file:
https://sftpgateway-container-beta.s3.us-east-1.amazonaws.com/sftpgw-docker-images-version-3.8.0-snapshot.202508300318/sftpgateway-backend.tar.gz
SFTP Gateway admin-ui
image zip file:
https://sftpgateway-container-beta.s3.us-east-1.amazonaws.com/sftpgw-docker-images-version-3.8.0-snapshot.202508300318/sftpgateway-admin-ui.tar.gz
Once you've downloaded the zip files, using the command line/terminal, load them into your docker image list using the following commands:
# Load backend image
gzip -dc sftpgateway-backend.tar.gz | docker load
# Load admin UI image
gzip -dc sftpgateway-admin-ui.tar.gz | docker load
Verify that these images are pulled into your local docker:
docker image list
Create docker compose file
Now that the images are loaded into docker, the next step is to create the docker compose file to bring everything together.
create a YAML file named docker-compose.yml
on your local machine:
version: '3.8'
services:
db:
container_name: sftpgw_container_db
image: postgres:16-alpine
environment:
POSTGRES_DB: sftpgw
POSTGRES_USER: sftpgw
POSTGRES_PASSWORD: sftpgw
PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_INITDB_ARGS: "--data-checksums"
POSTGRES_LOGGING: "on"
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5455:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U sftpgw -d sftpgw"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- sftpgw-network
backend:
container_name: backend
image: 115784076403.dkr.ecr.us-east-1.amazonaws.com/sftpgateway/sftpgateway-backend:3.8.0-snapshot.202508300318.uncommitted-03104f4-20250830033445
depends_on:
db:
condition: service_healthy
environment:
SPRING_PROFILES_ACTIVE: local
LOGGING_LEVEL_ROOT: INFO
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/sftpgw
SPRING_DATASOURCE_USERNAME: sftpgw
SPRING_DATASOURCE_PASSWORD: sftpgw
SECURITY_CLIENT_ID: 1234
SECURITY_CLIENT_SECRET: 1234
SECURITY_JWT_SECRET: b03c367c-a16c-4a43-9d47-8ff73462179e
SERVER_PORT: 8080
HOME: /home/sftpgw
JAVA_OPTS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
volumes:
- sftpgw_home:/home/sftpgw
ports:
- "8080:8080"
- "22:22"
- "5005:5005"
networks:
- sftpgw-network
user: "sftpgw"
working_dir: /opt/sftpgw
restart: unless-stopped
ui:
container_name: sftpgw-ui
image: 115784076403.dkr.ecr.us-east-1.amazonaws.com/sftpgateway/sftpgateway-admin-ui:3.8.0-snapshot.202508300318.uncommitted-03104f4-20250830033445
environment:
BACKEND_URL: http://backend:8080/
SECURITY_CLIENT_ID: 1234
SECURITY_CLIENT_SECRET: 1234
WEBSITE_BUNDLE_CRT: |
-----BEGIN CERTIFICATE-----
MIID4zCCAsugAwIBAgIUd2Q6F9G4dGxIqLd8cS6ltLeDpk4wDQYJKoZIhvcNAQEL
BQAwZDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
DVNhbiBGcmFuY2lzY28xFDASBgNVBAoMC0RldmVsb3BtZW50MRIwEAYDVQQDDAls
b2NhbGhvc3QwHhcNMjQxMTE3MDMwMzE4WhcNMjUxMTE3MDMwMzE4WjBkMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j
aXNjbzEUMBIGA1UECgwLRGV2ZWxvcG1lbnQxEjAQBgNVBAMMCWxvY2FsaG9zdDCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALY7NVKDdmGj0FLUY/mBjyvn
KQiF22bNxq56HTIKawjHxV70W+CBzPv2d2wNI4e4vOqTDCKOUbPKKPXX1vNu2u1l
McVQNwxR2xG4zsDj9WzX3Z782F6qmHi+hqsVbFgVdOxj4xjMOTeodwjNL2K4ylMi
Vn13M7Yj1qqPfXVRZgfcSuVmLpIadz5TAif4NhB6SBodg+jjeynGJLkS80kV13W9
bpu1JNcTFEaEB+E0RijdZ2BrUUaOaNF8wOP0Zk50v5t0M9uBfd9O0sDemzxesyWF
+pLANFkEPYiRCdn7epF1qZZer2uqbS15RhFyvfKfkZK0vx4vC/qcDKpI9CPg6t0C
AwEAAaOBjDCBiTAdBgNVHQ4EFgQUc31/aqt6ZE22MrD4JmpNZP8UNZswHwYDVR0j
BBgwFoAUc31/aqt6ZE22MrD4JmpNZP8UNZswDwYDVR0TAQH/BAUwAwEB/zAUBgNV
HREEDTALgglsb2NhbGhvc3QwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF
BwMBMA0GCSqGSIb3DQEBCwUAA4IBAQAGtPbCCjw3ckDncp3UD32X9dfDLWZnvXRi
jsZ0kpLu3O1A+AJb7HGdeV7TB13DU6DvlHfPMExI8LPaybiLbAB5yO3pIYueoacc
y6QK3s8AbtubWMROOeICBe6WVh63nzoPk3LjgyDk16Nm84VQequIGGJ3PlXZzXjZ
PVlEEPryg8s6U8iY7z/HHXse4CytMrEB9last5Z3TBgNqTT5Uiqw9zAhb4L6oHwW
zE99hgVx5G5eAVeziPY5Hy1xYY7/G6EXmdpRWI5BbJO4kKN0RFS03b8iGkgiwHvp
24Yi6PfMCT1WSNQ9OEIjsAaQIKJikH1xww46y0oEn/wc2BBCgcOO
-----END CERTIFICATE-----
WEBSITE_KEY: |
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC2OzVSg3Zho9BS
1GP5gY8r5ykIhdtmzcaueh0yCmsIx8Ve9Fvggcz79ndsDSOHuLzqkwwijlGzyij1
19bzbtrtZTHFUDcMUdsRuM7A4/Vs192e/Nheqph4voarFWxYFXTsY+MYzDk3qHcI
zS9iuMpTIlZ9dzO2I9aqj311UWYH3ErlZi6SGnc+UwIn+DYQekgaHYPo43spxiS5
EvNJFdd1vW6btSTXExRGhAfhNEYo3Wdga1FGjmjRfMDj9GZOdL+bdDPbgX3fTtLA
3ps8XrMlhfqSwDRZBD2IkQnZ+3qRdamWXq9rqm0teUYRcr3yn5GStL8eLwv6nAyq
SPQj4OrdAgMBAAECggEAJUl2puhO1fo4o2YhgblUlAFj2EJZaw7iXyuN40IV9hE4
Ta5WyViN2qVq+KE0mq3+e8n0UvLHfW/5UxpjuWI+qhIJbcv0w5DRMC5eIcJTIr8F
siUe2bny4kvrzsBer6ROTRtAKcAJ2h1eo96mGj9g6MNPKrN0EYoCP9qF63YpGCTO
zVpY7fIOxow2AHaiRlEblpRtJHMEL/DdcmxqvCvkREgjwQSWZKAL8Mu4dZKasYBy
+nNV7vIudGmTciRuWJLgLayLXFil7OJME44PIktGlBNL3UgMM/oKCTM0qp8aA9DQ
52dKWk9gI9I6mum+XnBMipQtBSFMyBHEoSb9dUytkQKBgQDonUUiz417NgO0fljE
0GvrqNzk2RrJ50KMcLB6wdJoVx037qLJkHJJUeKsJeOqJfYOQ68PnusucEvSgR5N
/69c1v5UfFASj+mVVtLaEsEEZ+MMSvYhSHq/Dlj4NdKaSkdcCxY8YoMN3fRNUTtY
o3oOQWDn+43uqe1Wabr2TMxUzQKBgQDIjT5jNo9H27bkiXUV2t+a9KmGTu2FNE9F
CtMrSAmpj+lCHPNJzwgP49KfGf+KerkZ/bslixhROXo0HXQ0Eyp+iduNmXKjEX/h
rpj+HekN/cdHyQA64Kc8qHYbN+4VgksXk1hWXovhY99bg2bEtzX9D4mFbmdArGXA
4eMNZfJuUQKBgACfAuM/6KHOmB3wRG5qHA+qCMT3q3Gkk3Hqjx4UzGoI6YQPuBGP
uC5n8JIDG+OFbG3HUn1ZMEmUdS9ftuQAbchyroUtO82A4t/KNo/sguVvHZUX0iZu
mh1OfYBULHbLAfvF785DeRQdZpyaPe1TqmzFUevsqQldHMwhRiWIOPd1AoGAYy6P
Cwvhgj0jzxQ3xm4vJXgYGqcQCk9bYJ7A3mfK94OHbT3aB8eOiiU2dZ6q5TZaMoNs
OV330bumNv3WCSbtXhUZcobPzduKrfbmDM6IAnZeRp8eMQAHVRVPC5j2csa0El25
U0WA0h/NR3nNqj2dQqCbd1SpVa+sxt4vpuGjKnECgYASiNxDdbApD6F153Y56dO1
PM17ujQ+sa0qZH+fdCKweBZ5xHN+I7VYf4zMJ630/7KWy9lwa4N8GWxNNGAEhWav
7xqWNw2UCfb5BzsztIxSL60NSnqCzqvZP7OSboFS9X6lQKQ73bWyAtQuhG5ydALz
0Bz/2SdeU40IbTl/wrpY2g==
-----END PRIVATE KEY-----
ports:
- "80:80"
- "443:443"
networks:
- sftpgw-network
restart: unless-stopped
volumes:
postgres_data:
driver: local
sftpgw_home:
driver: local
networks:
sftpgw-network:
driver: bridge
Configure the following environment variables in the backend container (Add the properties below the JAVA_OPTS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
environment variable):
If you're on Azure
you would configure the following variables:
FEATURES_FIRST_CONNECTION_CLOUD_PROVIDER: azure
FEATURES_FIRST_CONNECTION_NAME: "Blob Storage Cloud Connection"
FEATURES_FIRST_CONNECTION_BASE_PREFIX: "https://bryce.blob.core.windows.net/demo"
Note: In this example bryce
is my Storage Account and demo
is my container name.
Deploy docker container
Now that you've gotten the prerequisite docker images & docker compose file, we can deploy our docker container with the following command:
docker compose -f docker-compose.yml up -d
Note: We don't need to add the postgresql database image as docker will pull the image in automatically during the deployment.
Access your deployment
Once your container has deployed successfully, access it by navigating to this URL on a web browser: https://localhost
Setting up SFTP Gateway
After accessing the Web UI, create your initial Web Admin account & Sign in:
Even though the initial Cloud Connection is automatically configured with Blob container details, you'll need to specify valid credentials.
Here is documentation going over how to obtain the credentials for your Azure Storage Account:
Azure Storage Account Credentials - Azure Documentation for the Connection String
Once your connection has been configured and returns 3 green check marks for the Test Connection, navigate to the Users
tab and create your SFTP user (currently we've restricted the user count to 1 SFTP user):
Once created, connect with your SFTP user from an SFTP client such as FileZilla:
Upload a file to your Cloud Storage Location:
That's it, you've now successfully deployed SFTP Gateway in a containerized version and are connected to Cloud Storage.