Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to build SSR with quasar extension using Docker multi-stage build #6352

Closed
thr0n opened this issue Feb 12, 2020 · 5 comments
Closed

How to build SSR with quasar extension using Docker multi-stage build #6352

thr0n opened this issue Feb 12, 2020 · 5 comments

Comments

@thr0n
Copy link

thr0n commented Feb 12, 2020

I'd like to create the SSR production build of my quasar app using Docker multi-stage build (details about this pattern can be found for example here: https://codefresh.io/docker-tutorial/node_docker_multistage/).

So basically this is what I'm doing in my Dockerfile:

First stage - Build the app:

  1. Use a node Docker image as builder container
  2. Install node_modules using yarn install
  3. Create the ssr build using quasar build -m ssr
  4. cd into ./dist/ssr and execute yarn install to install dependencies needed for production

Second stage - Serve the app:

  1. Use a second node image as production container
  2. copy dist/ssr contents from the builder container to /app inside the production container
  3. Run CMD node index.js to serve the app

Now here's the issue: I'm using @quasar/quasar-app-extension-qmarkdown (added to my project using quasar ext add @quasar/qmarkdown) which has been automatically installed as a devDependency. Consequently qmarkdown and its dependencies (e.g. markdown-it) are missing in the production package.json file and they cannot be found at runtime:

Error: Cannot find module 'markdown-it' from '/app'
    at Function.resolveSync [as sync] (/app/node_modules/resolve/lib/sync.js:81:15)
    at r (/app/node_modules/vue-server-renderer/build.dev.js:9312:44)
    at Object.5d44 (server-bundle.js:1:27965)
    at o (server-bundle.js:1:194)
    at Module.4edf (server-bundle.js:1:16859)
    at o (server-bundle.js:1:194)
    at Object.0 (server-bundle.js:1:1423)
    at o (server-bundle.js:1:194)
    at module.exports.0 (server-bundle.js:1:1384)
    at Object.<anonymous> (server-bundle.js:1:1393) {
  code: 'MODULE_NOT_FOUND'
}

Is there a way to treat qmarkdown as a production dependency or to transfer the extension dependencies to the dist/ssr directory?

@thr0n
Copy link
Author

thr0n commented Feb 13, 2020

Addition: Of course I can just run yarn add @quasar/quasar-app-extension-qmarkdown to add qmarkdown as a production dependency. But shouldn't it be possible to achieve this by using quasar ext add? E.g. by the help of a flag?

@TobyMosque
Copy link
Contributor

TobyMosque commented Feb 13, 2020

maybe that will help u.:
my Dockerfile:

# develop stage
FROM node:13.8-alpine as develop-stage
WORKDIR /app
COPY package*.json ./
RUN npm i -g @quasar/cli@latest
RUN npm i -g pm2@latest
COPY . .

# local-deps
FROM develop-stage as local-deps-stage
RUN yarn

# build stage
FROM local-deps-stage as build-stage
RUN quasar build -m ssr
CMD ["pm2-runtime", "dist/ssr/index.js"]

# dev stage
# FROM local-deps-stage as dev-stage
# RUN quasar dev -m ssr

my docker-compose.yml

version: '3.7'

services:
  quasar_webapp:
    restart: always
    container_name: quasar_webapp
    build:
      context: ./webapp
      target: 'build-stage'
      dockerfile: .docker/Dockerfile
    volumes:
      - webapp:/app
    networks:
      - internal_network
    ports:
      - "23123:3000"
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.couchdb_master.loadbalancer.server.port=3000"
      - "traefik.http.routers.couchdb_master.rule=Host(`app.localhost`)"
      - "traefik.http.routers.couchdb_master.entrypoints=web"
      - "traefik.docker.network=internal_network"

  traefik_proxy:
    container_name: traefik_proxy
    image: traefik:latest
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    networks:
      - internal_network
      - external_network
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

volumes:
  webapp:

networks:
  internal_network:
    internal: true
  external_network:
    external: true

Of course, I'm copying the whole source to the image.
Maybe @hawkeye64 can handle that directly in the extension, checking if the @quasar/quasar-ui-qmarkdown is installed.:

if (isServer) {
  api.compatibleWith('@quasar/quasar-ui-qmarkdown', '1.0.23')
}

PS.:

that is my directory structure.:

root/
├── restapi/
│ └── .docker
│   └── Dockerfile
├── webapp/
│ ├── .docker
│ | └── Dockerfile
│ ├── src/
│ └── src-ssr/
└── docker-compose.yml

@hawkeye64
Copy link
Member

hawkeye64 commented Feb 13, 2020

@thr0n The flag does not exist, but I agree. Some app-exts are for build time and should go into devDependencies and some are for run-time and should go into dependencies.
Something similar to this should be added:

quasar ext add @quasar/qmarkdown -dev
# or
quasar ext add @quasar/qmarkdown -dep

where the default is dev (for backwards compatibility).

Maybe this is something @rstoenescu would consider.

@rstoenescu
Copy link
Member

Hi,

Please discuss within the community. We're trying to keep github tickets mainly for bug reports. Thank you.

@hawkeye64
Copy link
Member

hawkeye64 commented May 20, 2020

@thr0n To do what you want, in the interim, remove the QMarkdown app-extension (but, only if you are not importing *.md or *.vmd files).
Install into dependencies - quasar-ui-qmarkdown
You will need to write your own boot file (so, basically treat as Vue CLI install -- see instructions on site)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants