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

Add Node.js Support #710

Merged
merged 16 commits into from
Jul 19, 2024
Merged
34 changes: 34 additions & 0 deletions docs/nodejs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Node.js

Altis supports running Node.js applications alongside WordPress, utilizing WordPress as a headless API.

## Enabling Node.js in Local Server

Node.js can be enabled in Local Server by adding `extra.altis.modules.local-server.nodejs` in the project's `composer.json`

```json
{
"extra":{
"altis":{
"modules":{
"local-server":{
"nodejs":{
"path":"../altis-nodejs-skeleton"
}
}
}
}
}
}
```

`path` is relative to the directory where `composer.json` lives.

## Setting Node.js Version
Similar to configuring the Altis infrastructure, the Local Server determines the Node.js version to use based on the `engines.node` value found in the `package.json` at the specified `path`.

## Running Development Server
Once configured, the Local Server executes `npm run dev` inside the Node.js container at the specified path. This command watches for changes and recompiles necessary files.
Copy link
Contributor

Choose a reason for hiding this comment

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

I tried a new altis-skeleton with altis-nodejs-skeleton in a nodejs subdirectory. I had thought the nodejs code must live in the same repos as the Altis code.
Anyway, I saw no evidence of it having run npm run dev.
I tried looking at the nodejs container logs (I had to use vs-code) and it doesn't seem to show npm run dev instead it looks like it may have run next dev

added 23 packages, and audited 24 packages in 38s

3 packages are looking for funding
  run `npm fund` for details

1 high severity vulnerability

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

> [email protected] dev
> next dev

   ▲ Next.js 14.0.2
   - Local:        http://localhost:3000

 ✓ Ready in 1886ms
 ○ Compiling / ...
Browserslist: caniuse-lite is outdated. Please run:
  npx browserslist@latest --update-db
  Why you should do it regularly: https://github.com/browserslist/browserslist#browsers-data-updating
 ✓ Compiled / in 2.1s (201 modules)

after that, there are only get requests shown when I refresh my browser. Changing index.jsx does nothing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we get an entry in composer server logs for nodejs, please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried a new altis-skeleton with altis-nodejs-skeleton in a nodejs subdirectory. I had thought the nodejs code must live in the same repos as the Altis code.

Is this decision documented somewhere? I based this off how thehourglass manage their repo. They have front-end and backend on a separate repo.

Our skeleton uses next.js, internally it's running the npm run dev https://github.com/humanmade/altis-local-server/pull/710/files#diff-6e1aa008277f9688efac7746b347e1e418cfc7b7e36f5bec209e48022d735022R263

I'll check the auto-recompile and adding log entry.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mikelittle

  • Auto-recompile and reload working correctly for me.
  • Added nodejs entry in composer server logs

We also support having the nodejs code in the same repository by pointing to it using nodejs.path

Screen.Recording.2024-07-17.at.16.36.55.mov

Copy link
Contributor

Choose a reason for hiding this comment

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

Is this decision documented somewhere? I based this off how thehourglass manage their repo. They have front-end and backend on a separate repo.

I got the node app location information from this notion page but it must have moved on. No worries.

The live reload still doesn't work for me. But I'll put that down to my setup.

Copy link
Member

Choose a reason for hiding this comment

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

The docs are the better place to consult; they're separate repos as we changed that decision based on feedback. It does also make me wonder if we might want the server separate as a result 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rmccue Separate server meaning separate from Local Server?

Given our current setup, it makes sense for it to be part of the Local Server for now. When deployed, Node.js runs alongside WordPress. We currently assume that there's always a WordPress instance paired with the front-end in Altis.


## Accessing the Application
This setup makes the application accessible at `https://nodejs-{project-name}.altis.dev`.
8 changes: 8 additions & 0 deletions inc/composer/class-command.php
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,13 @@ protected function start( InputInterface $input, OutputInterface $output ) {
$output->writeln( '<info>Startup completed.</>' );
$output->writeln( '<info>To access your site visit:</> <comment>' . $site_url . '</>' );

if ( static::get_composer_config()['nodejs'] ?? false ) {
$tld = $this->get_project_tld();
$subdomain = $this->get_project_subdomain();
$hostname = $subdomain . '.' . $tld;
$output->writeln( '<info>To access your Node.js site visit:</> <comment>https://nodejs-' . $hostname . '</>' );
}

$this->check_host_entries( $input, $output );

return 0;
Expand Down Expand Up @@ -570,6 +577,7 @@ protected function logs( InputInterface $input, OutputInterface $output ) {
'redis',
's3',
'xray',
'nodejs',
],
0
);
Expand Down
49 changes: 49 additions & 0 deletions inc/composer/class-docker-compose-generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,50 @@ protected function get_service_php() : array {
];
}

/**
* Get the NodeJS container service.
*
* @return array
*/
protected function get_service_nodejs() : array {
$config = $this->get_config();

// Read package.json from nodejs.path to get the Node.js version to use.
$package_json = json_decode( file_get_contents( "{$config['nodejs']['path']}/package.json" ), true );
$version = $package_json['engines']['node'] ?? '20';

return [
'nodejs' => [
'image' => "node:{$version}-bookworm-slim",
'container_name' => "{$this->project_name}-nodejs",
'ports' => [
'3000',
],
'volumes' => [
"../{$config['nodejs']['path']}/:/usr/src/app",
],
'working_dir' => '/usr/src/app',
'command' => 'sh -c "npm install && npm run dev"',
'networks' => [
'proxy',
'default',
],
'labels' => [
'traefik.frontend.priority=1',
'traefik.port=3000',
'traefik.protocol=http',
'traefik.docker.network=proxy',
"traefik.frontend.rule=HostRegexp:nodejs-{$this->hostname}",
"traefik.domain=nodejs-{$this->hostname}",
],
'environment' => [
'ALTIS_ENVIRONMENT_NAME' => $this->project_name,
'ALTIS_ENVIRONMENT_TYPE' => 'local',
],
],
];
}

/**
* Webgrind service container for viewing Xdebug profiles.
*
Expand Down Expand Up @@ -813,6 +857,10 @@ public function get_array() : array {
$services = array_merge( $services, $this->get_service_webgrind() );
}

if ( $this->get_config()['nodejs'] ) {
$services = array_merge( $services, $this->get_service_nodejs() );
}

// Default compose configuration.
$config = [
// 'version' => '2.5',
Expand Down Expand Up @@ -914,6 +962,7 @@ protected function get_config() : array {
'ignore-paths' => [],
'php' => '8.1',
'mysql' => '8.0',
'nodejs' => $modules['nodejs'] ?? false,
];

return array_merge( $defaults, $modules['local-server'] ?? [] );
Expand Down