Reactive-Resume: [BUG] PDF Download not working

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)

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 4
  • Comments: 57 (11 by maintainers)

Most upvoted comments

It seems there may be multiple reasons people encounter this, but I found a solution to my issue. It had to do with how my reverse proxy was configured and the fact that I was trying to serve them off of the same port of the same domain. The issue was the server calls its public URL to its own printer endpoint differently than the endpoint to return a resume to the browser. So it must be able to resolve its own traffic back to itself locally using the same DNS & routing as over a public network.

In my Docker Compose file, I have it configured to serve the client from port 3180 and the server from port 3190.

My URL env variables are configured like this:

  • PUBLIC_URL=https://<sub>.<domain>.com/
  • PUBLIC_SERVER_URL=https://<sub>.<domain>.com/api

These variables are identical between the server and client containers.

In my Nginx reverse proxy, I configured traffic to <sub>.<domain>.com to be directed to the client on http://<docker_host>:3180, but then I needed to add a custom location to the same Nginx config specifically for https://<sub>.<domain>.com/api/ and forward all traffic to /api to http://<docker_host>:3190/ without the /api suffix. Here is what that extra rule looks like:

location /api/ {
    proxy_pass http://<docker_host>:3190/;
}

If you’re using Nginx Proxy Manager, this is what the extra config looks like:

Screenshot 2023-01-26 at 11 37 33 AM

I’ve also had 500 error when trying to generate PDF on local with docker. I’ve checked some docker logs from server container and to print pdf, server is trying to connect to localhost:3000 and gets connection refused errors.

@Etoile2 @joaquinvacas For all of you running locally with docker (by just running docker compose up -d), here is how to make PDF work:

diff --git a/docker-compose.yml b/docker-compose.yml
index 7d92ffd9..ca32537e 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -4,8 +4,7 @@ services:
   postgres:
     image: postgres:alpine
     restart: always
-    ports:
-      - 5432:5432
+    network_mode: host
     volumes:
       - pgdata:/var/lib/postgresql/data
     healthcheck:
@@ -25,8 +24,7 @@ services:
     #   context: .
     #   dockerfile: ./server/Dockerfile
     restart: always
-    ports:
-      - 3100:3100
+    network_mode: host
     depends_on:
       - postgres
     environment:
@@ -37,7 +35,7 @@ services:
       - POSTGRES_USER=postgres
       - POSTGRES_PASSWORD=postgres
       - SECRET_KEY=change-me-to-something-secure
-      - POSTGRES_HOST=postgres
+      - POSTGRES_HOST=localhost
       - POSTGRES_PORT=5432
       - POSTGRES_SSL_CERT=
       - JWT_SECRET=change-me-to-something-secure
@@ -64,8 +62,7 @@ services:
     #   context: .
     #   dockerfile: ./client/Dockerfile
     restart: always
-    ports:
-      - 3000:3000
+    network_mode: host
     depends_on:
       - server
     environment:
@@ -74,4 +71,4 @@ services:
       - PUBLIC_GOOGLE_CLIENT_ID=

Then docker compose up -d and it should work now after refreshing page in browser.

The trick is basically to use network_mode: host on all services and use POSTGRES_HOST=localhost.

⚠️ This is a workaround only for temporary use! Is is not secure and it will expose whole app to everyone who can access your machine in your network or from internet.

Better solution without modifying docker compose file

As I understand on local use with docker proper url for pdf printer is http://client:3000 not http://localhost:3000 because we are making request from withing server container and localhost means server container itself.

So all this could probably be avoided by adding new optional env var e.g. PDF_PRINTER_URL that if set, could be used in https://github.com/AmruthPillai/Reactive-Resume/blob/main/server/src/printer/printer.service.ts#L50 like this

 const url = this.configService.get<string>('app.pdf_printer_url', this.configService.get<string>('app.url'));

(I’m not js dev so sorry for garbage code)

This would allow to return correct urls from backend to client app and use this new pdf printer url to make internal calls to client container from within server container.

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
      - MAIL_FROM_EMAIL=noreply@rxresu.me
      - 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:

Same issue over here, also self-hosted.

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

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

It will work as expected

@AmruthPillai It also works for me, thank you!

I also can’t export a pdf. I am using 3.6.5 in a Synology NAS (latest tags didn’t had the manifest for linux/amd64). I’ve setup the containers behind a reverseproxy and everything is working fine, except the export to pdf.

My setup has this as the URLs: resume-server: - PUBLIC_URL=https://rxresume.mydomain - PUBLIC_SERVER_URL=https://rxresumeserver.mydomain

resume-client: - PUBLIC_URL=https://rxresume.mydomain - PUBLIC_SERVER_URL=https://rxresumeserver.mydomain

When looking at logs, I see an entry that then throws an ERR_NAME_NOT_RESOLVED error: navigating to “https://rxresume.**mydomainmaja391**/cv-maja-copy/printer?secretKey=mykey”, waiting until “load”

I was expecting that Reactive Resume would add a / after the mydomain part of url, and before the parameter (maja391 is the user), but that’s not the case. Is this a known issue or I am messing something on my setup?

[EDIT] noticed that this issue was fixed in the 3.7.4, tried again and the latest 3.7.5 is already available and working fine. Thank you so much!

Make sure to create a new resume as soon as you’ve changed some configs. It helped me during initial troubleshooting as older resumes were hitting errors again and new ones not.

This was the ticket for me. I recreated my resume from scratch by copying and pasting the info from my existing one to a new template and PDF export started working without the need for dns or extra_hosts entries. Duplicating or uploading a saved JSON did not work, I had to recreate from a blank template. I was also able to remove the extra SERVER_URL from environment variables.

I’ve just copied the above docker-compose example (the one with extra_hosts) again and pasted it into a new, blank Linux VM with Docker. The only changes I made was the domain name and extra_hosts IP address. As soon as the containers were up, I registered a new user account, logged in and created a new resume. I’ve also preloaded the resume with the available example data. Hitting the export button generated the PDF promptly.

I even tried accessing the traefik instance from another computer in LAN. Also worked flawlessly and I could generate new resumes and export them as PDF.

I’ve used multiple browsers (MS Edge, Mozilla Firefox and Google Chrome). With each browser it just worked. Not sure how to troubleshoot further, sorry.

Make sure to create a new resume as soon as you’ve changed some configs. It helped me during initial troubleshooting as older resumes were hitting errors again and new ones not.

These are the warnings and errors that pop up in the developer console when I try to export a pdf

The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
_app-43dbbd28d75c6765.js:195 
        
        
        GET https://resume.mydomain.com/api/printer/name/my-name?lastUpdated=1683091784 500
(anonymous) @ _app-43dbbd28d75c6765.js:195
xhr @ _app-43dbbd28d75c6765.js:195
eK @ _app-43dbbd28d75c6765.js:195
Promise.then (async)
request @ _app-43dbbd28d75c6765.js:195
e2.<computed> @ _app-43dbbd28d75c6765.js:195
(anonymous) @ _app-43dbbd28d75c6765.js:195
i @ _app-43dbbd28d75c6765.js:195
fn @ _app-43dbbd28d75c6765.js:210
u @ _app-43dbbd28d75c6765.js:210
c @ _app-43dbbd28d75c6765.js:210
t.executeMutation @ _app-43dbbd28d75c6765.js:210
(anonymous) @ _app-43dbbd28d75c6765.js:210
Promise.then (async)
t.execute @ _app-43dbbd28d75c6765.js:210
r.mutate @ _app-43dbbd28d75c6765.js:210
Y @ build-90afc5a151a44d66.js:1
await in Y (async)
eU @ framework-e23f030857e925d4.js:9
eH @ framework-e23f030857e925d4.js:9
(anonymous) @ framework-e23f030857e925d4.js:9
re @ framework-e23f030857e925d4.js:9
rn @ framework-e23f030857e925d4.js:9
(anonymous) @ framework-e23f030857e925d4.js:9
oP @ framework-e23f030857e925d4.js:9
eF @ framework-e23f030857e925d4.js:9
ro @ framework-e23f030857e925d4.js:9
nU @ framework-e23f030857e925d4.js:9
nD @ framework-e23f030857e925d4.js:9
_app-43dbbd28d75c6765.js:210  {statusCode: 500, message: 'Internal server error'}
(anonymous) @ _app-43dbbd28d75c6765.js:210
Promise.catch (async)
t.execute @ _app-43dbbd28d75c6765.js:210
r.mutate @ _app-43dbbd28d75c6765.js:210
Y @ build-90afc5a151a44d66.js:1
await in Y (async)
eU @ framework-e23f030857e925d4.js:9
eH @ framework-e23f030857e925d4.js:9
(anonymous) @ framework-e23f030857e925d4.js:9
re @ framework-e23f030857e925d4.js:9
rn @ framework-e23f030857e925d4.js:9
(anonymous) @ framework-e23f030857e925d4.js:9
oP @ framework-e23f030857e925d4.js:9
eF @ framework-e23f030857e925d4.js:9
ro @ framework-e23f030857e925d4.js:9
nU @ framework-e23f030857e925d4.js:9
nD @ framework-e23f030857e925d4.js:9
build-90afc5a151a44d66.js:1  Uncaught (in promise) {statusCode: 500, message: 'Internal server error'}
Y @ build-90afc5a151a44d66.js:1
await in Y (async)
eU @ framework-e23f030857e925d4.js:9
eH @ framework-e23f030857e925d4.js:9
(anonymous) @ framework-e23f030857e925d4.js:9
re @ framework-e23f030857e925d4.js:9
rn @ framework-e23f030857e925d4.js:9
(anonymous) @ framework-e23f030857e925d4.js:9
oP @ framework-e23f030857e925d4.js:9
eF @ framework-e23f030857e925d4.js:9
ro @ framework-e23f030857e925d4.js:9
nU @ framework-e23f030857e925d4.js:9
nD @ framework-e23f030857e925d4.js:9

Thank you, @funkybunch, it’s works for me.

But I also need to change permissions on folder /home/debian/reactiveresume/server/dist/assets/ to debian:debian inside container.

It seems there may be multiple reasons people encounter this, but I found a solution to my issue. It had to do with how my reverse proxy was configured and the fact that I was trying to serve them off of the same port of the same domain. The issue was the server calls its public URL to its own printer endpoint differently than the endpoint to return a resume to the browser. So it must be able to resolve its own traffic back to itself locally using the same DNS & routing as over a public network.

In my Docker Compose file, I have it configured to serve the client from port 3180 and the server from port 3190.

My URL env variables are configured like this:

  • PUBLIC_URL=https://<sub>.<domain>.com/
  • PUBLIC_SERVER_URL=https://<sub>.<domain>.com/api

These variables are identical between the server and client containers.

In my Nginx reverse proxy, I configured traffic to <sub>.<domain>.com to be directed to the client on http://<docker_host>:3180, but then I needed to add a custom location to the same Nginx config specifically for https://<sub>.<domain>.com/api/ and forward all traffic to /api to http://<docker_host>:3190/ without the /api suffix. Here is what that extra rule looks like:

location /api/ {
    proxy_pass http://<docker_host>:3190/;
}

If you’re using Nginx Proxy Manager, this is what the extra config looks like:

Screenshot 2023-01-26 at 11 37 33 AM

Running locally on Docker, using localhost isn’t possible to use the print function.

Any news on this with local usage?

Can anyone provide a working example with a traefik reverse proxy in front, using a local domain name?

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