Deploy a server-rendered site
Run the built app as a node service behind a web server, on your own host or a container platform like Lagoon.
Before you start: read Deployment models to confirm you need a server. Static hosting is cheaper and simpler when it fits.
A server-rendered Druxt site is a node process:
nuxt build
nuxt start
nuxt start reads HOST and PORT (see Environment
variables) and serves live-rendered
pages. Run it under a supervisor (systemd, PM2, or a container
platform's own runtime) so it restarts on failure, and put a web server
or the platform's ingress in front for TLS.
The API proxy works in this model, so browsers can talk
only to the frontend origin, and server middleware can hold secrets
(mail delivery, search services) via privateRuntimeConfig.
Behind nginx
A minimal reverse proxy:
server {
listen 443 ssl http2;
server_name www.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Add caching for anonymous traffic once things work. One caution from production: anything that sets cookies on every response (some auth setups do) makes responses uncacheable; keep anonymous responses cookie-free so a CDN or cache in front can do its job.
The hybrid: static files with a server fallback
Production Druxt sites often combine the models: nginx serves the
nuxt generate output directly with long cache headers, and passes
anything not generated (authenticated pages, server routes) to the node
service:
location / {
root /app/dist;
try_files $uri $uri/index.html @node;
}
location @node {
proxy_pass http://127.0.0.1:3000;
}
Most traffic gets CDN-grade static delivery; the node service only works
for the routes that need it. Driving the build target with an
environment variable (NUXT_TARGET) lets one codebase produce both
builds.
On a container platform
On Lagoon (which hosts this site) the same shapes
map to services: a node service running nuxt start, or the hybrid as
an nginx service whose image contains the generated files plus a
node fallback service. The build runs in the image build, which means:
- Environment variables the build needs must reach the image build (declared as build arguments), not just the running container. This is true of any Docker-based platform.
- The backend must be reachable from the builder. Gate the build on the
backend answering (
curlits/jsonapiuntil 200), and retry the build once or twice, because large generates can fail transiently.
Content freshness
Server-rendered pages are live. Generated pages in the hybrid are not: rebuild on a schedule, or from a Drupal webhook, whichever matches how often editors publish. The rebuild options in Deploy a static site apply to the hybrid's static half unchanged.
Where to go next
- Environment variables: the build-time vs runtime distinction matters most in this model.
- Proxy the Drupal backend: single-origin browser traffic.
- Authenticate users with OAuth: server deployments unlock the full authenticated experience.