Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

4 Commits

Repository files navigation

OpenSSH Docker Image

A production-ready OpenSSH server Docker image based on Debian Bookworm, designed for secure remote access, development environments, and CI/CD pipelines.

Features

  • Secure by Default: Password authentication disabled, public key authentication preferred
  • Flexible User Management: Customizable UID/GID for seamless host volume permissions
  • Persistent Configuration: All configs and host keys stored in /app volume
  • Development Tools: Includes git, golang, curl, wget, and common utilities
  • Timestamped Logging: Built-in log management with timestamps
  • Easy SSH Key Management: Multiple ways to inject public keys
  • Optional Sudo Access: Configurable sudo permissions
  • Small Footprint: Based on Debian Bookworm Slim

Quick Start

Using Docker Run

# Pull the image
docker pull ghcr.io/optimode/openssh:bookworm
# Create config directory
mkdir -p ./config/.ssh
# Add your SSH public key
cat ~/.ssh/id_rsa.pub > ./config/.ssh/authorized_keys
# Run the container
docker run -d \
--name openssh \
-p 2222:2222 \
-v ./config:/app \
-e USER_NAME=devuser \
-e PUID=1000 \
-e PGID=1000 \
ghcr.io/optimode/openssh:bookworm
# Connect
ssh -p 2222 devuser@localhost

Using Docker Compose

Create a docker-compose.yml file:

services:
openssh:
image: ghcr.io/optimode/openssh:bookwormcontainer_name: opensshrestart: unless-stoppedports:
- "2222:2222"volumes:
- ./config:/app
- ./workspace:/workspaceenvironment:
- TZ=Europe/Budapest
- PUID=1000
- PGID=1000
- USER_NAME=devuser
- SUDO_ACCESS=false
- PASSWORD_ACCESS=false

Then run:

# Add your SSH public key
mkdir -p ./config/.ssh
cat ~/.ssh/id_rsa.pub > ./config/.ssh/authorized_keys
# Start the container
docker-compose up -d
# Connect
ssh -p 2222 devuser@localhost

Configuration

Environment Variables

User Configuration

VariableDefaultDescription
USER_NAMEappUsername for SSH access
PUID911User ID (useful for matching host user permissions)
PGID911Group ID (useful for matching host group permissions)
USER_HOME/appUser home directory
USER_PASSWORD<random>User password (auto-generated if not set)
USER_PASSWORD_FILE-Path to file containing password (Docker secrets)

SSH Configuration

VariableDefaultDescription
LISTEN_PORT2222SSH server listening port
PASSWORD_ACCESSfalseEnable/disable password authentication
PUBLIC_KEY-SSH public key (single key as string)
PUBLIC_KEY_FILE-Path to file containing a public key
PUBLIC_KEY_DIR-Path to directory containing multiple key files

Access Control

VariableDefaultDescription
SUDO_ACCESSfalseGrant sudo privileges to the user
UMASK022Default umask for file creation

System Configuration

VariableDefaultDescription
TZUTCTimezone (e.g., Europe/Budapest, America/New_York)

Volume Mounts

PathPurpose
/appRequired - Persistent storage for SSH config, host keys, and user data
/workspaceOptional - Additional workspace directory

Ports

PortProtocolDescription
2222TCPSSH server port (configurable via LISTEN_PORT)

SSH Key Management

There are multiple ways to provide SSH public keys for authentication:

Method 1: Authorized Keys File (Recommended)

mkdir -p ./config/.ssh
cat ~/.ssh/id_rsa.pub > ./config/.ssh/authorized_keys
chmod 600 ./config/.ssh/authorized_keys

Method 2: Environment Variable

environment:
- PUBLIC_KEY=ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB...

Method 3: Key File

environment:
- PUBLIC_KEY_FILE=/secrets/ssh-key.pubvolumes:
- ./my-key.pub:/secrets/ssh-key.pub:ro

Method 4: Key Directory

environment:
- PUBLIC_KEY_DIR=/secrets/keysvolumes:
- ./keys:/secrets/keys:ro

Multiple methods can be used simultaneously - all keys will be added to authorized_keys.

Advanced Usage Examples

Example 1: Development Environment with Sudo

services:
devssh:
image: optimode/openssh:bookwormcontainer_name: devsshports:
- "2222:2222"volumes:
- ./config:/app
- ./projects:/workspace
- /var/run/docker.sock:/var/run/docker.sock # Docker-in-Dockerenvironment:
- USER_NAME=developer
- PUID=1000
- PGID=1000
- SUDO_ACCESS=true
- PASSWORD_ACCESS=false
- TZ=America/New_York

Example 2: Password Authentication Enabled

services:
openssh:
image: optimode/openssh:bookwormcontainer_name: openssh-passports:
- "2222:2222"volumes:
- ./config:/appenvironment:
- USER_NAME=testuser
- USER_PASSWORD=SecurePassword123
- PASSWORD_ACCESS=true
- SUDO_ACCESS=false

Example 3: Multiple Users with Docker Secrets

services:
openssh:
image: optimode/openssh:bookwormcontainer_name: openssh-secureports:
- "2222:2222"volumes:
- ./config:/appsecrets:
- ssh_passwordenvironment:
- USER_NAME=admin
- USER_PASSWORD_FILE=/run/secrets/ssh_password
- PASSWORD_ACCESS=truesecrets:
ssh_password:
file: ./secrets/password.txt

Example 4: Custom Port and Timezone

services:
openssh:
image: optimode/openssh:bookwormcontainer_name: openssh-customports:
- "2200:2200"volumes:
- ./config:/appenvironment:
- LISTEN_PORT=2200
- USER_NAME=sshuser
- TZ=Asia/Tokyo
- PUID=1001
- PGID=1001

Building from Source

# Clone the repository
git clone https://github.com/optimode/docker-openssh.git
cd docker-openssh
# Build the image
./build
# Or use docker build directly
docker build -t optimode/openssh:bookworm .

Directory Structure in Container

/app/
├── .ssh/
│ └── authorized_keys # SSH public keys
├── sshd/
│ └── sshd_config # OpenSSH server configuration
├── ssh_host_keys/ # Persistent host keys
└── logs/
└── openssh/
└── sshd.log # SSH server logs with timestamps

Logging

Logs are stored in /app/logs/openssh/sshd.log with timestamps in format [YYYY-MM-DD HH:MM:SS TZ].

View logs:

# Real-time logs
docker logs -f openssh
# Persistent log file
docker exec openssh tail -f /app/logs/openssh/sshd.log

Troubleshooting

Connection Refused

Problem: Cannot connect to SSH server

Solutions:

  • Check if container is running: docker ps
  • Verify port mapping: docker port openssh
  • Check firewall rules on host
  • Verify SSH service is running: docker exec openssh ps aux | grep sshd

Permission Denied (publickey)

Problem: Authentication fails with public key

Solutions:

  • Verify key is in authorized_keys: docker exec openssh cat /app/.ssh/authorized_keys
  • Check key permissions: Should be 600 for authorized_keys, 700 for .ssh
  • Ensure the correct private key is being used: ssh -i ~/.ssh/id_rsa -p 2222 user@localhost
  • Check logs: docker logs openssh

Permission Issues with Volumes

Problem: Files in mounted volumes have wrong ownership

Solutions:

  • Set PUID and PGID to match your host user:
    id -u # Get your UID
    id -g # Get your GID
  • Update docker-compose.yml with correct values
  • Restart container: docker-compose down && docker-compose up -d

Can't Write to Workspace

Problem: User cannot write to /workspace directory

Solutions:

  • Ensure proper ownership of host directory:
    sudo chown -R 1000:1000 ./workspace # Use your PUID:PGID
  • Or set permissions to allow write access:
    chmod -R 755 ./workspace

Sudo Not Working

Problem: Sudo commands fail despite SUDO_ACCESS=true

Solutions:

  • Verify environment variable is set: docker exec openssh env | grep SUDO
  • Check sudoers file: docker exec openssh cat /etc/sudoers | grep app
  • If password required, ensure USER_PASSWORD is set
  • Restart container after changing SUDO_ACCESS

Security Considerations

  1. Disable Password Authentication: Always use key-based authentication in production
  2. Use Strong Keys: Generate keys with ssh-keygen -t ed25519 or ssh-keygen -t rsa -b 4096
  3. Limit Sudo Access: Only enable SUDO_ACCESS=true when necessary
  4. Firewall Rules: Restrict SSH port access to known IPs
  5. Regular Updates: Keep the image updated for security patches
  6. Monitor Logs: Regularly check /app/logs/openssh/sshd.log for suspicious activity
  7. Use Docker Secrets: For sensitive data like passwords, use Docker secrets instead of environment variables

Version Information

  • Base Image: debian:bookworm-slim
  • OpenSSH Version: 8.4+
  • Exposed Port: 2222 (default)

License

MIT License - See LICENSE file for details

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Author

Optimode (Laszlo Malina)

Links

About

Secure OpenSSH Docker container on Debian. Flexible user management (UID/GID), persistent configs, key-based auth, optional sudo, dev tools included. Ideal for development environments, remote access, and CI/CD pipelines.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Packages

Contributors

Languages