business-cargo-cargo-container-163726.jpg

Deploy your Nuxt.js app to platform.sh

  • Pascal Thormeier

Nuxt.js allows to create Vue apps fast. Deploying it to Heroku, Now, GitHub, and more is already covered - but what about platform.sh?

Nuxt.js is Vue's version of Next.js for React. It's a "framework for creating Universal Vue.js Applications." Getting started with Nuxt.js is rather straight forward, the guides help a lot. platform.sh is a cloud hosting provider we use a lot at Liip. Configuring platform.sh to serve any kind of app is also pretty straight forward, as there's a lot of guides for all kinds of apps.

I started building a microsite. Nothing too fancy. As I was familiar with Vue, I wanted to give Nuxt.js a try and created this app as a single page application. So I created a skeleton of the app, included a header, a bit of navigation and an image or two and was ready to deploy the first version of it somewhere, so stakeholders could actually have a look at it. I've already used platform.sh for various other apps before, so I figured it would be fit for a Vue SPA.

Since this was my first Nuxt.js app, I tried to figure out how to deploy it to platform.sh, but didn't find any resources. I decided to share the steps and config needed in order to deploy it.

Vue rendered

Nuxt's documentation is pretty straight forward when it comes to deployment. There's essentially three commands that need to be run in order to get a fresh copy of a Nuxt app running:

npm install
npm run build
npm start

And these commands are exactly what is needed in order to deploy the app. Most important: There's no need for any special Nuxt config. The out-of-the-box config should be enough.

To configure an app for platform.sh, there's three files needed:

  • ./.platform/routes.yaml - Available routes for the app
  • ./.platform/services.yaml - Attached services, such as databases, search platforms, etc.
  • ./.platform.app.yaml - The main configuration file

First of all, the app must be configured. I'll call the app node, use a node:8.11 as its type and give it 128M disk space:

# .platform.app.yaml

name: node
type: nodejs:8.11
disk: 128

Now the build process needs to be added. This is done by adding a build hook:

# .platform.app.yaml

name: node
type: nodejs:8.11
disk: 128

# Build hook
hooks:
  build: |
    npm install
    npm run build

Afterwards, platform.sh needs to know how to start the app and what kind of locations it needs to serve. The finished .platform.app.yaml now looks like the following:

# .platform.app.yaml

name: node
type: nodejs:8.11
disk: 128

# Build hook
hooks:
  build: |
    npm install
    npm run build

# Web config
web:
  commands:
    start: npm start
  locations:
    '/':
      passthru: true

In the file .platform/routes.yaml, we also need to add a default route that passes everything it receives straight to the Nuxt process:

# .platform/routes.yaml

"https://{default}/":
    type: upstream
    upstream: "node:http"

The file .platform/services.yaml can be left empty.

That's it. Now we can go on to deploy the Nuxt app to platform.sh:

git remote add platform [...]
git push -u platform

Static pages

Static pages function a bit differently. They are generated by Nuxt during the build process and are served as static files by platform.sh. A starting point for such a configuration can be found in the platform.sh documentation.

A little bit of adjustment is needed, though.

The same starting config for name, type and disk size can be used:

# .platform.app.yaml

name: node
type: nodejs:8.11
disk: 128

Now, instead of running npm run build in the build hook, we let Nuxt generate static files via npm run generate:

# .platform.app.yaml

name: node
type: nodejs:8.11
disk: 128

hooks:
  build: |
    npm install
    npm run generate

... and let platform.sh serve everything in the dist/ folder as a static page:

# .platform.app.yaml

name: node
type: nodejs:8.11
disk: 128

hooks:
  build: |
    npm install
    npm run generate

web:
  commands:
    start: sleep infinity
  locations:
    '/':
      root: dist
      index:
         - index.html
      rules:
          \.(css|js|gif|jpe?g|png|ttf|eot|woff2?|otf|html|ico|svg?)$:
              allow: true
          ^/robots\.txt$:
              allow: true

Note the start command: by letting the whole app sleep for an infinite amount of time, we're not actually executing anything. Only the static files are served.

The files .platform/routes.yaml can stay the same:

# .platform/routes.yaml

"https://{default}/":
    type: upstream
    upstream: "node:http"

Also, the file .platform/services.yaml stays empty. The actual deployment then happens the same way:

git remote add platform [...]
git push -u platform

Takeaway thoughts

Platform.sh and Nuxt.js really play well together. Combining the two was less complex than I originally thought and the sheer speed of both make development, for me, loads of fun. Almost as much fun as sharing knowledge and learning new things.


Tell us what you think