Reactive-Resume icon indicating copy to clipboard operation
Reactive-Resume copied to clipboard

[BUG] PDF Download not working

Open mattlathrop opened this issue 2 years ago • 33 comments

Describe the bug PDF Download gives 500 Internal Server Error

To Reproduce

  1. Create new resume (I called it test)
  2. Click the download PDF button
  3. The network console shows a 500 error after awhile.

Expected behavior PDF should be created and downloaded

Additional context

[Nest] 42 - 03/16/2022, 1:44:41 PM ERROR [ExceptionsHandler] page.waitForSelector: Timeout 30000ms exceeded.
--
Wed, Mar 16 2022 8:44:41 am | =========================== logs ===========================
Wed, Mar 16 2022 8:44:41 am | waiting for selector "html.wf-active" to be visible
Wed, Mar 16 2022 8:44:41 am | ============================================================
Wed, Mar 16 2022 8:44:41 am | page.waitForSelector: Timeout 30000ms exceeded.
Wed, Mar 16 2022 8:44:41 am | =========================== logs ===========================
Wed, Mar 16 2022 8:44:41 am | waiting for selector "html.wf-active" to be visible
Wed, Mar 16 2022 8:44:41 am | ============================================================
Wed, Mar 16 2022 8:44:41 am | at PrinterService.printAsPdf (/app/server/dist/printer/printer.service.js:40:20)

mattlathrop avatar Mar 16 '22 13:03 mattlathrop

Have you self-hosted the app? Have you added a secret key to the env system?

AmruthPillai avatar Mar 17 '22 11:03 AmruthPillai

Hello, I have the same error with an SECRET_KEY defined.

.env

# App
TZ=Europe/Paris
SECRET_KEY=7e885874-a543-11ec-a459-00155d553b9b

# URLs
PUBLIC_URL=http://localhost:3000
PUBLIC_SERVER_URL=http://localhost:3100/api

# Database
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USERNAME=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DATABASE=postgres
POSTGRES_SSL_CERT=

# Auth
JWT_SECRET=change-me
JWT_EXPIRY_TIME=604800

# Google
PUBLIC_GOOGLE_CLIENT_ID=change-me
GOOGLE_CLIENT_SECRET=change-me
GOOGLE_API_KEY=change-me

# SendGrid (Optional)
SENDGRID_API_KEY=
SENDGRID_FORGOT_PASSWORD_TEMPLATE_ID=
SENDGRID_FROM_NAME=
SENDGRID_FROM_EMAIL=

logs:

[client] wait  - compiling /[username]/[slug]/printer (client and server)...
[client] event - compiled client and server successfully in 1084 ms (12461 modules)
[client] wait  - compiling / (client and server)...
[client] event - compiled client and server successfully in 940 ms (12620 modules)
[client] error - Error: socket hang up
[client] wait  - compiling /_error (client and server)...
[client] wait  - compiling / (client and server)...
[client] event - compiled client and server successfully in 2.1s (12461 modules)
[client] event - compiled client and server successfully (12505 modules)
[server] [Nest] 21116  - 03/17/2022, 1:00:48 PM   ERROR [ExceptionsHandler] page.waitForSelector: Timeout 30000ms exceeded.
[server] =========================== logs ===========================
[server] waiting for selector "html.wf-active" to be visible
[server] ============================================================
[server] page.waitForSelector: Timeout 30000ms exceeded.
[server] =========================== logs ===========================
[server] waiting for selector "html.wf-active" to be visible
[server] ============================================================
[server]     at PrinterService.printAsPdf (/home/enzo/Reactive-Resume/server/src/printer/printer.service.ts:35:16)
[server] [Nest] 21116  - 03/17/2022, 1:01:04 PM   ERROR [ExceptionsHandler] Request failed with status code 400
[server] Error: Request failed with status code 400
[server]     at createError (/home/enzo/Reactive-Resume/node_modules/.pnpm/[email protected]/node_modules/axios/lib/core/createError.js:16:15)
[server]     at settle (/home/enzo/Reactive-Resume/node_modules/.pnpm/[email protected]/node_modules/axios/lib/core/settle.js:17:12)
[server]     at IncomingMessage.handleStreamEnd (/home/enzo/Reactive-Resume/node_modules/.pnpm/[email protected]/node_modules/axios/lib/adapters/http.js:322:11)
[server]     at IncomingMessage.emit (node:events:538:35)
[server]     at endReadableNT (node:internal/streams/readable:1345:12)
[server]     at processTicksAndRejections (node:internal/process/task_queues:83:21)

enzops avatar Mar 17 '22 12:03 enzops

Please Use PUBLIC_SERVER_URL=http://localhost:3100/

instead of PUBLIC_SERVER_URL=http://localhost:3100/api

It will work as expected

chandiwalaaadhar avatar Mar 17 '22 14:03 chandiwalaaadhar

I have the same issue with PUBLIC_SERVER_URL=http://localhost:3100/

enzops avatar Mar 17 '22 17:03 enzops

With docker I have the same issue

docker-compose.yml

version: '3'

services:
  postgres:
    image: postgres
    container_name: postgres
    ports:
      - 5432:5432
    env_file: .env
    volumes:
      - pgdata:/var/lib/postgresql/data

  traefik:
    image: traefik
    container_name: traefik
    command:
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
    ports:
      - 80:80
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

  server:
    image: amruthpillai/reactive-resume:server-latest
    container_name: server
    env_file: .env
    environment:
      - POSTGRES_HOST=postgres
    depends_on:
      - traefik
      - postgres
    labels:
      - traefik.enable=true
      - traefik.http.routers.server.entrypoints=web
      - traefik.http.routers.server.rule=Host(`ec2-52-58-184-203.eu-central-1.compute.amazonaws.com`) && PathPrefix(`/api/`)
      - traefik.http.routers.server.middlewares=server-stripprefix
      - traefik.http.middlewares.server-stripprefix.stripprefix.prefixes=/api
      - traefik.http.middlewares.server-stripprefix.stripprefix.forceslash=true

  client:
    image: amruthpillai/reactive-resume:client-latest
    container_name: client
    env_file: .env
    depends_on:
      - traefik
      - server
    labels:
      - traefik.enable=true
      - traefik.http.routers.client.rule=Host(`ec2-52-58-184-203.eu-central-1.compute.amazonaws.com`)
      - traefik.http.routers.client.entrypoints=web

volumes:
  pgdata:

.env

# App
TZ=Europe/Paris
SECRET_KEY=c106bff8-a640-11ec-aa72-06ab43eb872a

# URLs
PUBLIC_URL=http://ec2-52-58-184-203.eu-central-1.compute.amazonaws.com/
PUBLIC_SERVER_URL=http://ec2-52-58-184-203.eu-central-1.compute.amazonaws.com/

# Database
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USERNAME=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DATABASE=postgres
POSTGRES_SSL_CERT=

# Auth
JWT_SECRET=6b1a15c4-a544-11ec-a710-06ab43eb872a
JWT_EXPIRY_TIME=604800

# Google
PUBLIC_GOOGLE_CLIENT_ID=change-me
GOOGLE_CLIENT_SECRET=change-me
GOOGLE_API_KEY=change-me

# SendGrid (Optional)
SENDGRID_API_KEY=
SENDGRID_FORGOT_PASSWORD_TEMPLATE_ID=
SENDGRID_FROM_NAME=
SENDGRID_FROM_EMAIL=

Same with PUBLIC_SERVER_URL=http://ec2-52-58-184-203.eu-central-1.compute.amazonaws.com/api/

enzops avatar Mar 17 '22 22:03 enzops

# App
TZ=Europe/Paris
SECRET_KEY=c106bff8-a640-11ec-aa72-06ab43eb872a

# URLs
PUBLIC_URL=http://ec2-52-58-184-203.eu-central-1.compute.amazonaws.com 
PUBLIC_SERVER_URL=http://ec2-52-58-184-203.eu-central-1.compute.amazonaws.com 

# Database
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USERNAME=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DATABASE=postgres
POSTGRES_SSL_CERT=

# Auth
JWT_SECRET=6b1a15c4-a544-11ec-a710-06ab43eb872a
JWT_EXPIRY_TIME=604800

# Google
PUBLIC_GOOGLE_CLIENT_ID=change-me
GOOGLE_CLIENT_SECRET=change-me
GOOGLE_API_KEY=change-me

# SendGrid (Optional)
SENDGRID_API_KEY=
SENDGRID_FORGOT_PASSWORD_TEMPLATE_ID=
SENDGRID_FROM_NAME=
SENDGRID_FROM_EMAIL=

If you notice I have removed the forward slashes from the end of the URL, which will make this work you

Please try modifying the Docker File according to this

chandiwalaaadhar avatar Mar 18 '22 01:03 chandiwalaaadhar

I am self hosting as well. Running the instance in docker. I have set my PUBLIC_URL and PUBLIC_SERVER_URL values to the same address now and have no trailing slashes and it still does not work. I also have a SECRET_KEY defined.

mattlathrop avatar Mar 18 '22 01:03 mattlathrop

I am self hosting as well. Running the instance in docker. I have set my PUBLIC_URL and PUBLIC_SERVER_URL values to the same address now and have no trailing slashes and it still does not work. I also have a SECRET_KEY defined.

Can you share the .env file?

chandiwalaaadhar avatar Mar 18 '22 01:03 chandiwalaaadhar

Here is a partial kubeconfig file (the docker containers are running in kubernetes)

containers:
        - name: reactive-client
          image: amruthpillai/reactive-resume:client-latest
          ports:
            - containerPort: 3100
              name: reactive-client
          env:
            - name: POSTGRES_HOST
              value: localhost
            - name: POSTGRES_PORT
              value: "5432"
            - name: POSTGRES_USERNAME
              value: postgres
            - name: POSTGRES_PASSWORD
              value: postgres
            - name: POSTGRES_DATABASE
              value: postgres
            - name: GOOGLE_API_KEY
              value: <the key>
            - name: JWT_EXPIRY_TIME
              value: "604800"
            - name: JWT_SECRET
              value: <long random sting>
            - name: SECRET_KEY
              value: <long random sting>
            - name: PUBLIC_URL
              value: https://subdomain.domain.com
            - name: PUBLIC_URL_API
              value: https://subdomain.domain.com
        - name: reactive-server
          image: amruthpillai/reactive-resume:server-latest
          ports:
            - containerPort: 3000
              name: reactive-server
          env:
            - name: POSTGRES_HOST
              value: localhost
            - name: POSTGRES_PORT
              value: "5432"
            - name: POSTGRES_USERNAME
              value: postgres
            - name: POSTGRES_PASSWORD
              value: postgres
            - name: POSTGRES_DATABASE
              value: postgres
            - name: GOOGLE_API_KEY
              value: <the key>
            - name: JWT_EXPIRY_TIME
              value: "604800"
            - name: JWT_SECRET
              value: <long random sting>
            - name: SECRET_KEY
              value: <long random sting>
            - name: PUBLIC_URL
              value: https://subdomain.domain.com
            - name: PUBLIC_URL_API
              value: https://subdomain.domain.com
        - name: postgres
          image: postgres
          ports:
            - containerPort: 5432
              name: postgres
          volumeMounts:
            - name: postgres
              mountPath: /var/lib/postgresql/data
              subPath: postgres
          env:
            - name: POSTGRES_HOST
              value: localhost
            - name: POSTGRES_PORT
              value: "5432"
            - name: POSTGRES_USERNAME
              value: postgres
            - name: POSTGRES_PASSWORD
              value: postgres
            - name: POSTGRES_DATABASE
              value: postgres

I also have the following Traefik rules on my load balancer:

[http.routers]
  [http.routers.resume-rtr]
      entryPoints = ["https"]
      rule = "Host(`subdomain.domain.ax`)"
      service = "resume-svc"
      middlewares = ["chain-no-auth"]
      [http.routers.resume-rtr.tls]
        certresolver = "dns-route53"

[http.services]
  [http.services.resume-svc]
    [http.services.resume-svc.weighted.healthCheck]
    [[http.services.resume-svc.weighted.services]]
      name = "resume-svc-n1"
  [http.services.resume-svc-n1]
    [http.services.resume-svc-n1.loadBalancer]
      [http.services.resume-svc-n1.loadBalancer.healthCheck]
        path = "/"
        interval = "10s"
        timeout = "3s"
      [[http.services.resume-svc-n1.loadBalancer.servers]]
        url = "http://10.0.1.218:3000"
[http.routers]
  [http.routers.resume-api-rtr]
      entryPoints = ["https"]
      rule = "Host(`subdomain.domain.ax`) && PathPrefix(`/api`)"
      service = "resume-api-svc"
      middlewares = ["chain-no-auth", "middlewares-api-stripprefix"]
      [http.routers.resume-api-rtr.tls]
        certresolver = "dns-route53"

[http.services]
  [http.services.resume-api-svc]
    [http.services.resume-api-svc.loadBalancer]
      passHostHeader = true
      [[http.services.resume-api-svc.loadBalancer.servers]]
        url = "http://10.0.1.218:3100"

mattlathrop avatar Mar 18 '22 01:03 mattlathrop

Just to add some extra light using postman to just run a GET request to both subdomain.domain.ax/api/printer/<username>/test and 10.0.1.218:3100/printer/<username>/test produce the same result as the GUI.

mattlathrop avatar Mar 18 '22 01:03 mattlathrop

Can confirm I'm also getting the same issue.

The following error occurs:

today at 13:10:38[Nest] 42  - 03/29/2022, 1:10:38 PM   ERROR [ExceptionsHandler] page.waitForSelector: Timeout 30000ms exceeded.
today at 13:10:38=========================== logs ===========================
today at 13:10:38waiting for selector "html.wf-active" to be visible
today at 13:10:38============================================================
today at 13:10:38page.waitForSelector: Timeout 30000ms exceeded.
today at 13:10:38=========================== logs ===========================
today at 13:10:38waiting for selector "html.wf-active" to be visible
today at 13:10:38============================================================
today at 13:10:38    at PrinterService.printAsPdf (/app/server/dist/printer/printer.service.js:40:20)

My compose file:

 ###################
 ##Reactive Resume##
 ###################

  reactiveresumeserver:
    image: amruthpillai/reactive-resume:server-latest
    container_name: ReactiveResume-Server
    environment:
      - PUBLIC_URL=https://resume.$DOMAINNAME
      - POSTGRES_HOST=reactiveresumedb
      - POSTGRES_DATABASE=$RR_POSTGRES_DATABASE
      - POSTGRES_PASSWORD=$RR_POSTGRES_PASSWORD
      - POSTGRES_USER=$RR_POSTGRES_USERNAME
      - TZ=$TZ
      - SECRET_KEY=$RR_SECRET_KEY
      - JWT_SECRET=$RR_JWT_SECRET
      - JWT_EXPIRY_TIME=$RR_JWT_EXPIRY_TIME
      - PUBLIC_GOOGLE_CLIENT_ID=$RR_PUBLIC_GOOGLE_CLIENT_ID
      - GOOGLE_CLIENT_SECRET=$RR_GOOGLE_CLIENT_SECRET
      - GOOGLE_API_KEY=$RR_GOOGLE_API_KEY
    depends_on:
      - reactiveresumedb
    networks:
      pihole:
        ipv4_address: '172.22.0.140'
      isolated:
    labels: 
      - autoheal=true
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.resumeserver-rtr.entrypoints=https"
      - "traefik.http.routers.resumeserver-rtr.rule=Host(`resume.$DOMAINNAME`) && PathPrefix(`/api/`)"
      - "traefik.http.routers.resumeserver-rtr.tls=true"
      ## Middlewares
      - "traefik.http.routers.resumeserver-rtr.middlewares=chain-no-auth@file, resume-api" # No Authentication
      # - "traefik.http.routers.resumeserver-rtr.middlewares=chain-basic-auth@file" # Basic Authentication
      # - "traefik.http.routers.resumeserver-rtr.middlewares=chain-oauth@file" # Google OAuth 2.0
      # - "traefik.http.routers.resumeserver-rtr.middlewares=chain-authelia@file" # Authelia
      - "traefik.http.middlewares.resume-api.stripprefix.prefixes=/api"
      - "traefik.http.middlewares.resume-api.stripprefix.forceslash=true"
      ## HTTP Services
      - "traefik.http.routers.resumeserver-rtr.service=resumeserver-svc"
      - "traefik.http.services.resumeserver-svc.loadbalancer.server.port=3100"
    volumes:
      - $USERDIR/ReactiveResume/uploads:/app/server/dist/assets/uploads
    healthcheck:
      test: curl -fSs http://localhost:3100/health || exit 1
      interval: 30s
      timeout: 5s
      retries: 3
    restart: always

  reactiveresumeclient:
    image: amruthpillai/reactive-resume:client-latest
    container_name: ReactiveResume-Client
    environment:
      - PUBLIC_SERVER_URL=https://resumeserver.$DOMAINNAME
      - TZ=$TZ
      # - SECRET_KEY=$RR_SECRET_KEY
      # - JWT_SECRET=$RR_JWT_SECRET
      # - JWT_EXPIRY_TIME=$RR_JWT_EXPIRY_TIME
      - PUBLIC_GOOGLE_CLIENT_ID=$RR_PUBLIC_GOOGLE_CLIENT_ID
      - GOOGLE_CLIENT_SECRET=$RR_GOOGLE_CLIENT_SECRET
      - GOOGLE_API_KEY=$RR_GOOGLE_API_KEY
      - PUBLIC_FLAG_DISABLE_SIGNUPS=true
    depends_on:
      - reactiveresumeserver
      - reactiveresumedb
    networks:
      pihole:
        ipv4_address: '172.22.0.141'
    labels: 
      - autoheal=true
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.resume-rtr.entrypoints=https"
      - "traefik.http.routers.resume-rtr.rule=Host(`resume.$DOMAINNAME`)"
      - "traefik.http.routers.resume-rtr.tls=true"
      ## Middlewares
      - "traefik.http.routers.resume-rtr.middlewares=chain-no-auth@file" # No Authentication
      # - "traefik.http.routers.resume-rtr.middlewares=chain-basic-auth@file" # Basic Authentication
      # - "traefik.http.routers.resume-rtr.middlewares=chain-oauth@file" # Google OAuth 2.0
      # - "traefik.http.routers.resume-rtr.middlewares=chain-authelia@file" # Authelia
      ## HTTP Services
      - "traefik.http.routers.resume-rtr.service=resume-svc"
      - "traefik.http.services.resume-svc.loadbalancer.server.port=3000"
      ## Flame Dashboard
      - flame.type=application # "app" works too
      - flame.name=Reactive Resume
      - flame.icon=https://raw.githubusercontent.com/modem7/MiscAssets/master/Icons/rxresume.png
    healthcheck:
      test: curl -fSs 127.0.0.1:3000 || exit 1
      interval: 30s
      timeout: 5s
      retries: 3
    restart: always

  reactiveresumedb:
    image: postgres:alpine
    container_name: ReactiveResume-DB
    environment:
      - TZ=$TZ
      - POSTGRES_DB=$RR_POSTGRES_DATABASE
      - POSTGRES_PASSWORD=$RR_POSTGRES_PASSWORD
      - POSTGRES_USER=$RR_POSTGRES_USERNAME
    networks:
      - isolated
    volumes:
      - $USERDIR/ReactiveResume/db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $RR_POSTGRES_USERNAME" ]
      interval: 30s
      timeout: 5s
      retries: 3
    restart: always

modem7 avatar Mar 29 '22 12:03 modem7

Same issue over here, also self-hosted.

Luk164 avatar Mar 29 '22 19:03 Luk164

Please Use PUBLIC_SERVER_URL=http://localhost:3100/

instead of PUBLIC_SERVER_URL=http://localhost:3100/api

It will work as expected

HI, @chandiwalaaadhar i have the same issue too, with download pdf.

My env:

  • docker
    • run with docker-compose.yml
    • has handle font 401 issue
    • has handle traefik routers limit
    • has expose port with 3000,3100,80,5432
  • ubuntu

The following log

server      | [Nest] 42  - 04/06/2022, 10:01:18 AM   ERROR [ExceptionsHandler] page.waitForSelector: Timeout 30000ms exceeded.
server      | =========================== logs ===========================
server      | waiting for selector "html.wf-active" to be visible
server      | ============================================================
server      | page.waitForSelector: Timeout 30000ms exceeded.
server      | =========================== logs ===========================
server      | waiting for selector "html.wf-active" to be visible
server      | ============================================================
server      |     at PrinterService.printAsPdf (/app/server/dist/printer/printer.service.js:40:20)

the second log is print from https://github.com/AmruthPillai/Reactive-Resume/issues/721#issuecomment-1071938664

swoiow avatar Apr 06 '22 10:04 swoiow

@swoiow Haven't checked this with Docker yet, will check once and look for a resolution

chandiwalaaadhar avatar Apr 06 '22 14:04 chandiwalaaadhar

@swoiow Haven't checked this with Docker yet, will check once and look for a resolution

Ok, thx, bro. Looking forward the good news.

swoiow avatar Apr 06 '22 15:04 swoiow

Ran into this issue as well, Fix in my case was a firewall change. self managed stack is running behind a Nginx Proxy Manager instance which was configured to only allow certain IP access to service. The instance IP that reactive resume itself was running on was denied access which lead to the print function waiting for a page to load which would never load. suggest you look at url the server is trying to connect to and make sure its accessible

kgotso avatar Aug 15 '22 17:08 kgotso

@kgotso I am not very good when it comes to nginx, is there a setting in compose file I could add to make it work?

Luk164 avatar Aug 17 '22 13:08 Luk164

@Luk164 is there a setting in compose file I could add to make it work?

This issue was happening for me as well in v3.6.5 (latest). I suspect this is because the server instance is unable to reach the PUBLIC_URL configured. In my case, I was running the server/client instance behind a reverse proxy, so I was using my domain url as PUBLIC_URL.

Once I fixed the PUBLIC_URL for the server, I am able to export pdf successfully. Also made sure both server/client is in the same network

Here is my config in docker-compose yaml. Hope this helps.

networks:
  frontend:
    external: true
  backend:
    external: true
...
postgres:
  networks:
    - backend
...
resume-server:
  environment:
    - PUBLIC_URL=http://resume-client:3000
    - PUBLIC_SERVER_URL=https://resume-server.mydomain.com
  networks:
    - frontend
    - backend
...
resume-client:
  environment:
    - PUBLIC_URL=https://resume.mydomain.com
    - PUBLIC_SERVER_URL=https://resume-server.mydomain.com
  networks:
    - frontend

Note: I have following configurations in my reverse proxy setup to forward request https://resume.mydomain.com to http://resume-client:3000 https://resume-server.mydomain.com to http://resume-server:3100

prakashrx avatar Sep 14 '22 17:09 prakashrx

pdf-error_1 Hello, I would like to know if anyone managed to solve this problem. I still can't download in PDF, but it works in json. I specify that it is in local. Here is the error message. Thanks

@reactive-resume/client:dev: event - compiled client and server successfully in 3.1s (13133 modules) @reactive-resume/server:dev: [Nest] 7498 - 29/10/2022 18:29:49 ERROR [ExceptionsHandler] page.waitForSelector: Timeout 30000ms exceeded. @reactive-resume/server:dev: =========================== logs =========================== @reactive-resume/server:dev: waiting for selector "html.wf-active" to be visible @reactive-resume/server:dev: ============================================================ @reactive-resume/server:dev: page.waitForSelector: Timeout 30000ms exceeded. @reactive-resume/server:dev: =========================== logs =========================== @reactive-resume/server:dev: waiting for selector "html.wf-active" to be visible @reactive-resume/server:dev: ============================================================ @reactive-resume/server:dev: at PrinterService.printAsPdf (/home/user/Desk/project_Resum/Reactive-Resume-main/server/src/printer/printer.service.ts:36:16) @reactive-resume/client:dev: wait - compiling /dashboard... @reactive-resume/client:dev: wait - compiling /[username]/[slug]/printer (client and server)... @reactive-resume/client:dev: event - compiled client and server successfully in 2.8s (13147 modules) @reactive-resume/client:dev: event - compiled client and server successfully (13149 modules)

Etoile2 avatar Oct 29 '22 16:10 Etoile2

I am also experiencing this issue, accessing locally, not through a reverse proxy.

tehniemer avatar Nov 05 '22 19:11 tehniemer

I experience the same issue (both client and server apps behind a reverse proxy), PDF export is really a core feature, hope it will be fixed soon. Not sure what is wrong, the public url is accessible from the server (tried with CURL).

grozandrei avatar Nov 10 '22 08:11 grozandrei

I experience the same issue (both client and server apps behind a reverse proxy), PDF export is really a core feature, hope it will be fixed soon. Not sure what is wrong, the public url is accessible from the server (tried with CURL).

If the server public URL is accessible through curl, that's good. Now, the next step would be to figure out which URL the client is trying to access. As you can see here: https://github.com/AmruthPillai/Reactive-Resume/blob/main/client/services/axios.ts, it always looks for the ENV SERVER_URL if it exists. If it does, and it matches the public server url, then it should work. Otherwise, it would revert to /api which means it would look for the /api route on client's own domain (which is what is happening in your case, I believe).

AmruthPillai avatar Nov 10 '22 10:11 AmruthPillai

Still does not work. So I have the following setup:

  • the public url: http://resume.mydomain.local
  • the server public url: http://resume.mydomain.local/api

A load balancer in front of them(Traefik), so http://resume.mydomain.local points to client:3000, and http://resume.mydomain.local/api points to server:3100.

Server is able to access client url, client is able to access server url, but the error still persists.

  • PUBLIC_URL=http://resume.mydomain.local
  • PUBLIC_SERVER_URL=http://resume.mydomain.local/api
  • SERVER_URL=http://resume.mydomain.local/api

The only log I get is:

> server_1    | @reactive-resume/server:start: [Nest] 83  - 11/10/2022, 10:20:35 AM   ERROR [ExceptionsHandler] page.waitForSelector: Timeout 30000ms exceeded.
> server_1    | @reactive-resume/server:start: =========================== logs ===========================
> server_1    | @reactive-resume/server:start: waiting for selector "html.wf-active" to be visible
> server_1    | @reactive-resume/server:start: ============================================================
> server_1    | @reactive-resume/server:start: page.waitForSelector: Timeout 30000ms exceeded.
> server_1    | @reactive-resume/server:start: =========================== logs ===========================
> server_1    | @reactive-resume/server:start: waiting for selector "html.wf-active" to be visible
> server_1    | @reactive-resume/server:start: ============================================================
> server_1    | @reactive-resume/server:start:     at PrinterService.printAsPdf (/app/server/dist/printer/printer.service.js:41:20)
> 

grozandrei avatar Nov 10 '22 11:11 grozandrei

To resolve this problem:

  • I deploy another docker image: https://hub.docker.com/r/martadinata666/reactive-resume
  • change internal app name in docker-compose.yml to my external domain name
  • forward 3100 port directly to VM
  • proxy domain name using Nginx Proxy Manager to port 3000
  • enable write permissons for app mounts

It's works, but wo HTTPS :(

My Portainer Stack config (change example.com to your domain):

version: "3.8"
services:
  example.com:
    image: martadinata666/reactive-resume:latest
    env_file:
      - stack.env
    environment:
       - TZ=UTC
    networks:
      - reactiveresume
    ports:
      - 3000:3000
      - 3100:3100
    volumes:
      - /srv/reactive_resume_martadinata/uploads:/home/debian/reactiveresume/server/dist/assets/uploads
      - /srv/reactive_resume_martadinata/exports:/home/debian/reactiveresume/server/dist/assets/exports #photo and export storage
    restart: unless-stopped

  db:
    image: postgres:13
    #user: 1000:1000 #debian image had user override feature, not working on alpine image
    environment:
      - POSTGRES_USER=reactiveresume
      - POSTGRES_PASSWORD=reactiveresumepass
      - POSTGRES_DB=reactiveresume
    restart: unless-stopped
    volumes:
      - /srv/reactive_resume_martadinata/db:/var/lib/postgresql/data
    networks:
      - reactiveresume

volumes:
  db:

networks:
  reactiveresume:
    name: reactiveresume

Stack.env:

TZ=UTC
SECRET_KEY=12345
POSTGRES_HOST=db
POSTGRES_PORT=5432
POSTGRES_USER=reactiveresume
POSTGRES_PASSWORD=reactiveresumepass
POSTGRES_DB=reactiveresume
POSTGRES_SSL_CERT=
JWT_SECRET=12345
JWT_EXPIRY_TIME=604800
GOOGLE_API_KEY=
PUBLIC_FLAG_DISABLE_SIGNUPS=false
PUBLIC_URL=http://example.com:3000
PUBLIC_SERVER_URL=http://example.com:3100

vinogradovnet avatar Nov 10 '22 22:11 vinogradovnet

@vinogradovnet Thanks for help, but I want to hide the app behind reverse proxy, so only 80 and 443 are available from outside. Besides that, it should also work with https (which it doesn't, and I am not referring to your solution).

So I believe this issue should be fixed in amruthpillai/reactive-resume images.

grozandrei avatar Nov 12 '22 13:11 grozandrei

if your call pdf download api, there is /api prefix. But client call api from internal, there isn't api prefix. This is the reason caused this err.

Jack-Kingdom avatar Dec 02 '22 15:12 Jack-Kingdom

@Jack-Kingdom no, client call PDF export API through proxy, not internally. So which should be the docker configuration with both client and server running behind reverse proxy, under a single domain?

grozandrei avatar Dec 02 '22 19:12 grozandrei

@grozandrei I recheck those code and I found that whether client ssr request page through proxy depends env config SERVER_URL that user provide.

Screen Shot 2022-12-10 at 3 39 03 AM

If you want client ssr request page from the internal network or with different domain. You can provide a SERVER_URL with domain and port. For example: http://example.com:80.

But, if you want client ssr request page through a proxy with the same domain. You must provide SERVER_URL with api suffix. Because it's the rule that you added in the proxy. For example: http://example.com:80/api

Jack-Kingdom avatar Dec 09 '22 19:12 Jack-Kingdom

Still unable to get PDF downloads working. I have also tried using martadinata666's container because it has client and server together but it gave me the same result. I am using the most basic setup copied from the repository:


version: "3.8"

services:
  postgres:
    image: postgres:alpine
    restart: always
    ports:
      - 5432:5432
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      start_period: 15s
      interval: 30s
      timeout: 30s
      retries: 3
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres

  server:
    image: amruthpillai/reactive-resume:server-latest
    # build:
    #   context: .
    #   dockerfile: ./server/Dockerfile
    restart: always
    ports:
      - 3100:3100
    depends_on:
      - postgres
    environment:
      - PUBLIC_URL=http://localhost:3000
      - PUBLIC_SERVER_URL=http://localhost:3100
      - PUBLIC_GOOGLE_CLIENT_ID=
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - SECRET_KEY=change-me-to-something-secure
      - POSTGRES_HOST=postgres
      - POSTGRES_PORT=5432
      - POSTGRES_SSL_CERT=
      - JWT_SECRET=change-me-to-something-secure
      - JWT_EXPIRY_TIME=604800
      - GOOGLE_CLIENT_SECRET=
      - GOOGLE_API_KEY=
      - MAIL_FROM_NAME=Reactive Resume
      - [email protected]
      - MAIL_HOST=
      - MAIL_PORT=
      - MAIL_USERNAME=
      - MAIL_PASSWORD=
      - STORAGE_BUCKET=
      - STORAGE_REGION=
      - STORAGE_ENDPOINT=
      - STORAGE_URL_PREFIX=
      - STORAGE_ACCESS_KEY=
      - STORAGE_SECRET_KEY=
      - PDF_DELETION_TIME=

  client:
    image: amruthpillai/reactive-resume:client-latest
    # build:
    #   context: .
    #   dockerfile: ./client/Dockerfile
    restart: always
    ports:
      - 3000:3000
    depends_on:
      - server
    environment:
      - PUBLIC_URL=http://localhost:3000
      - PUBLIC_SERVER_URL=http://localhost:3100
      - PUBLIC_GOOGLE_CLIENT_ID=

volumes:
  pgdata:

Luk164 avatar Dec 19 '22 14:12 Luk164

Hello, Please has anyone managed to solve the problem of downloading PDF locally? Thanks

Etoile2 avatar Jan 22 '23 00:01 Etoile2