Lando + Bedrock + Bud/Sage Configuration

@ben So far this seems to work well for me.
Should have thought of this myself I feel, but thanks for providing this workaround!

It’s even better: my lando config now also seems to work with bud 5.7.6 (without the workaround)

2 Likes

As @cim first noted, as of bud 5.7.6 Lando and Bud seem to be playing nicely together. My working config looks like this:

.lando.yml

name: lando-bedrock
recipe: wordpress
config:
  webroot: web
proxy:
  appserver:
    - bedrock.lndo.site
  theme:
    - theme.bedrock.lndo.site:3000
services:
  theme:
    type: node:16

bud.config.js

/**
 * @typedef {import('@roots/bud').Bud} bud
 *
 * @param {bud} app
 */
module.exports = (app) => {
    app
    /**
     * Application entrypoints
     *
     * Paths are relative to your resources directory
     */
    .entry({
        app: ['@scripts/app.js', '@styles/app.scss'],
        editor: ['@scripts/editor.js', '@styles/editor.scss'],
    })

    /**
     * These files should be processed as part of the build
     * even if they are not explicitly imported in application assets.
     */
    .assets(['images'])

    /**
     * These files will trigger a full page reload
     * when modified.
     */
    .watch([
      'tailwind.config.js',
      'resources/views/**/*.blade.php',
      'app/View/**/*.php',
    ])

    /**
     * Development URL to be used in the browser.
     */
    .serve('http://theme.bedrock.lndo.site');
}

The bud.proxy line is also not required if WP_HOME is set.

With this config, the bud dev server can be accessed from http://theme.bedrock.lndo.site.

5 Likes

Additionally, this config assumes you are running everything with the Lando containers, i.e. lando composer install, lando yarn, lando yarn dev

I ran into an issue on 2 of 3 projects I had set up like this where Bud would include CSS and JS assets using an absolute URL with port 3000 that would not work outside of the containers. Interestingly enough, one site worked perfectly, including assets with relative URLs, without any apparent differences in configuration and dependency versions.

To solve this problem, the app.hooks.action code can be added below the .serve line in bud.config.js:

   /**
     * Development URL to be used in the browser.
     */
    .serve('http://theme.bedrock.lndo.site');

    /**
     * Fix JS & CSS assets included with incorrect URL by updating the server config AFTER the
     * dev server has been started.
     */
    app.hooks.action('event.server.after', async(app) => {
        Object.assign(app.server.connection, {url: new URL('http://theme.bedrock.lndo.site')})
    });
5 Likes

Last solution from @noahott works.

Without hooks, CSS and JS are not enqueued.

Hey @ben, what to take a look at this thread again when you have a moment? I believe I have a working solution here now. Thanks!

1 Like

This works for me :heart:

Thanks @noahott

1 Like

@aksld Do you mean that literally? As in: they are not enqueued by acorn?

@noahott thanks for your work on this. two questions that could help me improve for future releases:

  1. is it possible you could try playing around with this script? You would just replace SEARCH_BODY_STRING and REPLACE_BODY_STRING with string or regexp values. If you use a regexp it has to end with /g (global).
 app.hooks.action('event.proxy.interceptor', async ({hooks}) =>
    hooks.on('middleware.proxy.replacements', replacements => [
      ...(replacements ?? []),
      [SEARCH_BODY_STRING, REPLACE_BODY_STRING],
      // can add as many as needed
    ]),
  )

I think this hook will eventually be surfaced as an config fn – proxyFindReplace() or something to that effect. Curious if you would have been able to fix this with that as a tool, had it been available.

  1. Related strongly to the first question… What is the value you are overwriting here?
app.hooks.action('event.server.after', async(app) => {
        Object.assign(app.server.connection, {url: new URL('http://theme.bedrock.lndo.site')})
    });

You can get at it with this snippet (run with --log flag and it’ll exit right after it logs the value):

app.hooks.action('event.server.after', async(app) => {
  app.log(app.server.connection.url).close()
});

:pray:

2 Likes
  1. Your script also works to solve this issue for me. I set it up to find the URLs with port 3000 and remove the port:
app.hooks.action('event.proxy.interceptor', async ({hooks}) =>
      hooks.on('middleware.proxy.replacements', replacements => [
        ...(replacements ?? []),
        ['//theme.bedrock.lndo.site:3000', '//theme.bedrock.lndo.site'],
        // can add as many as needed
      ]),
    );
  1. The value I’m overwriting is:
URL {
  href: 'http://theme.bedrock.lndo.site:3000/',
  origin: 'http://theme.bedrock.lndo.site:3000',
  protocol: 'http:',
  username: '',
  password: '',
  host: 'theme.bedrock.lndo.site:3000',
  hostname: 'theme.bedrock.lndo.site',
  port: '3000',
  pathname: '/',
  search: '',
  searchParams: URLSearchParams {},
  hash: ''
}

This is correct based on the default configuration, but causes an issue with Lando. The port used inside the docker container is 300, but should be 80 outside. When absolute URLs instead of relative, those assets don’t load.

What I can’t figure out is why one of my projects includes vendor/app.js, vendor/bud.app.editor.js, app.js, etc. with relative URLs, while other ones use absolute. If we can ensure that relative URLs are always used, then this would not be a problem.

Please let me know if there is any more info or help I can provide with this.

2 Likes

Got it working, thanks @noahott !

Initially I did’t realize all @Roots/... devDependencies in package.json had to be updated to 5.7.7 for the whole setup to work.

1 Like

@noahott while on theme.bedrock.lndo.site don’t you have any issues logging into wp-admin (or alternatively to WooCommerce my-account)?

In my case page reloads and fails to log in, no visible errors, nothing in console nor in debug log.

Yes, this is an issue. WordPress is expecting it’s cookies to be set from the primary domain and I have not found a solution to this yet.

Recent versions of bud.js nulls the cookie domain which means you should be able to log in through the dev server URL.

Assuming you are serving on 0.0.0.0:3000:

  1. Navigate to http://localhost:3000/wp/wp-login.php. Note that you must use localhost, the 0.0.0.0 IP will not work because it is not a hostname.
  2. Clear application/cookie data.
  3. Attempt to log-in. You will receive a UI error that cookies are not enabled in your browser. Ensure you are still on localhost and try again.
  4. You should log in successfully.

It may be more complicated here, depending on your setup and if you’re running bud dev from within the context of the container. I’m not sure. But the above instructions work for a VM with the bud dev command run on the host.

2 Likes

Seems to be working for me. Thanks!

1 Like

This got me thinking, though. Instead of setting the domain attribute to null what if instead it were just set to undefined?

The answer is that it seems to make the login fully transparent in both directions. So, if you’re logged in on the proxied server that login is automatically applied to the dev server and vice versa.

I opened a PR here:

Going to ask a couple of other roots maintainers to give this a go before I merge it. I’m happy that null seems to be working, for now, and don’t want to mess it up :smiley:

1 Like

Edit: moved to new topic as per request: Yarn dev with Lando not working anymore (bud 6.3.0)

Please create a new topic relevant to your issue instead of bumping an old topic that was resolved months ago :pray: