Quasar: [docs] Deploy SSR to AWS Amplify / Firebase

Created on 6 Feb 2020  ·  6Comments  ·  Source: quasarframework/quasar

I can’t deploy quasar ssr app to aws amplify or firebase.
Is that possible?

docs

Most helpful comment

create that files.:
./.firebaserc

{
  "projects": {
    "default": "{project-name}"
  }
}

./firebase.json

{
  "hosting": {
    "public": "dist/ssr",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "function": "ssrapp"
      }
    ]
  },
  "functions": {
    "source": "dist/ssr"
  }
}

./src-ssr/__index.js

let server = require('./server/index.js')
exports.ssrapp = server.ssrapp

add the follow packages.:

yarn add firebase-admin firebase-functions

modify your ./src-ssr/index.js

/*...*/

const
  functions = require('firebase-functions'),
  express = require('express'),
  compression = require('compression')

const
  ssr = require('../ssr'),
  extension = require('./extension'),
  app = express()

const serve = (path, cache) => express.static(ssr.resolveWWW(path), {
  maxAge: cache ? 1000 * 60 * 60 * 24 * 30 : 0
})

// gzip
app.use(compression({ threshold: 0 }))

// serve this with no cache, if built with PWA:
if (ssr.settings.pwa) {
  app.use('/service-worker.js', serve('service-worker.js'))
}

// serve "www" folder
app.use('/', serve('.', true))

// we extend the custom common dev & prod parts here
extension.extendApp({ app })

// this should be last get(), rendering with SSR
app.get('*', (req, res) => {
  res.setHeader('Content-Type', 'text/html')
  ssr.renderToString({ req, res }, (err, html) => {
    if (err) {
      if (err.url) {
        res.redirect(err.url)
      } else if (err.code === 404) {
        res.status(404).send('404 | Page Not Found')
      } else {
        // Render Error Page or Redirect
        res.status(500).send('500 | Internal Server Error')
        if (ssr.settings.debug) {
          console.error(`500 on ${req.url}`)
          console.error(err)
          console.error(err.stack)
        }
      }
    } else {
      res.send(html)
    }
  })
})

// app.listen(port, () => {
//   console.log(`Server listening at port ${port}`)
// })
exports.ssrapp = functions.https.onRequest(app)

build the project, replace the dist/ssr/index.js by src-ssr/__index.js and deploy:

quasar build -m ssr
COPY src-ssr/__index.js dist/ssr/index.js
firebase deploy --project "{project-name}"

if u're using a CI service, get a token.:

firebase login:ci

and copy the follow command to your CI.:

firebase deploy --project "{project-name}" --token "{firebase-token}"

don't forget to replace {project-name} by the project name and {firebase-token} by he ci token

All 6 comments

create that files.:
./.firebaserc

{
  "projects": {
    "default": "{project-name}"
  }
}

./firebase.json

{
  "hosting": {
    "public": "dist/ssr",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "function": "ssrapp"
      }
    ]
  },
  "functions": {
    "source": "dist/ssr"
  }
}

./src-ssr/__index.js

let server = require('./server/index.js')
exports.ssrapp = server.ssrapp

add the follow packages.:

yarn add firebase-admin firebase-functions

modify your ./src-ssr/index.js

/*...*/

const
  functions = require('firebase-functions'),
  express = require('express'),
  compression = require('compression')

const
  ssr = require('../ssr'),
  extension = require('./extension'),
  app = express()

const serve = (path, cache) => express.static(ssr.resolveWWW(path), {
  maxAge: cache ? 1000 * 60 * 60 * 24 * 30 : 0
})

// gzip
app.use(compression({ threshold: 0 }))

// serve this with no cache, if built with PWA:
if (ssr.settings.pwa) {
  app.use('/service-worker.js', serve('service-worker.js'))
}

// serve "www" folder
app.use('/', serve('.', true))

// we extend the custom common dev & prod parts here
extension.extendApp({ app })

// this should be last get(), rendering with SSR
app.get('*', (req, res) => {
  res.setHeader('Content-Type', 'text/html')
  ssr.renderToString({ req, res }, (err, html) => {
    if (err) {
      if (err.url) {
        res.redirect(err.url)
      } else if (err.code === 404) {
        res.status(404).send('404 | Page Not Found')
      } else {
        // Render Error Page or Redirect
        res.status(500).send('500 | Internal Server Error')
        if (ssr.settings.debug) {
          console.error(`500 on ${req.url}`)
          console.error(err)
          console.error(err.stack)
        }
      }
    } else {
      res.send(html)
    }
  })
})

// app.listen(port, () => {
//   console.log(`Server listening at port ${port}`)
// })
exports.ssrapp = functions.https.onRequest(app)

build the project, replace the dist/ssr/index.js by src-ssr/__index.js and deploy:

quasar build -m ssr
COPY src-ssr/__index.js dist/ssr/index.js
firebase deploy --project "{project-name}"

if u're using a CI service, get a token.:

firebase login:ci

and copy the follow command to your CI.:

firebase deploy --project "{project-name}" --token "{firebase-token}"

don't forget to replace {project-name} by the project name and {firebase-token} by he ci token

quasar build -m ssr
I can't find the dist /server dir, I only have these directories

dist
└── ssr
    ├── www
    ├──index.js
    ├──quasar.client-manifest.json
    └── quasar.server-manifest.json   

dist/ssr :)

Here is the updated solution I've came up with: https://stackoverflow.com/a/63843922/884143

  1. After having initialized your firebase project in the root of your project folder with firebase init, open the generated firebase.json:
{
  "hosting": {
    "public": "dist/ssr",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [{
      "source": "**",
      "function": "ssrapp" // <- This NAME should be the same as in /src-ssr/index.js
    }]
  },
  "functions": {
    "source": "dist/ssr"
  }
}
  1. Install dependencies yarn add firebase-admin firebase-functions

  2. Open and edit /src-ssr/index.js:

// BEGINNING OF THE FILE
const functions = require('firebase-functions') // <---- ADD FIREBASE FUNCTIONS

const
  express = require('express'),
  compression = require('compression')

const
  ssr = require('quasar-ssr'),
  extension = require('./extension'),
  app = express(),
  port = process.env.PORT || 3000
...
...
...
// END OF THE FILE

// COMMENT or DELETE following 3 lines of app.listen function
// app.listen(port, () => {
//   console.log(`Server listening at port ${port}`)
// })

exports.ssrapp = functions.https.onRequest(app) // <- "ssrapp" name is the same as in firebase.json
  1. Now build the SSR app with quasar build -m ssr

  2. In your terminal, go to ./dist/ssr/ and run yarn install to install node modules.

  3. Finally go back to your root path "./" and test before deployment with firebase serve command. It will be available at port 5000 as usual. localhost:5000

@danieltorscho Does your solution for the /src-ssr/index.js include all the other express code from @TobyMosque's solution?

I am getting 500s when deploying using the combination of both index.js files.

I was building without putting in my QENV 🤦

QENV

What does QENV mean ? quasar environement variable ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexeigs picture alexeigs  ·  3Comments

adwidianjaya picture adwidianjaya  ·  3Comments

green-mike picture green-mike  ·  3Comments

wc-matteo picture wc-matteo  ·  3Comments

Bangood picture Bangood  ·  3Comments