Render Modes (SSR/Streaming) [Experimental]

Deployments

Up until now when deploying a Redwood app you’ve only needed a server for the api side. The web side could be served as static files from a CDN. With Render Modes this changes. You now need a frontend server too. Because of this none of our official deployment guides or 3rd party integrations work out of the box.

It’s worth repeating that the Render Mode experiment isn’t ready for production yet. But if you do want to try to deploy your app we’ve got two documented options for you. Using fly.io and doing a Baremetal deploy.

fly.io

Deploying with fly.io is by far the easiest option. And before we officially launch Render Modes we’re going to make it even easier!

Install the fly CLI tools if you haven’t already. Then you just run fly launch and answer the prompts. Just make sure to answer “No” when it asks if you want to deploy. The CLI will generate a few files. You’re going to have to modify two of them. Start by updating .fly/start.sh. Replace the npx rw-server command with these two lines

node node_modules/@redwoodjs/api-server/dist/index.js api &
yarn rw-serve-fe

And then you’ll have to switch to development mode in Dockerfile. Find the first ENV NODE_ENV and change it from development to production. And finally you have to make it copy over the api side files before building the web side so that your route hooks can access the api side code. Just add COPY api api before COPY web web.

That should be it. Commit all changes and run fly deploy

Baremetal

This is an advanced topic. Click to show

Do a normal Baremetal deployment setup. Then update ecosystem.config.js to look like this

module.exports = {
  apps: [
    {
      name: 'api',
      cwd: 'current',
      script: 'node_modules/.bin/rw',
      args: 'serve api',
      instances: 'max',
      exec_mode: 'cluster',
      wait_ready: true,
      listen_timeout: 10000,
    },
    {
      name: 'fe',
      cwd: 'current/web',
      script: 'yarn',
      args: 'rw-serve-fe',
      instances: 'max',
      exec_mode: 'cluster',
      wait_ready: true,
      listen_timeout: 10000,
    },
  ],
}

This makes sure we run both the api server and the frontend server inside pm2.
You also have to log in to your server and update the nginx config.
At the top I define two upstreams:

upstream redwood_api_server {
  server 127.0.0.1:8911 fail_timeout=0;
}

upstream redwood_fe_server {
  server 127.0.0.1:8910 fail_timeout=0;
}

And then in the server block I use them like this

  location ~ /.redwood/functions(.*) {
    rewrite ^/.redwood/functions(.*) $1 break;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://redwood_api_server;
  }

  location / {
    # try_files $uri /200.html =404;
    proxy_pass http://redwood_fe_server;
  }

Restart nginx and you should be able to access your RW app.

1 Like