This guide explains how to set up and manage SFTP servers using Docker. It covers everything from quick, basic setups for local testing to more advanced, secure, and customizable servers for production environments using Docker Compose.
Verify Docker installation:
docker --version
docker-compose --version
This method is quick for local testing using the pre-built atmoz/sftp image.
docker pull atmoz/sftp
docker run -p 2222:22 -d atmoz/sftp testuser1:password123:::upload
-p 2222:22 maps host port 2222 to container SSH port 22.testuser1:password123:::upload creates testuser1 with password123 and a home directory containing an upload folder.sftp -P 2222 testuser1@localhost
This also uses the pre-built image for quick local testing with SSH keys.
ssh-keygen -t rsa -b 4096 -f ~/.ssh/sftp_test_key
# Create the directory structure
mkdir -p ~/sftp_key_auth/testuser2
# Copy your public key
cp ~/.ssh/sftp_test_key.pub ~/sftp_key_auth/testuser2/authorized_keys
docker run --platform linux/amd64 -p 2225:22 -d \
-v ~/sftp_key_auth/testuser2/authorized_keys:/home/testuser2/.ssh/authorized_keys:ro \
atmoz/sftp testuser2::::
testuser2:::: creates user testuser2 without a password for key-only login.-v flag mounts your public key, granting access.sftp -i ~/.ssh/sftp_test_key -P 2225 testuser2@localhost
docker run -p 2223:22 -d atmoz/sftp userA:passA:::upload
docker run -p 2224:22 -d atmoz/sftp userB:passB:::upload
docker run -p 2222:22 -d atmoz/sftp \
user1:pass1:::dir1 \
user2:pass2:::dir2
This section details how to build a custom, secure SFTP server using your own Dockerfile and docker-compose.yml. This provides much more control and is the recommended approach for a real server.
This is the most secure and recommended setup. It disables passwords entirely and relies only on SSH keys.
Create a project directory with the following files:
/sftp_key_only/
├── docker-compose.yml
├── Dockerfile
└── authorized_keys
This file builds a custom Ubuntu image with an SSH server configured for key-only authentication.
File: Dockerfile
FROM ubuntu:22.04
# Install SSH server and create sshd directory
RUN apt-get update && \
apt-get install -y openssh-server && \
mkdir /var/run/sshd
# Create a user for SFTP access
ARG USERNAME=sftpuser
RUN useradd -m -s /bin/bash $USERNAME
# Disable password authentication for security
RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config && \
sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
# Configure SFTP by appending settings to sshd_config
RUN echo "Match User $USERNAME" >> /etc/ssh/sshd_config && \
echo " ForceCommand internal-sftp" >> /etc/ssh/sshd_config && \
echo " PasswordAuthentication no" >> /etc/ssh/sshd_config && \
echo " ChrootDirectory /home/$USERNAME/data" >> /etc/ssh/sshd_config && \
echo " AllowTcpForwarding no" >> /etc/ssh/sshd_config && \
echo " X11Forwarding no" >> /etc/ssh/sshd_config
# Create .ssh directory for key-based authentication
RUN mkdir -p /home/$USERNAME/.ssh && \
chown -R $USERNAME:$USERNAME /home/$USERNAME/.ssh && \
chmod 700 /home/$USERNAME/.ssh
# Expose SSH port and start the server
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]
This file runs your server, mapping ports and mounting volumes for keys and data.
File: docker-compose.yml
version: '3.0'
services:
sftp:
build:
context: .
args:
USERNAME: sftpuser
container_name: my-sftp-key-only-server
ports:
# Map host port 2223 to the container's SSH port 22
- "2223:22"
volumes:
# Mount the authorized_keys file from the host (read-only)
- ./authorized_keys:/home/sftpuser/.ssh/authorized_keys:ro
# Mount a directory for user data
- ./sftp_data:/home/sftpuser/data
ssh-keygen -t rsa -b 4096 -f ~/.ssh/prod_sftp_key
~/.ssh/prod_sftp_key.pub) and paste it into the authorized_keys file on your server.# Create and set ownership for the data directory
mkdir -p sftp_data
sudo chown 1001:1001 sftp_data # UID 1001 for the created sftpuser
# Set ownership and strict permissions for the key file
sudo chown 1001:1001 authorized_keys
sudo chmod 600 authorized_keys
2223.docker-compose up -d --buildsftp -i ~/.ssh/prod_sftp_key -P 2223 sftpuser@YOUR_SERVER_IP
This setup requires three distinct factors for authentication:
This provides a robust, multi-layered security approach, ensuring that only users with the correct key and password can access the SFTP server.
/sftp_multifactor/
├── docker-compose.yml
├── Dockerfile
└── authorized_keys
This Dockerfile creates a user, sets a password passed in during the build process, and configures SSH to require both public key and password authentication.
File: Dockerfile
FROM ubuntu:22.04
# Install SSH server
RUN apt-get update && \
apt-get install -y openssh-server && \
mkdir /var/run/sshd
# Create user and set password from build argument
ARG USERNAME=multifactoruser
ARG PASSWORD=DefaultPasswordChangeMe!
RUN useradd -m -s /bin/bash $USERNAME && \
echo "$USERNAME:$PASSWORD" | chpasswd
# --- SSH Configuration for Multi-Factor Authentication ---
# 1. Ensure PubkeyAuthentication is enabled
RUN sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
# 2. Ensure PasswordAuthentication is enabled
RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
RUN sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
# 3. Require both authentication methods
RUN echo "\n# --- Custom Multi-Factor Auth Settings ---" >> /etc/ssh/sshd_config
RUN echo "AuthenticationMethods publickey,password" >> /etc/ssh/sshd_config
# Create .ssh directory for key mounting
RUN mkdir -p /home/$USERNAME/.ssh && \
chown -R $USERNAME:$USERNAME /home/$USERNAME/.ssh && \
chmod 700 /home/$USERNAME/.ssh
# Expose SSH port and start the server
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]
The docker-compose.yml file passes the username and password as build arguments, maps a host port, and mounts the necessary volumes.
File: docker-compose.yml
version: '3.0'
services:
sftp-multifactor:
build:
context: .
args:
USERNAME: multifactoruser
PASSWORD: YourSuperStrongPassword123! # <<< CHANGE THIS PASSWORD
container_name: my-sftp-multifactor-server
ports:
- "2224:22" # Mapped to host port 2224
volumes:
- ./authorized_keys:/home/multifactoruser/.ssh/authorized_keys:ro
- ./sftp_data:/home/multifactoruser/data
restart: unless-stopped
ssh-keygen -t rsa -b 4096 -f ~/.ssh/sftp_mfa_key
~/.ssh/sftp_mfa_key.pub) and paste it into the authorized_keys file in your project directory (sftp_multifactor/authorized_keys).PASSWORD in your docker-compose.yml file (under sftp-multifactor service, args section) to a strong, unique password.# Create and set ownership for the data directory
mkdir -p sftp_data
sudo chown 1000:1000 sftp_data # UID 1000 for the created multifactoruser
# Set ownership and strict permissions for the key file
sudo chown 1000:1000 authorized_keys
sudo chmod 600 authorized_keys
2224.docker-compose up -d --buildsftp -i ~/.ssh/sftp_mfa_key -P 2224 multifactoruser@YOUR_SERVER_IP
You will be prompted for your SSH key passphrase (if any) and then for the user’s password.
Once you are connected and see the sftp> prompt, use these commands.
| Command | Description | Example |
|---|---|---|
put |
Upload a single file from local to remote. | put local_file.txt |
get |
Download a single file from remote to local. | get remote_file.txt |
mput |
Upload multiple files (use with wildcards). | mput *.jpg |
mget |
Download multiple files (use with wildcards). | mget *.pdf |
put -r |
Upload a directory and its contents. | put -r local_directory |
get -r |
Download a directory and its contents. | get -r remote_directory |
ls |
List files in the remote directory. | ls -l |
lls |
List files in the local directory. | lls -l |
cd |
Change the remote directory. | cd /data/uploads |
lcd |
Change the local directory. | lcd ~/Documents |
rm |
Delete a remote file. | rm old_file.log |
mkdir |
Create a remote directory. | mkdir new_folder |
pwd |
Show the current remote directory path. | pwd |
lpwd |
Show the current local directory path. | lpwd |
exit |
Disconnect from the server. | exit |
localhost2222, 2223).Key file.Interactive (FileZilla will ask for both key and password).sftpuser, hybriduser, etc.).