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

LANDO_INFO inside a container not always matches lando info #2565

Open
hanoii opened this issue Aug 12, 2020 · 22 comments
Open

LANDO_INFO inside a container not always matches lando info #2565

hanoii opened this issue Aug 12, 2020 · 22 comments
Labels
bug Something aint working right!
Projects

Comments

@hanoii
Copy link
Contributor

hanoii commented Aug 12, 2020

v3.0.11 on OSX 10.15.6

Trying to explain this the best way I can. I have my local native webserver running on port 80 and port 443, so on lando start I get different ports.

I have a proxy to my node container so that I can use browser sync, very similar setup to https://docs.lando.dev/guides/how-to-wire-up-browsersync-and-gulp-in-my-lando-app.html with some tweaks.

I am trying to get the lando external proxy urls by looking into LANDO_INFO env variable inside the node container. The first time I run this (after lando rebuild -y) this worked. I got port 8080 and port 4433 for SSL. I then lando restarted it and this time I got the proxy URLs with port 8000 and 444. However, LANDO_INFO inside the node container still had the old ports (8080, and 4433) so obviously when I feed those to browser sync it fails.

My first guess was that LANDO_INFO was created on build but not updated on start but this is not consistent, I believe at one point it did update.

Couple test commands (this example shows it the other way around as what I wrote above):

# lando info -s node --format=json | jq ".[0].urls[]"
"http://bs.project.lndo.site:8080/, https://bs.project.lndo.site:4433/"

# lando ssh -s node -c "printenv LANDO_INFO" | jq '(.node.urls[])'
"http://bs.project.lndo.site:8000/, https://bs.project.lndo.site:444/"

After one lando restart:

# lando info -s node --format=json | jq ".[0].urls[]"
"http://bs.project.lndo.site:8000/, https://bs.project.lndo.site:444/"

# lando ssh -s node -c "printenv LANDO_INFO" | jq '(.node.urls[])'
"http://bs.project.lndo.site:8000/, https://bs.project.lndo.site:444/"

After another lando restart: I got the same output as the first set above (wrong URLs)
After another lando restart: I got the same output as the second set above (proper URLs)
After another lando restart: I got the same output as the first set above (wrong URLs)

It does seem like the LANDO_INFO inside the container never (or hardly ever) changes.

@hanoii hanoii added the bug Something aint working right! label Aug 12, 2020
@hanoii
Copy link
Contributor Author

hanoii commented Aug 18, 2020

I tried seeing if could spot the issue in the code. It definitely looks like LANDO_INFO is set somehow on the container and not run when started so I only have very old urls of the proxied nodes. I am struggling with this on another project as well.

@hanoii
Copy link
Contributor Author

hanoii commented Aug 20, 2020

After much more in depth review and some talks in Slack with @pirog, I still believe this is an issue but not something that can be sorted by the lando side of things.

I found related issues around browser-sync and I think I come up with a neat workaround as noted on BrowserSync/browser-sync#505 (comment)

That also improved on the guide above in making forms work (at least on Drupal) so I'll try to contribute to that at some point.

Let you review this and see if you want to follow up anything more on this.

@pfrenssen
Copy link

I'm also affected by this. I'm trying to set the base URL in Drush but I'm getting the wrong port number in LANDO_INFO.

@pfrenssen
Copy link

It seems this is populated only on initialisation (post-init), here is the relevant part from lando-core/app.js:

  // Collect info so we can inject LANDO_INFO
  //
  // @TODO: this is not currently the full lando info because a lot of it requires
  // the app to be on
  app.events.on('post-init', 10, () => {
    const info = toObject(_.map(app.info, 'service'), {});
    _.forEach(info, (value, key) => {
      info[key] = _.find(app.info, {service: key});
    });
    app.log.verbose('setting LANDO_INFO...');
    app.env.LANDO_INFO = JSON.stringify(info);
  });

Should this be run maybe also on pre-rebuild or maybe moved to pre-start?

@com2
Copy link

com2 commented Oct 21, 2020

Very annoying when you want the up-to-date localhost port. Is there a work around, something to force the update (beside a full rebuild)?

@pirog
Copy link
Sponsor Member

pirog commented Oct 21, 2020

You should NEVER use the localhost port internally.

@com2
Copy link

com2 commented Oct 21, 2020

You should NEVER use the localhost port internally.

Thank you for the advice but that does not really answer the question, does it? I did not want to go off topic either by explaining to a full extend why I need it. But thangs anyway. Your remark provoked me to look further and I found what I needed.

@pfrenssen
Copy link

@com2 can you provide more information on how you fixed it?

@pfrenssen
Copy link

pfrenssen commented Oct 22, 2020

@pirog I suppose you have some use cases in mind for which the localhost port is not suitable, but there are legitimate use cases where this is needed. For example CLI tools and testing tools can use this information to communicate URLs to the end user.

Some examples:

  • The Drush CLI tool for Drupal has a command that opens a browser window with a password reset link to give easy admin access. If the port number is not correct this doesn't work.
  • Drupal browser tests provide a log with URLs to pages that contain errors or unexpected output. If these URLs do not contain the current localhost port the developer cannot open them.
  • When Behat tests fail they can save the current page as a HTML dump in a temporary folder inside the webspace, and output a link to this page in the terminal which the developer can click to quickly view the screenshot of the page that caused the failure. These links don't work if the port number is not up-to-date.

@pirog
Copy link
Sponsor Member

pirog commented Oct 23, 2020

You should not be using the "randomly generated" external localhost port for anything except for viewing the site in the browser. Using it for anything programmatic is going to be inherently brittle.

There are numerous other networking mechanisms in Lando and Docker at your disposal that are MUCH better suited for the use cases you describe. This is the point.

And to be clear, this is not to say that LANDO_INFO shouldn't be improved, because it should. This is just advice.

@pfrenssen
Copy link

pfrenssen commented Dec 16, 2020

You should not be using the "randomly generated" external localhost port for anything except for viewing the site in the browser.

Yes that is clear, that is what this issue is about. LANDO_INFO outputs URLs with the wrong port number and this prevents us from viewing the site in the browser.

There are numerous other networking mechanisms in Lando and Docker at your disposal that are MUCH better suited for the use cases you describe. This is the point.

Can you please elaborate on this? I'm not clear on how these use cases can be solved if we cannot get the correct port number from inside the container. All three cases I mentioned are outputting absolute URLs generated by PHP code that is running inside the container. Since the port number is not available to them, they output incorrect URLs.

@pirog pirog added this to Needs triage in Starbuck Dec 28, 2020
@stale
Copy link

stale bot commented Jun 16, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions and please check out this if you are wondering why we auto close issues.

@stale stale bot added the stale Issue has been auto-flagged as stale label Jun 16, 2021
@pfrenssen
Copy link

Not stale.

@stale stale bot removed the stale Issue has been auto-flagged as stale label Aug 4, 2021
@markjaquith
Copy link

markjaquith commented Aug 31, 2021

Here's how I worked around this issue for a WordPress install. WP-CLI, like Drupal's Drush, sometimes needs to know "what host does the web version of me run on?"

if (getenv('LANDO_INFO')) {
	$lando_info = json_decode(getenv('LANDO_INFO'));
	$database_config = $lando_info->database;
	define('DB_NAME', $database_config->creds->database);
	define('DB_USER', $database_config->creds->user);
	define('DB_PASSWORD', $database_config->creds->password);
	define('DB_HOST', $database_config->internal_connection->host);

	/**
	 * This is nasty.
	 *
	 * Lando does not keep LANDO_INFO up-to-date:
	 * https://github.com/lando/lando/issues/2565
	 *
	 * So when running via a web browser, we can sniff the HTTP_HOST
	 * and write that to a file. Then, when not running via web browser
	 * (like when running WP-CLI), we can read the host from the file
	 * and use that.
	 */
	$_lando_host_file = __DIR__ . '/.lando.host';

	if (isset($_SERVER['HTTP_HOST'])) {
		$_host = 'https://' . $_SERVER['HTTP_HOST'];
		$_lando_host = @file_get_contents($_lando_host_file);
		if ($_host !== $_lando_host) {
			file_put_contents($_lando_host_file, $_host);
		}
	} else {
		$_host = @file_get_contents($_lando_host_file);
	}

	defined('WP_HOME') || define('WP_HOME', $_host);
	defined('WP_SITEURL') || define('WP_SITEURL', $_host);

	unset($_host, $lando_host, $_lando_host_file, $lando_info, $database_config);
}

TL;DR: the only way I can reliably get the "host name it is running on" is when it is accessed via the web server. I then write this value to a file if it has changed. The CLI then reads from this file when running not as a web server.

I know. I know. But it unblocked me.

@stale
Copy link

stale bot commented Mar 30, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions and please check out this if you are wondering why we auto close issues.

@stale stale bot added the stale Issue has been auto-flagged as stale label Mar 30, 2022
@pfrenssen
Copy link

Not stale.

@jeroennoten
Copy link

Any update on this? I run Magento with Lando and Magento needs the base URL configured in its configuration. And because the URL might change after a lando start, I wanted to run a script that sets the base URL on the post-start event. However, this sometimes (often) misconfigures the URL due to this issue. I cannot use the above trick so I am afraid that I cannot automate this using a post-start event at the moment.

@stale stale bot removed the stale Issue has been auto-flagged as stale label Aug 9, 2022
@stale
Copy link

stale bot commented May 22, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions and please check out this if you are wondering why we auto close issues.

@stale stale bot added the stale Issue has been auto-flagged as stale label May 22, 2023
@DuaelFr
Copy link

DuaelFr commented Jul 12, 2023

Not stale please.

In my case I'm trying to get the external_connection port of my database to feed a PHPStorm config file when I start my project and be able to access the database in its internal viewer. I wish it was possible to set a custom proxy address to route the 3306 port of something like database.PROJECT.lndo.site to the randomly generated port of the service but it seems it's not possible either.

If LANDO_INFO cannot be relied upon, I'd be happy to be able to run a command on the host on a post-start event but I wasn't able to do that either.

@stale stale bot removed the stale Issue has been auto-flagged as stale label Jul 12, 2023
@AaronFeledy
Copy link
Collaborator

AaronFeledy commented Jul 14, 2023

@DuaelFr You can do that!

.lando.yml

name: myapp
recipe: lamp

proxy:
  database:
    - db.myapp.lndo.site:3306

After a lando rebuild, this will tell Lando's proxy to route connections on port 80 at the above URL and send them to the internal connection port of 3306 on the database service. Now you can tell PHPStorm to connect to the db URL above and use port 80. No need to manage the external connection port.

@DuaelFr
Copy link

DuaelFr commented Jul 17, 2023

Thanks a lot @AaronFeledy! I thought the proxy was sending requests to the external connection port. I should have read the documentation more carefully 🤦

@DuaelFr
Copy link

DuaelFr commented Jul 18, 2023

@AaronFeledy I spoke too quick. It's not working. Maybe that's because the proxy is trying to route only http traffic, I don't know. I tried to use a simple mysql client (ie. mysql -h db.myapp.lndo.site -P 80 -u drupal9 -pdrupal9 -v -v -v) but, like PHPStorm, it's somehow stuck forever. Is that something I'm missing?


In the meantime, if that can be of any use for someone, I wrote that bash script that I manually execute when I need it (it's working even if your PHPStorm is already in use):

#!/bin/bash

if [ ! -f .idea/dataSources.xml ]; then
  echo ".idea/dataSources.xml not found. You need to create the datasource in PHPStorm at least once."
  exit 1
fi

LANDO_INFO=`lando info -s database --format=json`
if [[ "$LANDO_INFO" == "[]" ]]; then
    echo "\"database\" lando service not found"
    exit 2
fi

DB_HOST=$(echo $LANDO_INFO | jq -r '.[0].external_connection.host')
DB_PORT=$(echo $LANDO_INFO | jq -r '.[0].external_connection.port')
DB_NAME=$(echo $LANDO_INFO | jq -r '.[0].creds.database')
DB_USER=$(echo $LANDO_INFO | jq -r '.[0].creds.user')

JDBC_URL="<jdbc-url>jdbc:mysql://$DB_HOST:$DB_PORT/$DB_NAME</jdbc-url>"
JDBC_USER="<user-name>$DB_USER</user-name>"

sed -i "s#<jdbc-url>.*</jdbc-url>#$JDBC_URL#" .idea/dataSources.xml
sed -i "s#<user-name>.*</user-name>#$JDBC_USER#" .idea/dataSources.xml

You need to have created a datasource once first so the dataSources.xml file already exists and have the entry we want to replace.
⚠️ do not use this script if you have more than one datasource in your project or it will overwrite all of them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something aint working right!
Projects
No open projects
Starbuck
Needs triage
Development

No branches or pull requests

8 participants