Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connect to appserver container with SSH (without cli) #2188

Closed
Bouhnosaure opened this issue Apr 27, 2020 · 11 comments
Closed

Connect to appserver container with SSH (without cli) #2188

Bouhnosaure opened this issue Apr 27, 2020 · 11 comments

Comments

@Bouhnosaure
Copy link

Hi !

Thanks you for this project, i use it with Laravel every day on Fedora since I've left Windows and Laragon.

My question is about connecting with ssh into the appserver without the lando CLI because i use Tinkerwell and it has remote support with ssh.

Since i don't want to install PHP on my local machine just for this it could be great to have a guide how to use ssh without the CLI.

Also I've noticed that my keys had been imported into the container so i might not be far from being able to connect with the container.

78649038-2994ef80-78bd-11ea-992f-2dbc65bb2c16

And here is a copy of my .lando.yml

name: back-end
recipe: laravel
config:
  webroot: public
  php: '7.4'
  via: apache
  database: mysql:5.7
  cache: redis
  xdebug: false
services:
  appserver:
    ports:
      - "22:22" <---- I've tried this but this port is commented in sshd_config on appserver
  phpmyadmin:
    type: phpmyadmin
    hosts:
      - database
  mailhog:
    type: mailhog
    portforward: 1025
  node:
    type: node
  gotenberg:
    type: compose
    services:
      image: thecodingmachine/gotenberg:6
      command: gotenberg
      ports:
        - "3000:3000"
tooling:
  node:
    service: node
  npm:
    service: node
  yarn:
    service: node
proxy:
  phpmyadmin:
    - phpmyadmin.lndo.site
  mailhog:
    - mailhog.lndo.site
  gotenberg:
    - gotenberg.lndo.site
@pirog
Copy link
Sponsor Member

pirog commented Apr 27, 2020

lando ssh does not actually use ssh behind the scenes. It's named such primarily to communicate something the user is familiar with eg "dropping to the shell".

So if you wanted to connect to a lando service via ssh youd be responsible for setting up and managing that entire interaction

@ruelluna
Copy link

ruelluna commented May 18, 2020

youd be responsible for setting up and managing that entire interaction

What do you mean by this? How do I do that per se?

This is the only thing left for me to switch to lando vs homestead for my app..
I couldn't connect to Tinkerwell, PhpStorm (tests), and Invoker.

@StanBarrows
Copy link

Hey @ruelluna any updates on tihs?

@phil-s
Copy link

phil-s commented Sep 13, 2023

lando ssh does not actually use ssh behind the scenes. It's named such primarily to communicate something the user is familiar with eg "dropping to the shell".

Well that's a very confusing decision, to my mind. It's also crazy that this isn't mentioned at https://docs.lando.dev/cli/ssh.html (I think it should be highlighted).

Could someone please explain what this does use, and where to find documentation for it?

(In my case I currently want to know how to replicate the SendEnv / AcceptEnv ssh config options, but general documentation would be much appreciated.)

@AaronFeledy
Copy link
Collaborator

AaronFeledy commented Sep 13, 2023

You can see what a lando command is doing in the background by making it very verbose with -vvv added to your command. Something like lando ssh -s appserver shows me that it's running /usr/share/lando/bin/docker-compose exec appserver /bin/sh if ! type bash > /dev/null; then sh; else bash; fi

So it's just using docker exec to launch bash (or fall back to sh).

How does that relate to ssh? Given the most prominent user base of Lando is web developers who are most familiar with ssh in the context of getting a bash prompt that is executing on a web server, I assume that lando ssh was meant to convey that the developer would use this command to do the same.

If your goal is to get a host variable into a shell running inside the container, you can do something like this example that launches bash inside the container with the host's TERM variable applied.

lando ssh -c "sh -c 'TERM=$TERM bash'"

@phil-s
Copy link

phil-s commented Sep 13, 2023

Thank you for the info and the suggestion. What I really want is for plain lando ssh to be doing that kind of thing via config (and also not to interfere with using lando ssh -c for other purposes), but your approach is definitely helpful (especially as I already had a wrapper script for lando). If anyone else also wants to do this, I only suggest using env rather than sh -c. Cheers!

@phil-s
Copy link

phil-s commented Sep 14, 2023

The following suggests to me that this could be easily supported as config, given that docker-compose exec is the command being used:

$ /usr/share/lando/bin/docker-compose exec --help
Execute a command in a running container

Usage: exec [options] [-e KEY=VAL...] [--] SERVICE COMMAND [ARGS...]

Options:
    [...]
    -e, --env KEY=VAL Set environment variables (can be used multiple times,
                      not supported in API < 1.25)

@pirog
Copy link
Sponsor Member

pirog commented Sep 14, 2023

@phil-s im not sure if this is supported for lando ssh because it is a "core" command but you can set envvars for all Lando tooling commands eg if you define your own command you might be able to do what you want

@phil-s
Copy link

phil-s commented Sep 14, 2023

My impression is that none of the current ways lando provides for using environment variables allow a value to actually be read from the inherited environment and propagated to the container command. They all seem to be "set VAR to a hard-coded value X" rather than "pass VAR with its current value to the container/command".

Not only that, but the env_file variables and their values get hard-coded at build time! So I can put FOO=$FOO into that file, but the containers will always see the value of FOO that was in the environment of the last lando rebuild command. (I found this one very counter-intuitive -- I anticipated a lando restart being needed for env_file changes rather than a lando rebuild, which can be a far more expensive/time-consuming process).

The TERM variable is (unfortunately) even more hard-coded, but #2827 exists for that problem. (And I forgot that I'd identified the docker -e option back then as well.)

@pirog
Copy link
Sponsor Member

pirog commented Sep 14, 2023

@phil-s this is by design. as a rule we try to limit anything on the host polluting the environment in containers as a matter of stability. that said there are some obvious envvars we might want to forward along such as TERM, COLUMNS, etc, lando 4 will address that.

right now lando 3 just piggybacks off of docker which sets environment variables at build time so a rebuild is required. in lando 4 we have "fast rebuilds" eg build steps are cached so the "cost" of resetting envvars and rebuiding should be lower. we also are looking into a more "dynamic" way to set envvars that DOES NOT require a rebuild and supporting envvars usage directly in the landofile.

@phil-s
Copy link

phil-s commented Sep 15, 2023

Sounds good, thanks @pirog.

If it helps anyone else in the meantime, this is what I wrote as a wrapper:

#!/bin/sh

# Force "lando ssh" (which does not involve ssh in any way!) to use
# the correct TERM environment variable.  The idea for this came from
# https://github.com/lando/lando/issues/2188#issuecomment-1718218526

quote () {
    local param
    for param; do
        printf %s "${param}Z" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/Z\$/' /"
    done
}

if [ "$1" = "ssh" ]; then
    shift
    unset -v command help params
    while [ $# -gt 0 ]; do
        case "$1" in
            ( -h | --help ) {
                help=1
            };;
            ( -c | --command ) {
                shift
                command=$1
            };;
            ( --command=* ) {
                command=${1#--command=}
            };;
            ( * ) {
                params="${params}$(quote "$1")"
            };;
        esac
        shift
    done
    if [ -z "${command}" ]; then
        # No command; just run bash (by preference) or sh (otherwise).
        # We use the same test that "lando ssh -vvv" shows normally.
        shell="sh -c 'if type bash >/dev/null; then bash; else sh; fi'"
    else
        shell="sh -c $(quote "${command}")"
    fi
    # Apply the TERM environment variable.
    shell="env TERM=${TERM} ${shell}"
    # If --help was passed, don't use the shell command.
    if [ -n "${help}" ]; then
        params="ssh --help"
    else
        params="ssh -c $(quote "${shell}")${params}"
    fi
    echo "Command: lando ${params}"
    eval "set -- ${params}"
fi

# Run the maybe-modified command.
/usr/local/bin/lando "$@"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants