Starting remote SSH session from Deployer inside Docker

124 views Asked by At

I am trying to add an additional script to my PHP deployer script to open an SSH session on my hosting server.

Amongst the welcome message from the remote server, there is an error message:

the input device is not a TTY

Then I get an "exit code 1 (General error)" at the end, and it exits back to my local docker terminal.

Here is my script so far:

task('remotessh', function () {
    $host = currentHost();

    $hostname = $host->getHostname();
    $remoteUser = $host->get('remote_user');

    if (!$remoteUser) {
        throw new \RuntimeException("Remote user not set for host.");
    }

    $sshCommand = "ssh -T $remoteUser@$hostname";
    runLocally($sshCommand, ['tty' => true]);
});

Note: when I manually run ssh {remoteUser}@{hostname} in the same docker terminal, I can start an ssh session just fine.

Note 2: when I add -v flag there is some relevant output:

[server.com] err debug1: Offering public key: /home/user/.ssh/id_rsa RSA SHA256:xxx
[server.com] err debug1: Server accepts key: /home/user/.ssh/id_rsa RSA SHA256:xxx
[server.com] err debug1: Authentication succeeded (publickey).
[server.com] err Authenticated to server.com ([IP Address]:22).
[server.com] err debug1: channel 0: new [client-session]
[server.com] err debug1: Requesting [email protected]
[server.com] err debug1: Entering interactive session.
[server.com] err debug1: pledge: network
[server.com] err debug1: client_input_global_request: rtype [email protected] want_reply 0
[server.com] err debug1: Remote: /data/docker0/ssh/user/login/.ssh/authorized_keys:6: key options: agent-forwarding port-forwarding pty user-rc x11-forwarding
[server.com] err debug1: Remote: /data/docker0/ssh/user/login/.ssh/authorized_keys:6: key options: agent-forwarding port-forwarding pty user-rc x11-forwarding
[server.com] err debug1: Sending environment.
[server.com] err the input device is not a TTY

Any ideas how I can get this running?

2

There are 2 answers

1
JGK On

To forcibly allocate a TTY you have to specify -t. From the ssh manual page

Force pseudo-terminal allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.

So in my opinion you have to use

$sshCommand = "ssh -t $remoteUser@$hostname";
runLocally($sshCommand, ['tty' => true]);

Maybe you have to specify ssh -ttt $remoteUser@$hostname.

0
VonC On

First, note that if the TTY is not strictly necessary for what you need to do on the remote server, you could modify your SSH command to not require a TTY.

$sshCommand = "ssh -T $remoteUser@$hostname";
runLocally($sshCommand);

The -T flag explicitly tells SSH not to allocate a pseudo-terminal.

But if you do need said terminal, and if using -tt in the SSH command does not resolve the "input device is not a TTY" error, try and use the script command to emulate a terminal (TTY). That can be particularly useful when running commands in environments that lack TTY, like Docker containers or CI/CD pipelines.

Modify your script as follows:

task('remotessh', function () {
    $host = currentHost();
    $hostname = $host->getHostname();
    $remoteUser = $host->get('remote_user');

    if (!$remoteUser) {
        throw new \RuntimeException("Remote user not set for host.");
    }

    $sshCommand = "script -q -c \"ssh $remoteUser@$hostname\" /dev/null";
    runLocally($sshCommand, ['tty' => true]);
});

If you have control over how the Docker container is run, you can try allocating a pseudo-TTY at the Docker level.

For example, when running the container, use:

docker run -it (rest of your Docker command)

The -it flag allocates an interactive terminal when the Docker container is run.

Make sure the environment from which the PHP script is run (i.e., the Docker container) supports interactive sessions. Check the SSH client configuration (typically found in ~/.ssh/config or /etc/ssh/ssh_config) for any settings that might affect TTY allocation (like, for instance, RequestTTY).