Docker container for mounting an Object Storage bucket to an (S)FTP(S) server
To access a bucket over FTP, FTPS
A Docker container implements links between a FUSE client and servers: vsftpd
Getting started
- Create a service account.
- Add the service account to a group to grant it necessary permissions.
- Create a static access key.
Installing
-
Pull a Docker container:
docker pull cr.ai.nebius.cloud:1.0
-
Create a directory named
secrets
to store FTP server user data and bucket mounting settings:mkdir secrets
-
In the
secrets
directory:-
Create a
credentials
file:[default] aws_access_key_id = <key ID> aws_secret_access_key = <key contents>
Where:
aws_access_key_id
: ID of the static access key obtained before starting.aws_secret_access_key
: Contents of the static access key.
-
If you are going to use SFTP, create a file named
authorized_keys
with a public SSH key:ssh-ed25519 AAAAB3Nz.....BdZoeQ==
To learn how to create an SSH key pair, see the Compute Cloud documentation.
-
If you are going to use FTPS, add the
ftp.pem
TLS certificate and itsftp.key
to the folder. For example, for testing purposes, you can issue a self-signed certificate:openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout secrets/ftp.key -out secrets/ftp.pem
-
-
Create an
env.list
file with environment variables for the Docker container:<variable name>=<variable value> ...
Supported variables:
S3_BUCKET
: Bucket name to mount to the FTP server, in<bucket name>
format. This is a required variable.S3_ENDPOINT
: Object Storage endpoint, should behttps://storage.ai.nebius.cloud
. This is a required variable.SFTP
: Enables the use of SFTP. By default, it is set toYES
.FTP
: Enables the use of FTP. By default, it is set toNO
.FTP_USER
: Username for establishing a server connection. By default, it is set tos3
.FTP_PASS
: User password for establishing a server connection. By default, a random password is generated and displayed in Docker container logs.FTP_PASV_ENABLE
: Enables passive FTP connection mode. By default, it is set toYES
.FTP_PASV_MIN_PORT
: Start of the port range for passive mode. The default value is21100
.FTP_PASV_MAX_PORT
: End of the port range for passive mode. The default value is21100
.FTP_PASV_ADDRESS
: Server IP address or its domain name (if theFTP_PASV_ADDR_RESOLVE
option is selected) for passive mode. By default, the IP address specified in the Docker container's route table (theip route show
command) is used as the default route target IP address (specified in adefault via <IP address> ...
string).FTP_PASV_ADDR_RESOLVE
: Allows specifying the server domain name instead of its IP address in theFTP_PASV_ADDRESS
variable. By default, it is set toYES
.FTP_PASV_PROMISCUOUS
: Disables client IP address mapping for passive mode: a managing connection may be opened from one client address, while a connection for data exchange, from another. By default, it is set toNO
. We do not recommend disabling this check.FTP_PORT_PROMISCUOUS
: Disables client IP address mapping for active mode: when a managing connection is established, a client can specify another client's address in thePORT
command. By default, it is set toNO
. We do not recommend disabling this check.FTP_SSL_ENABLE
: Enables the use of FTPS (over TLS 1.x) instead of FTP:YES
(default): FTPS is enabled but optional. Clients can establish non-secure FTP connections to the server.FORCE
: FTPS is enabled and required. Clients can only establish secure FTPS connections to the server.NO
: FTPS is disabled.
FTP_RSA_CERT_FILE
: Path to the TLS certificate inside the Docker container. By default, it is set to/secrets/ftp.pem
.FTP_RSA_PRIVATE_KEY_FILE
: Path to the private key of the TLS certificate inside the Docker container. By default, it is set to/secrets/ftp.key
.
-
Run the Docker container:
SFTPFTP(S)docker run -d -it \ --cap-add SYS_ADMIN \ --device /dev/fuse \ --security-opt apparmor:unconfined \ --env-file env.list \ -v <full path to the secrets folder>:/secrets \ -p 1022:22 \ --name ftp \ cr.ai.nebius.cloud:1.0
The server will accept connections on port 1022.
docker run -d -it \ --cap-add SYS_ADMIN \ --device /dev/fuse \ --security-opt apparmor:unconfined \ --env-file env.list \ -v <full path to the secrets folder>:/secrets \ --expose 21 \ -p 1021:21 \ --expose 21100 \ -p 21100:21100 \ --name ftp \ cr.ai.nebius.cloud:1.0
The server will accept connections on port 1021. In addition, for passive mode (the
FTP_PASV_ENABLE
variable), port 21100 is open: if you don't use this mode, the--expose 21100
and-p 21100:21100
options aren't required.
Specifics of uploading files to a bucket
The GeeseFS client that is part of a Docker container works with files asynchronously. It caches new files and uploads them to a bucket after a while. If an FTP server connection is broken between these two points of time, uploaded files may be lost either partially or completely.
To ensure data integrity when establishing SFTP connections, use the fsync@openssh.com
extension so that file uploads are considered successful only after the fsync
system call. For example, for the sftp client that is part of OpenSSH, the extension is enabled with the -f
flag: sftp -f <server address>
. Waiting for fsync
calls slows down operations with files.