Skip to content

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.

Notifications You must be signed in to change notification settings

optimode/openssh

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:bookworm
    container_name: openssh
    restart: unless-stopped
    ports:
      - "2222:2222"
    volumes:
      - ./config:/app
      - ./workspace:/workspace
    environment:
      - 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

Variable Default Description
USER_NAME app Username for SSH access
PUID 911 User ID (useful for matching host user permissions)
PGID 911 Group ID (useful for matching host group permissions)
USER_HOME /app User home directory
USER_PASSWORD <random> User password (auto-generated if not set)
USER_PASSWORD_FILE - Path to file containing password (Docker secrets)

SSH Configuration

Variable Default Description
LISTEN_PORT 2222 SSH server listening port
PASSWORD_ACCESS false Enable/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

Variable Default Description
SUDO_ACCESS false Grant sudo privileges to the user
UMASK 022 Default umask for file creation

System Configuration

Variable Default Description
TZ UTC Timezone (e.g., Europe/Budapest, America/New_York)

Volume Mounts

Path Purpose
/app Required - Persistent storage for SSH config, host keys, and user data
/workspace Optional - Additional workspace directory

Ports

Port Protocol Description
2222 TCP SSH 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.pub
volumes:
  - ./my-key.pub:/secrets/ssh-key.pub:ro

Method 4: Key Directory

environment:
  - PUBLIC_KEY_DIR=/secrets/keys
volumes:
  - ./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:bookworm
    container_name: devssh
    ports:
      - "2222:2222"
    volumes:
      - ./config:/app
      - ./projects:/workspace
      - /var/run/docker.sock:/var/run/docker.sock  # Docker-in-Docker
    environment:
      - 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:bookworm
    container_name: openssh-pass
    ports:
      - "2222:2222"
    volumes:
      - ./config:/app
    environment:
      - USER_NAME=testuser
      - USER_PASSWORD=SecurePassword123
      - PASSWORD_ACCESS=true
      - SUDO_ACCESS=false

Example 3: Multiple Users with Docker Secrets

services:
  openssh:
    image: optimode/openssh:bookworm
    container_name: openssh-secure
    ports:
      - "2222:2222"
    volumes:
      - ./config:/app
    secrets:
      - ssh_password
    environment:
      - USER_NAME=admin
      - USER_PASSWORD_FILE=/run/secrets/ssh_password
      - PASSWORD_ACCESS=true

secrets:
  ssh_password:
    file: ./secrets/password.txt

Example 4: Custom Port and Timezone

services:
  openssh:
    image: optimode/openssh:bookworm
    container_name: openssh-custom
    ports:
      - "2200:2200"
    volumes:
      - ./config:/app
    environment:
      - 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

Watchers

Forks

Packages