Closed ataylorme closed 5 years ago
I could be wrong, but I think Node needs to be installed in appserver
in addition to another container. Node needs to be in the appserver
container for running Grunt. This is separate from Node that is used to actually run a server which would indeed be in another container.
@ataylorme I did what you said initially, and just couldn't get it to work for the reasons @westonruter outlined.
Maybe I did something wrong while doing that, but connecting the separate Node service so that I can call npm
and grunt
from appserver
when SSHd in via lando ssh
just didn't work.
@ataylorme or would that be best done by letting the Node service have access to the same filesystem as the appserver? I don't know if that's even possible.
@westonruter yes, any new services you add to Lando will have access to the file system. My recommendation would be a Node service using a Dockerfile that has Node and Grunt installed. See my snippet in #1 for how I do that. My example is gulp but Grunt should be an easy switch.
If you wanted to run an express server or some other backend Node process you could use the same service or have separate ones. I prefer to separate services and their tasks by language (JS, PHP, etc.) but it comes down to preference. I prefer multiple, smaller services that do a few things well to one monolithic service.
Commands can be mapped to services with the tooling
declaration. So if you had a service named node
then the snippet below would allow you to run lando grunt
which would run the command grunt
inside the node
service container. It will be run relative to the current local directory, so you could run it from the project root, a plugin, theme, etc.
tooling:
grunt:
service: node
Similarly, you can run bash scripts (or anything really) with Lando commands. Below is my example that calls a bash script that will find gulp files throughout the project and run npm install
and gulp
in their directory with lando gulp-build
. I like this as I can run the same scripts/processes locally that I use in CI services.
tooling:
gulp-build:
description: Install npm dependencies and run gulp
cmd: ./.circleci/build-gulp-assets.sh
service: node
I prefer to separate services and their tasks by language (JS, PHP, etc.) but it comes down to preference. I prefer multiple, smaller services that do a few things well to one monolithic service.
Here's a complication that maybe you have some advice for. The Grunt command to build the AMP plugin depends on Node, obviously, but it also needs to invoke WP-CLI:
https://github.com/ampproject/amp-wp/blob/9958f6fcae2b1fb39ae3f35e90df6a91de8026b5/Gruntfile.js#L41
Would this not require that Node and WP-CLI be installed on the same service?
Would this not require that Node and WP-CLI be installed on the same service?
Yes, unless you split the Grunt command up and ran the Node parts in a Node service and the wp-cli parts in appserver
.
Again, these decisions are just preference. I don't think the advantages of using separate services outweighs the hassle it would take to modify/modularize your Grunt build process.
The Lando Slack instance is a great place to have a discussion like this to get multiple opinions.
To clarify, when you use a separate node
service, you can do lando npm
, but not lando ssh
and then npm
right?
You could still do lando ssh node
to SSH into the Node container. In that container npm
would be available.
Ah okay, I didn't know that. It still feels odd to me that you can't lando ssh
in and then do grunt
and phpunit
from the same session. Maybe that's just me not having used lando ...
commands before though.
I didn't know that. It still feels odd to me that you can't
lando ssh
in and then dogrunt
andphpunit
from the same session.
Two thoughts on this
1) You should not ssh
into each service to run commands. SSH is really for debugging. You should use be using the tooling feature to create Lando commands that run what you need in the container. For example, lando grunt
could run grunt
. See this doc on how to set that up
2) You can do that if the service (container) has all the requirements, in this case PHP and Node. When using Docker though it is best (in my opinion) to create separate services/containers rather than having a monolithic container that does all the things. If you have that set up then there is really not much difference from a VM solution like VVV. The advantage containers have is being able to have them be more lightweight and set up to do one job and so efficiently.
- When using Docker though it is best (in my opinion) to create separate services/containers rather than having a monolithic container that does all the things.
Yeah, that makes sense. However, both Node and PHP need to be in the same container here for WP-CLI and Node to be able to call each other.
I'm not sure if you can call one service from another. I asked in the Lando Slack for you though.
The answer is in. In rc.1+
you can set up tooling commands that call multiple services
mycommand:
# Run our two build steps
cmd:
- service1: command1
- service2: command2
So you can probably split the shell commands in the AMP Grunt process in this way.
build_amp:
# Run our two build steps
cmd:
# Readme
- appserver: ./dev-lib/generate-markdown-readme
# PHP Unit
- appserver: phpunit
# Verify matching version
- appserver: php bin/verify-version-consistency.php
# Webpack production
- node: cross-env BABEL_ENV=production webpack
# pot to PHP part 1
- node: npm run pot-to-php
# pot to PHP part 1
- appserver: php -l languages/amp-translations.php
# makepot
- appserver: wp i18n make-pot . languages/amp-js.pot --include="*.js" --file-comment="*/null/*"
# Create build .zip
- appserver: if [ ! -e build ]; then echo "Run grunt build first."; exit 1; fi; if [ -e amp.zip ]; then rm amp.zip; fi; cd build; zip -r ../amp.zip .; cd ..; echo; echo "ZIP of build: $(pwd)/amp.zip"
@ataylorme thanks, but this will require the general Lando environment to have a command specifically for the AMP plugin. In other words, we wouldn't be able to package a build command in the AMP plugin for use in an arbitrary environment if php
and node
aren't available on the same container. It seems the only way to achieve that would be to allow two containers to invoke commands on each other, but this does not seem feasible according to a subsequent reply in Slack:
having
service1
be able to invoke some command inservice2
is definitely a much more tricky endeavor so tricky that i dont think we intend to ever support something like that
So I don't think having separate services is practical, even though it is surely more pure.
So I don't think having separate services is practical, even though it is surely more pure.
I agree for this use case. Closing this out. We cam work on a Dockerfile that supports Node and PHP in #1
Rather than adding Node to the existing
appserver
service a new service for node should be used. One of the advantages of Docker is being able to use containers focused on one task.Lando does this out of the box with different services for PHP, the database, Redis, etc.
See the setting up additional services doc and my
.lando.yml
for an example