---
title: railway ssh
description: Connect to a service via SSH and manage SSH keys.
---
Open an interactive shell session inside a deployed Railway service container, or manage the SSH keys registered with your Railway account.

Railway uses your system `ssh` client to connect to `ssh.railway.com`. You must have an SSH key registered with Railway before you can connect. The CLI prompts you to register a local key the first time you run `railway ssh`.

## Usage

```bash
railway ssh [OPTIONS] [COMMAND...]
railway ssh config [OPTIONS] [COMMAND]
railway ssh keys [SUBCOMMAND] [OPTIONS]
```

## Options

| Flag | Description |
|------|-------------|
| `-p, --project <ID>` | Project to connect to (defaults to linked project) |
| `-s, --service <SERVICE>` | Service to connect to (defaults to linked service) |
| `-e, --environment <ENV>` | Environment to connect to (defaults to linked environment) |
| `-d, --deployment-instance <ID>` | Specific deployment instance ID to connect to |
| `--session [NAME]` | Connect inside a persistent tmux session that reconnects automatically. Defaults to `railway` |
| `-i, --identity-file <PATH>` | Path to a private key to forward to ssh, like `ssh -i` |

## Examples

### Interactive shell

```bash
railway ssh
```

Opens an interactive shell in the service container.

### Run a single command

```bash
railway ssh -- ls -la
```

PTY allocation is autodetected. Interactive tools like `vim` or `htop` work when both stdin and stdout are terminals; piped input runs without a PTY so output stays clean for scripts and CI.

### Persistent tmux session

```bash
railway ssh --session
```

Connects inside a tmux session named `railway`. If the connection drops, the CLI reconnects and reattaches to the same session. Pass a name to use a different session:

```bash
railway ssh --session debug
```

Railway installs tmux in the container automatically if it isn't already installed.

### Connect to a specific deployment instance

```bash
railway ssh --deployment-instance <instance-id>
```

### Use a specific identity file

```bash
railway ssh -i ~/.ssh/railway_ed25519
```

When set, the CLI skips its local `~/.ssh` scan and forwards the key directly to `ssh`.

## Connect to a service without a public domain

The SSH username is the service's domain, so a service that has no domain needs
a different target. Use its service instance ID instead.

1. Open the service in the dashboard.
2. Open the **command palette** with `CMD + K` (Mac) or `Ctrl + K` (Windows).
3. Choose **Copy Service Instance ID**.

That ID works as the username anywhere a domain does:

```bash
ssh <service-instance-id>@ssh.railway.com
scp <service-instance-id>@ssh.railway.com:/app/data.json ./data.json
```

The palette also offers **Copy Service ID**, which is a different value and is
not a valid SSH target.

## Copy files with scp and sftp

Railway SSH supports the SFTP subsystem, so your system `scp` and `sftp` clients
work against `ssh.railway.com` using the same registered key. Use the service's
domain as the username, or its service instance ID if it has no domain.

```bash
# Copy a file out of the container
scp myapp.up.railway.app@ssh.railway.com:/app/data.json ./data.json

# Copy a file into the container
scp ./data.json myapp.up.railway.app@ssh.railway.com:/app/data.json

# Copy a directory
scp -r myapp.up.railway.app@ssh.railway.com:/app/logs ./logs

# Open an interactive SFTP session
sftp myapp.up.railway.app@ssh.railway.com
```

A deployment instance ID works as the username too, in place of the domain.

`scp` uses the SFTP protocol on OpenSSH 9.0 and newer. On older clients, pass
`-s` to select it.

If you added a host alias with [`railway ssh config`](#manage-ssh-config), use
the alias instead:

```bash
scp railway-api:/app/data.json ./data.json
```

Transfers reach the running container's filesystem, including any mounted
volume. For volume files specifically, [`railway volume browse`](/cli/volume)
gives you an interactive browser without setting up SSH.

## Forward a port with ssh -L

Railway SSH supports local port forwarding, so you can open an SSH tunnel from
your own machine to a port inside your container.

```bash
ssh -N -L 8080:127.0.0.1:8080 myapp.up.railway.app@ssh.railway.com
```

The connection is dialed from inside the container, so `127.0.0.1` is the
container's own loopback. `-N` skips the shell, so the command does nothing but
hold the tunnel open. Keep the session running while you use the tunnel.

Forwarding is limited to the container's loopback and your project's private
network. Public destinations are refused, so an SSH tunnel can't be used as a
general internet proxy.

## Manage SSH config

Use the `config` subcommand to add, preview, or remove a Railway OpenSSH config
block for a service.

```bash
railway ssh config [OPTIONS] [COMMAND]
```

### Subcommands

| Subcommand | Aliases | Description |
|------------|---------|-------------|
| `remove` | `rm` | Remove the Railway block from the SSH config file |

### Add or update SSH config

```bash
railway ssh config --service api
```

Adds or updates the Railway block in `~/.ssh/config` for the selected service.

### Preview SSH config

```bash
railway ssh config --service api --dry-run
```

Prints the generated block without writing the SSH config file.

### Use a custom host alias

```bash
railway ssh config --service api --alias railway-api
```

Sets the `Host` alias in the generated OpenSSH config block.

### Remove SSH config

```bash
railway ssh config remove --service api
```

Removes the Railway block for the selected service from the SSH config file.

### Options for `config`

| Flag | Description |
|------|-------------|
| `-p, --project <PROJECT>` | Project to use |
| `-s, --service <SERVICE>` | Service to use |
| `-e, --environment <ENVIRONMENT>` | Environment to use |
| `--path <PATH>` | SSH config file to update or remove from. Defaults to `~/.ssh/config` |
| `--alias <ALIAS>` | Host alias to use in the SSH config |
| `-i, --identity-file <PATH>` | Emit an `IdentityFile` directive for this private key path |
| `--dry-run` | Print the generated block without writing the SSH config file |

### Options for `config remove`

| Flag | Description |
|------|-------------|
| `-p, --project <PROJECT>` | Project to use |
| `-s, --service <SERVICE>` | Service to use |
| `-e, --environment <ENVIRONMENT>` | Environment to use |
| `--path <PATH>` | SSH config file to remove from. Defaults to `~/.ssh/config` |

## Manage SSH keys

Use the `keys` subcommand to register, list, and remove SSH keys for your Railway account or workspace.

```bash
railway ssh keys [SUBCOMMAND] [OPTIONS]
```

### Subcommands

| Subcommand | Aliases | Description |
|------------|---------|-------------|
| `list` | `ls` | List SSH keys registered with Railway (default when no subcommand is given) |
| `add` | `create`, `register` | Register a local SSH key with Railway |
| `remove` | `rm`, `delete` | Remove a registered SSH key |
| `github` | `import` | Import SSH keys from your linked GitHub account |

### Options

| Flag | Description |
|------|-------------|
| `--workspace <WORKSPACE_ID>` | Operate on workspace-owned keys instead of your personal keys |
| `--key <PATH>` | Path to the public key file (for `add`) |
| `--name <NAME>` | Name for the registered key (for `add`) |
| `--2fa-code <CODE>` | 2FA code for verification (for `remove`) |

### List registered keys

```bash
railway ssh keys
```

### Add a key

```bash
railway ssh keys add --key ~/.ssh/id_ed25519.pub --name "laptop"
```

Run without flags to pick from your local `~/.ssh` keys interactively.

### Remove a key

```bash
railway ssh keys remove
```

### Import keys from GitHub

```bash
railway ssh keys github
```

GitHub keys belong to your personal account and can't be imported directly into a workspace. To register a GitHub key for a workspace, import it first, then add it with `--workspace`.

### Workspace-owned keys

Workspace keys grant SSH access to every service in the workspace. Adding or removing workspace keys requires workspace **Admin** access.

```bash
railway ssh keys --workspace <workspace-id>
railway ssh keys add --workspace <workspace-id> --key ~/.ssh/id_ed25519.pub
```

When you authenticate with a workspace-scoped `RAILWAY_API_TOKEN`, the CLI operates on workspace keys automatically. SSH key management isn't supported with project tokens (`RAILWAY_TOKEN`); use a workspace API token or run `railway login`.

## Known limitations

VS Code Remote-SSH isn't supported. Use `railway ssh` directly for shell access.

## Use cases

- Debugging production issues
- Running database migrations
- Accessing language REPLs (Rails console, Django shell)
- Inspecting log files
- Troubleshooting network issues

## Related

- [railway connect](/cli/connect)
- [railway logs](/cli/logs)