A Docker image designed for Railway deployment that provides an Ubuntu 24.04 LTS base with SSH server enabled (SSHD). This allows you to connect to your Railway container via SSH for remote access and management.
- Ubuntu 24.04 LTS base image
- SSH server (OpenSSH) pre-configured
- Clean SSH Login: No welcome messages for direct command line access
- Password authentication enabled
- Root login disabled by default for security
- Created user has sudo permissions
- Network utilities included (ping, telnet, iproute2)
- Development Environment: Claude Code, Node.js 20.x LTS, Ruby 3.3.6, Rails, Python 3.12
- CLI Tools: GitHub CLI, Railway CLI, PostgreSQL client, Redis tools
- Package Managers: npm, pnpm, yarn, bundler, pip
- Automated setup: Git configuration, CLI authentication, repository cloning
- Docker Compose: Local testing support with docker-compose.yml
- Health Monitoring: Built-in health checks for Railway deployment
Railway runs Docker containers, not VPS! Any data stored in the container will be lost when redeploying. This includes:
- Files created after deployment
- Installed packages
- Configuration changes
- User data
If you need persistent storage, consider using Railway's volume mounts or external storage solutions.
-
Before deploying, edit the
ssh-user-config.shfile and change the default values:# Change these default values to your desired credentials : ${SSH_USERNAME:="myuser"} : ${SSH_PASSWORD:="mypassword"}
-
Commit and push your changes to your repository
-
Then deploy to Railway
-
Deploy to Railway
-
Go to your project dashboard
-
Navigate to Settings → Variables:
-
Add the following environment variables:
SSH Configuration:
SSH_USERNAME- Your desired usernameSSH_PASSWORD- Your desired passwordROOT_PASSWORD- Root password (optional, leave empty if root login is disabled)AUTHORIZED_KEYS- SSH public keys for key-based authentication (optional)
Development Environment (Optional):
GH_TOKEN- GitHub Personal Access Token for GitHub CLI authentication and git push/pullGITHUB_EMAIL- Your git commit email addressGITHUB_NAME- Your git commit nameTZ- Timezone (e.g., America/New_York, Europe/London)SSH_BANNER- Custom welcome message displayed after SSH loginLOG_LEVEL- SSH logging level (DEBUG, INFO, NOTICE, WARN, ERROR)HOST- Host binding address for Railway applications (defaults to 0.0.0.0)HOSTNAME- Hostname binding for Railway applications (defaults to 0.0.0.0)
-
Redeploy your project to apply the new environment variables:
-
Go to your Railway project dashboard
-
Navigate to Settings → Networking:
-
Under Public Networking, click TCP Proxy
-
Enter the exposed port
22(the default SSH port): -
Click Add Proxy
After configuring the TCP proxy, redeploy your project to apply the networking changes:
-
Once deployed, Railway will provide you with a domain and port for TCP access:
-
Use the SSH command to connect:
ssh {username}@{domain} -p {port}Example:
ssh [email protected] -p 30899
-
When prompted about the host authenticity, type
yesto accept the new key pair -
Enter the user password when prompted
-
You're now connected to your Railway container via SSH!
This container comes pre-configured with a complete development environment including:
- Claude Code: AI-powered development assistant
- Node.js 20.x LTS: JavaScript runtime with npm, pnpm, and yarn
- Python 3.12: Python runtime with pip and venv
- Ruby 3.3.6: Latest stable Ruby via rbenv with Rails and bundler pre-installed
- GitHub CLI: Authenticated and ready to use (if
GH_TOKENprovided) - Railway CLI: Available (requires manual login:
railway login) - Database Clients: PostgreSQL and Redis clients
- Build Tools: ripgrep, build-essential, git, curl, wget
When the container starts, it automatically:
- Configures git with your identity (if
GITHUB_EMAILandGITHUB_NAMEprovided) - Authenticates GitHub CLI and configures git for push/pull (if
GH_TOKENprovided) - Installs Railway CLI (manual login required after SSH connection)
- Installs Claude Code globally for the SSH user
- Creates a
~/dev/directory for your projects - Clones all your GitHub repositories to
~/dev/(ifGH_TOKENprovided)
SSH login goes directly to command prompt with no welcome messages for a clean development experience.
After SSH connection:
# Claude Code is ready to use
claude
# GitHub CLI is authenticated (git push/pull work automatically)
gh repo list
git push # Works without additional authentication
# Railway CLI (requires manual login in SSH session)
railway login
railway list
# Clone your repos to ~/dev/
cd ~/dev
gh repo clone owner/repo
# Ruby and Rails are ready
ruby --version
rails --version
# Python is ready
python3 --version
pip --version
# Node.js tools are ready
node --version
npm --version
pnpm --versionFor local testing, use the included docker-compose.yml:
# Build and start the container
docker-compose up --build
# Connect via SSH (in another terminal)
ssh testuser@localhost -p 2222
# Stop the container
docker-compose downThe Docker Compose setup includes:
- Pre-configured test user credentials
- Port mapping (2222:22)
- Environment variables for development
- Health checks
- Optional volume mounting for persistent development
Copy .env.example to .env and customize your settings:
cp .env.example .env
# Edit .env with your preferred settingsThe current default values in ssh-user-config.sh are:
SSH_USERNAME=myuserSSH_PASSWORD=mypassword
The system checks for credentials in this order:
- Railway environment variables (highest priority)
- Values set directly in
ssh-user-config.sh(default if no environment variables)
Root login is disabled by default for security reasons. If you need to enable root login, you can modify the Dockerfile by changing:
&& echo "PermitRootLogin no" >> /etc/ssh/sshd_configto:
&& echo "PermitRootLogin yes" >> /etc/ssh/sshd_configNote: The created user already has sudo permissions and is added to the sudo group, so root access is typically unnecessary.
- CRITICAL: Always change the default SSH credentials in
ssh-user-config.shbefore deploying to production - Root login is disabled by default
- SSH security hardening included:
- Max 3 authentication attempts
- Client timeout protection (5 minutes idle)
- Protocol 2 enforcement
- Only password authentication is enabled by default
- The default user has sudo privileges for administrative tasks
- Consider using SSH keys (
AUTHORIZED_KEYS) instead of passwords for better security - When using
AUTHORIZED_KEYS, password authentication is automatically disabled - Configurable logging levels for security monitoring
- No persistent storage: All data is lost when redeploying.
- Not a VPS: This is a containerized environment, not a virtual private server
- Temporary file system: Any files created inside the image will be lost on restart/redeploy
Important: Conside using Railway Volume Mount for persistent storage
- Ensure the TCP proxy is configured correctly on Railway
- Verify the correct domain and port are being used
- Check that the container is running and healthy
- Confirm firewall settings allow SSH connections
- Verify credentials are set correctly in
ssh-user-config.shor Railway environment variables - Remember that data loss occurs on every redeploy
This project is licensed under the terms included in the LICENSE file.





