SSH Connections¶
aiodocker supports connecting to remote Docker hosts over SSH using the ssh:// URL scheme. This feature requires the asyncssh library and follows the same security principles as docker-py.
The SSH connector uses docker system dial-stdio to communicate with the remote Docker daemon, which automatically discovers and uses the correct socket path on the remote host. This works seamlessly with standard Docker installations, rootless Docker, and custom socket configurations without requiring manual socket path specification.
Installation¶
Install aiodocker with SSH support:
pip install aiodocker[ssh]
Basic Usage¶
Connect to a remote Docker host using an SSH URL:
import asyncio
import aiodocker
async def main():
# Connect to Docker over SSH
async with aiodocker.Docker(url="ssh://user@remote-host:22") as docker:
# Use Docker API normally
version = await docker.version()
print(f"Docker version: {version['Version']}")
# List containers
containers = await docker.containers.list()
for container in containers:
print(f"Container: {container['Names'][0]}")
if __name__ == "__main__":
asyncio.run(main())
URL Format¶
SSH URLs follow this format:
ssh://[user[:password]@]host[:port]
Examples:
ssh://ubuntu@host:22- Connect to host on port 22ssh://ubuntu@host- Connect using default SSH port (22)ssh://dockeruser@production.example.com:2222- Custom port
Note on Socket Paths:
Unlike traditional SSH port forwarding approaches, aiodocker uses docker system dial-stdio which automatically discovers the correct Docker socket on the remote host. Socket paths in URLs (e.g., ssh://user@host///var/run/docker.sock) are accepted for backward compatibility but are ignored.
This automatic discovery means the connector works correctly with:
Standard Docker installations (
/var/run/docker.sock)Rootless Docker (
/run/user/1000/docker.sock)Custom socket paths configured in the remote Docker daemon
Docker contexts on the remote host
Authentication¶
SSH Key Authentication (Recommended)¶
The preferred method is SSH key authentication:
# Automatic key discovery from ~/.ssh/config
async with aiodocker.Docker(url="ssh://ubuntu@host:22") as docker:
containers = await docker.containers.list()
# Specify custom key file
from aiodocker.ssh import SSHConnector
connector = SSHConnector(
"ssh://ubuntu@host:22",
client_keys=["~/.ssh/docker_key"]
)
async with aiodocker.Docker(connector=connector) as docker:
containers = await docker.containers.list()
Password Authentication (Discouraged)¶
Passwords can be included in URLs but this is not recommended for security reasons:
# Warning: Password will be stored in memory and may appear in logs
async with aiodocker.Docker(url="ssh://ubuntu:password@host:22") as docker:
containers = await docker.containers.list()
Host Key Verification¶
By default, aiodocker enforces strict host key verification for security. The remote host must be present in ~/.ssh/known_hosts.
Adding Host Keys¶
Add the remote host to your known hosts file:
# Method 1: Connect manually to add host key
ssh ubuntu@remote-host
# Method 2: Add host key directly
ssh-keyscan -H remote-host >> ~/.ssh/known_hosts
# Method 3: Copy from another trusted machine
scp trusted-machine:~/.ssh/known_hosts ~/.ssh/known_hosts
Relaxing Host Key Verification¶
For testing environments only, you can disable strict host key checking:
from aiodocker.ssh import SSHConnector
# WARNING: Only for testing - vulnerable to man-in-the-middle attacks
connector = SSHConnector(
"ssh://ubuntu@test-host:22",
strict_host_keys=False
)
async with aiodocker.Docker(connector=connector) as docker:
containers = await docker.containers.list()
SSH Configuration¶
aiodocker automatically reads SSH configuration from ~/.ssh/config when the paramiko library is available.
Example SSH config:
Host docker-prod
HostName production.example.com
User dockeruser
Port 2222
IdentityFile ~/.ssh/docker_prod_key
UserKnownHostsFile ~/.ssh/known_hosts_prod
Host docker-staging
HostName staging.example.com
User ubuntu
Port 22
IdentityFile ~/.ssh/docker_staging_key
Usage with SSH config:
# Automatically uses settings from ~/.ssh/config
async with aiodocker.Docker(url="ssh://docker-prod") as docker:
containers = await docker.containers.list()
Advanced Configuration¶
Custom SSH Options¶
Pass additional SSH options directly to the underlying asyncssh connection:
from aiodocker.ssh import SSHConnector
connector = SSHConnector(
"ssh://ubuntu@host:22",
# Custom SSH options
compression=True,
keepalive_interval=30,
known_hosts="/custom/path/known_hosts"
)
async with aiodocker.Docker(connector=connector) as docker:
containers = await docker.containers.list()
Connection Reuse¶
For better performance, reuse the same connector across multiple Docker instances:
from aiodocker.ssh import SSHConnector
# Create connector once
connector = SSHConnector("ssh://ubuntu@host:22")
# Reuse across multiple Docker instances
async with aiodocker.Docker(connector=connector) as docker1:
containers = await docker1.containers.list()
async with aiodocker.Docker(connector=connector) as docker2:
images = await docker2.images.list()
# Clean up when done
await connector.close()
Security Considerations¶
The SSH implementation follows security best practices:
Environment Sanitization¶
Potentially dangerous environment variables are automatically removed from SSH connections:
LD_LIBRARY_PATHSSL_CERT_FILESSL_CERT_DIRPYTHONPATH
Credential Protection¶
Passwords are cleared from memory after successful connection
Error messages sanitize credential information to prevent leakage
Log messages are filtered to avoid password exposure
Secure Temporary Files¶
Local socket files are created in secure temporary directories with restricted permissions (mode 0700), ensuring only the current user can access them.
Troubleshooting¶
Common Issues¶
“Host key verification failed”
Add the host to your known hosts file:
ssh-keyscan -H hostname >> ~/.ssh/known_hosts
“Permission denied (publickey)”
Ensure your SSH key is properly configured:
ssh-add ~/.ssh/your_key
ssh ubuntu@hostname # Test SSH connection manually
“Connection refused”
Verify the SSH service is running and accessible:
telnet hostname 22
Debugging¶
Enable debug logging to troubleshoot connection issues:
import logging
logging.basicConfig(level=logging.DEBUG)
async with aiodocker.Docker(url="ssh://ubuntu@host:22") as docker:
containers = await docker.containers.list()
Requirements¶
asyncssh >= 2.14.0(installed automatically withaiodocker[ssh])SSH access to the remote Docker host
Docker CLI (
dockercommand) available on the remote host (required fordocker system dial-stdio)Docker daemon running and accessible on the remote host