Skip to content

NEX-195: Allow the frontend to access the backend via internal url in runtime #289

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

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

vermario
Copy link
Collaborator

@vermario vermario commented Apr 12, 2025

This PR introduces the concept of an internal url to access drupal from the frontend.

The backend needs to be accessible by a public URL for these reasons:

  1. the editors need to log into the site and do their content editing work
  2. in our example, there is a flow where the user asks to register on the frontend, gets an email with the link to go to drupal and set the password, gets redirected back
  3. the build of the site is done in our case by CircleCI and it's not feasible to allow access to the internal url because the circle ci agent does not have a predictable IP.

But, it would be useful for the node.js process running in next.js to access the backend also with an internal URL. In SILTA, this means that the data flows inside the same cluster, and does not involve our CDN.

One thing that we had to take into consideration was the fact that we are using next-image, and both the internal and external urls need to be allowed as source for the images.

I have added the same concept to the lando and ddev setups, because hopefully this would allow us to catch subtle bugs in case we are using the wrong internal/external url for drupal there.

Summary of the changes:

Configuration Updates:

  • .circleci/config.yml: Added environment variables DRUPAL_BASE_URL_INTERNAL and DRUPAL_BASE_URL_INTERNAL_IMAGES to handle internal URLs and ensure they are used within CircleCI. [1] [2] [3]
  • .ddev/config.yaml: Added DRUPAL_BASE_URL_INTERNAL and DRUPAL_BASE_URL_INTERNAL_IMAGES for local development.
  • .lando.yml: Added DRUPAL_BASE_URL_INTERNAL and DRUPAL_BASE_URL_INTERNAL_IMAGES for Lando environments.
  • silta/silta-next.yml: Added DRUPAL_BASE_URL_INTERNAL and DRUPAL_BASE_URL_INTERNAL_IMAGES for Silta environments.

Code Updates:

…main

* for now in silta it's set to the same as the external one
Base automatically changed from NEX-194 to main April 14, 2025 06:25
@vermario vermario changed the title NEX-195: Add a separate env var for the backend, using an internal do… NEX-195: Allow the frontend to access the backend via internal url in runtime Apr 15, 2025
@vermario vermario requested a review from MarttiR April 16, 2025 05:31
@hkirsman
Copy link
Collaborator

hkirsman commented Apr 23, 2025

I liked also this explanation from Slack thread:

Main issue:

If the frontend uses the fastly-protected public url for drupal, we unnecessarily generate
fastly traffic (since drupal also runs behind fastly, as for our normal procedures), and we
might incur in issues with rate limiting (since the frontend is seen as an individual "client"
doing a lot of calls, and it might be blocked,

Copy link
Collaborator

@Zionknight-crypto Zionknight-crypto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, not the greatest at configs but this looks clear enough. Where exactly do we retrieve and see these internal urls? It would be great to document this with a short readme eventually.

@vermario
Copy link
Collaborator Author

I found this issue in tests:
image

basically the email link is generated using the internal url for drupal this way... will have to fix

@vermario
Copy link
Collaborator Author

vermario commented May 3, 2025

I found this issue in tests: image

basically the email link is generated using the internal url for drupal this way... will have to fix

Fixed in b5cfb18

@vermario vermario requested a review from mgalang May 5, 2025 07:48
Copy link
Member

@joshua-scott joshua-scott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach here is now working nicely on a live site too! A few comments from that implementation to consider, then this should be good to go

Comment on lines +143 to +144
DRUPAL_BASE_URL_INTERNAL: http://appserver_nginx.nextdrupalstarterkit.internal
DRUPAL_BASE_URL_INTERNAL_IMAGES: http://appserver_nginx.nextdrupalstarterkit.internal
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In lando also just http://appserver_nginx should work, I don't think the .nextdrupalstarterkit.internal part is needed. I suppose it's one less thing that would need to be changed later

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 339c79a

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi! unfortunately with this change the lando setup did not work anymore (could not get data from the backend). I reverted it in 4fc3bfb and now it works again.

},
{
protocol: imageHostnameInternal[0] === "https" ? "https" : "http",
hostname: imageHostnameInternal[1],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In another project, we kept logic for this in one place like this:

remotePatterns: [
    process.env.DRUPAL_BASE_URL_INTERNAL_IMAGES,
    process.env.NEXT_PUBLIC_DRUPAL_BASE_URL,
  ].map((url = "") => {
    const [protocol, hostname] = url.split("://");
    if (!hostname || (protocol !== "https" && protocol !== "http")) {
      throw new Error(`Invalid images URL "${url}" in next.config.ts`);
    }
    return {
      protocol,
      hostname,
      pathname: "**",
    };
  }),

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 70bd4b6

@@ -34,7 +34,7 @@ const options: HTMLReactParserOptions = {
if (isRelative(src)) {
return (
<Image
src={`${env.NEXT_PUBLIC_DRUPAL_BASE_URL}${src}`}
src={`${env.DRUPAL_BASE_URL_INTERNAL}${src}`}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think here we should actually use NEXT_PUBLIC_DRUPAL_BASE_URL, or are we 100% sure this component will only ever load from the server?

In another project (pages router but otherwise very similar) where this line in FormattedText caused an error "Attempted to access a server-side environmental variable on the client", so had to change this one

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 035ebbe

This avoids the need for projects to update the value later
This avoids the possibility of trying to access a server env var on the client
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

Successfully merging this pull request may close these issues.

6 participants