Skip to main content

Overview

SSH Portfolio can be configured using environment variables to customize runtime behavior without modifying code or rebuilding the application.

Available Environment Variables

SSH_PORT

Controls which port the SSH server listens on.
SSH_PORT
string
default:"2222"
The port number for the SSH server to bind to.
Implementation (main.go:27-29):
port := "2222"
if p := os.Getenv("SSH_PORT"); p != "" {
    port = p
}
Usage:
SSH_PORT=3000 ./ssh-portfolio

Configuration Files

In addition to environment variables, SSH Portfolio uses configuration files:

config.yaml

The application loads config.yaml from the working directory (main.go:31-34):
cfg, err := config.Load("config.yaml")
if err != nil {
    log.Fatalf("Failed to load config: %v", err)
}
Location: Must be in the same directory as the binary or specified via mount in Docker.

SSH Host Keys

SSH host keys are loaded from a hardcoded path (main.go:38):
wish.WithHostKeyPath(".ssh/id_ed25519"),
Default path: .ssh/id_ed25519 (relative to working directory)
The host key path is not currently configurable via environment variables. It must exist at .ssh/id_ed25519 relative to the working directory.

Server Configuration

Host Address

The server binds to all interfaces by default (main.go:25):
host := "0.0.0.0"
Default: 0.0.0.0 (all interfaces)
The host address is hardcoded and not configurable via environment variables. To bind to a specific interface, you would need to modify the source code.

Default Port

When SSH_PORT is not set, the server uses port 2222 (main.go:26):
port := "2222"
Default: 2222

Address Binding

The host and port are combined using (main.go:37):
wish.WithAddress(net.JoinHostPort(host, port)),
This creates the full address like 0.0.0.0:2222.

Configuration Examples

Development Setup

Run locally on a high port:
SSH_PORT=2222 ./ssh-portfolio
Connect with:
ssh localhost -p 2222

Production Setup

Run on standard SSH port (requires root or capabilities):
SSH_PORT=22 ./ssh-portfolio
Connect with:
ssh yourserver.com

Docker Development

Map container port 22 to host port 2222:
docker run -d \
  -p 2222:22 \
  -e SSH_PORT=22 \
  -v $(pwd)/config.yaml:/app/config.yaml \
  -v ssh-keys:/app/.ssh \
  ssh-portfolio:latest

Docker Production

Run on standard SSH port:
services:
  ssh-portfolio:
    build: .
    ports:
      - "22:22"
    environment:
      - SSH_PORT=22
    volumes:
      - ./config.yaml:/app/config.yaml
      - ssh-keys:/app/.ssh
    restart: unless-stopped

systemd Service

Configure via systemd unit file:
[Service]
Type=simple
User=portfolio
WorkingDirectory=/opt/ssh-portfolio
Environment="SSH_PORT=2222"
ExecStart=/opt/ssh-portfolio/ssh-portfolio
Restart=always

Multiple Instances

Run multiple instances on different ports:
SSH_PORT=2222 ./ssh-portfolio &
Each instance must have its own working directory with separate config.yaml and .ssh/id_ed25519 files.

Override Hierarchy

Configuration is loaded in this order:
  1. Code defaults - Hardcoded in main.go
    • Host: 0.0.0.0
    • Port: 2222
    • Config file: config.yaml
    • SSH keys: .ssh/id_ed25519
  2. Environment variables - Override defaults
    • SSH_PORT - Overrides default port
  3. Command-line flags - Not currently implemented

Default Values Summary

SettingDefault ValueConfigurableMethod
Host0.0.0.0NoHardcoded
Port2222YesSSH_PORT
Config fileconfig.yamlNoHardcoded
SSH key path.ssh/id_ed25519NoHardcoded

Validation and Errors

Missing Configuration File

If config.yaml is not found:
Failed to load config: open config.yaml: no such file or directory
Solution: Ensure config.yaml exists in the working directory.

Missing SSH Host Keys

If .ssh/id_ed25519 is not found, the server will attempt to generate keys automatically. If generation fails:
Failed to create SSH server: unable to load or generate host keys
Solution: Manually generate keys with:
mkdir -p .ssh
ssh-keygen -t ed25519 -f .ssh/id_ed25519 -N ""

Invalid Port Number

If SSH_PORT contains an invalid port:
Server error: listen tcp: address 99999: invalid port
Solution: Use a valid port number (1-65535). Ports below 1024 require root privileges.

Port Already in Use

If the port is already bound:
Server error: listen tcp :2222: bind: address already in use
Solution: Choose a different port or stop the conflicting service.

Environment Files

Using .env Files

Create a .env file for local development:
# .env
SSH_PORT=2222
Load it before running:
export $(cat .env | xargs)
./ssh-portfolio
Or use a tool like direnv:
# .envrc
export SSH_PORT=2222

Docker .env File

Docker Compose automatically loads .env:
# .env
SSH_PORT=3000
# docker-compose.yml
services:
  ssh-portfolio:
    build: .
    ports:
      - "${SSH_PORT}:${SSH_PORT}"
    environment:
      - SSH_PORT=${SSH_PORT}

Security Considerations

Never commit .env files containing sensitive information to version control. Add .env to your .gitignore.

Sensitive Values

While SSH Portfolio currently doesn’t use sensitive environment variables, follow these best practices:
  • Use restrictive file permissions: chmod 600 .env
  • Store secrets in proper secret management systems
  • Rotate SSH host keys periodically
  • Monitor environment variable access in logs

Next Steps

Docker Deployment

Deploy with Docker

Manual Deployment

Deploy from source

Build docs developers (and LLMs) love