AmruthPillai / Reactive-Resume

A one-of-a-kind resume builder that keeps your privacy in mind. Completely secure, customizable, portable, open-source and free forever. Try it out today!
https://rxresu.me
MIT License
26.08k stars 2.67k forks source link

[Bug] InvalidBrowserConnection error (PDF/Preview are not working) #1854

Open Sekhan opened 7 months ago

Sekhan commented 7 months ago

Is there an existing issue for this?

Product Variant

Self-Hosted

Current Behavior

RxResume can't connect to chromium browserless, resulting in the following issue :

error2

Here's the error message generated in the dev console:

error3 Visiting my self-hosted instance on _https://{resume_domain}/api/health_ confirm the connectivity problem with chrome :

{
  "error": {
  },
  "details": {
    "database": {
      "status": "up"
    },
    "storage": {
      "status": "up"
    },
    "browser": {
      "status": "down",
      "message": "InvalidBrowserConnection"
    },
    "redis": {
      "status": "up"
    }
  }
}

I'm running the app on a server with docker behind Traefik, I've followed the recommended way. Here's my current docker-compose :

services:
  # Database (Postgres)
  postgres:
    image: postgres:15-alpine
    container_name: postgres-resume
    expose:
      - "5432"
    volumes:
      - "${DATA}/Docker/rx-resume/postgres_data:/var/lib/postgresql/data"
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - "resume"
    restart: unless-stopped

  # Storage (for image uploads)
  minio:
    image: minio/minio
    container_name: minio
    command: server /data
    expose:
      - "9000"
    volumes:
      - "${DATA}/Docker/rx-resume/minio_data:/data"
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
    networks:
      - "resume"
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.minio.loadbalancer.server.port=9000"
      - "traefik.http.routers.minio.rule=Host(`storage.${DOMAIN}`)"
      - "traefik.http.routers.minio.tls=true"
      - "traefik.http.routers.minio.entrypoints=web-secure"
    restart: unless-stopped

  # Chrome Browser (for printing and previews)
  chrome:
    image: ghcr.io/browserless/chromium:latest
    container_name: chrome
##    extra_hosts:
##      - host.docker.internal:host-gateway
    expose:
      - "3000"
    environment:
      TIMEOUT: 10000
      CONCURRENT: 10
      TOKEN: ${TOKEN}
      EXIT_ON_HEALTH_FAILURE: true
      HEALTH: true
    networks:
      - "resume"
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.printer.loadbalancer.server.port=3000"
      - "traefik.http.routers.printer.rule=Host(`printer.${DOMAIN}`)"
      - "traefik.http.routers.printer.tls=true"
      - "traefik.http.routers.printer.entrypoints=web-secure"
    restart: unless-stopped

  # Redis (for cache & server session management)
  redis:
    image: redis:alpine
    container_name: redis-resume
    command: redis-server --save 60 1 --loglevel warning --requirepass ${PASS}
    volumes:
      - "${DATA}/Docker/rx-resume/redis_data:/data"
    networks:
      - "resume"
    restart: unless-stopped

  app:
    image: amruthpillai/reactive-resume:latest
    container_name: reactive-resume
    depends_on:
      - postgres
      - minio
      - redis
      - chrome
    environment:
      # -- Environment Variables --
      PORT: 3000
      NODE_ENV: production

      # -- URLs --
      PUBLIC_URL: https://cv.${DOMAIN}
      STORAGE_URL: https://storage.${DOMAIN}/default

      # -- Printer (Chrome) --
      CHROME_TOKEN: ${TOKEN}
      CHROME_URL: ws://printer.${DOMAIN}

      # -- Database (Postgres) --
      DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/postgres

      # -- Auth --
      ACCESS_TOKEN_SECRET: ${ACCESS_TOKEN}
      REFRESH_TOKEN_SECRET: ${REFRESH_TOKEN_SECRET}

      # -- Emails --
      MAIL_FROM: noreply@example.com
      # SMTP_URL: smtp://user:pass@smtp:587 # Optional

      # -- Storage (Minio) --
      STORAGE_ENDPOINT: minio
      STORAGE_PORT: 9000
      STORAGE_BUCKET: default
      STORAGE_ACCESS_KEY: ${MINIO_ROOT}
      STORAGE_SECRET_KEY: ${MINIO_ROOT_PASSWORD}
      STORAGE_USE_SSL: false

      # -- Cache (Redis) --
      REDIS_URL: redis://default:${PASS}@redis:6379

    networks:
      - "resume"
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.resume.loadbalancer.server.port=3000"
      - "traefik.http.routers.resume.rule=Host(`cv.${DOMAIN}`)"
      - "traefik.http.routers.resume.tls=true"
      - "traefik.http.routers.resume.entrypoints=web-secure"
    restart: unless-stopped

Also, trying to reach directly https://printer.${DOMAIN} (without or without ?token=[REDACTED]) in firefox give this error:

error

I've spend quite some time searching, lots of people already report this issue : https://github.com/AmruthPillai/Reactive-Resume/issues/1607 https://github.com/AmruthPillai/Reactive-Resume/issues/1609 https://github.com/AmruthPillai/Reactive-Resume/issues/1623 https://github.com/AmruthPillai/Reactive-Resume/issues/1821

But none of the fix mentioned are working :worried:

In advance, thanks for the amazing work on this projet (and help) :grinning:

Expected Behavior

Preview and PDF function should work properly

Steps To Reproduce

No response

What browsers are you seeing the problem on?

Firefox, Chrome

What template are you using?

None

Anything else?

No response

ghxstxch commented 6 months ago

I just want to add that I am also running into these same issues. This is a truly wonderful project, but the lack of proper documentation makes it hard to diagnose what I may be doing wrong.

ghxstxch commented 6 months ago

Just want to keep this updated with my progress - I made SOME headway, still attempting to find out a truly solid solution. NOTE: I am using NPM instead of Traefik. Using the below docker-compose.yaml as an example adding

    extra_hosts:
      - host.docker.internal:host-gateway

to the Chrome service, while it still does not redirect correctly to the PDF when attempting to download it, it does spit out a "valid" URL (http://localhost:9000/default/STRING1/resumes/STRING2.pdf). Changing 'localhost' to the IP address the container gets then allows me to successfully download it. Not great, but better than not being able to access it at all. Hopefully this helps someone who's running into the same issues I am. I'll keep this updated if I can figure anything further out.

docker-compose.yaml:

version: "3.8"

# In this Docker Compose example, it assumes that you maintain a reverse proxy externally (or chose not to).
# The only two exposed ports here are from minio (:9000) and the app itself (:3000).
# If these ports are changed, ensure that the env vars passed to the app are also changed accordingly.

services:
  # Database (Postgres)
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    volumes:
      - ./postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Storage (for image uploads)
  minio:
    image: minio/minio
    restart: unless-stopped
    command: server /data
    ports:
      - "9000:9000"
    volumes:
      - ./minio_data:/data
    environment:
      MINIO_ROOT_USER: miniouser
      MINIO_ROOT_PASSWORD: miniopass

  # Chrome Browser (for printing and previews)
  chrome:
    image: ghcr.io/browserless/chromium:latest
    restart: unless-stopped
    extra_hosts:
      - host.docker.internal:host-gateway
    environment:
      TIMEOUT: 10000
      CONCURRENT: 10
      TOKEN: CHROMETOKEN
      EXIT_ON_HEALTH_FAILURE: true
      PRE_REQUEST_HEALTH_CHECK: true

  app:
    image: amruthpillai/reactive-resume:latest
    restart: unless-stopped
    ports:
      - "3000:3000"
    depends_on:
      - postgres
      - minio
      - chrome
    environment:
      # -- Environment Variables --
      PORT: 3000
      NODE_ENV: production

      # -- URLs --
      PUBLIC_URL: http://localhost:3000
      STORAGE_URL: http://localhost:9000/default

      # -- Printer (Chrome) --
      CHROME_TOKEN: CHROMETOKEN
      CHROME_URL: ws://chrome:3000

      # -- Database (Postgres) --
      DATABASE_URL: postgresql://user:pass@postgres:5432/postgres

      # -- Auth --
      ACCESS_TOKEN_SECRET: access_token_secret
      REFRESH_TOKEN_SECRET: refresh_token_secret

      # -- Emails --
      MAIL_FROM: noreply@localhost
      # SMTP_URL: smtp://user:pass@smtp:587 # Optional

      # -- Storage (Minio) --
      STORAGE_ENDPOINT: minio
      STORAGE_PORT: 9000
      STORAGE_REGION: us-east-1 # Optional
      STORAGE_BUCKET: default
      STORAGE_ACCESS_KEY: user
      STORAGE_SECRET_KEY: pass
      STORAGE_USE_SSL: false

      # -- Sentry (Optional) --
      # SERVER_SENTRY_DSN:
      # VITE_CLIENT_SENTRY_DSN:

      # -- Crowdin (Optional) --
      # CROWDIN_PROJECT_ID:
      # CROWDIN_PERSONAL_TOKEN:

      # -- Email (Optional) --
      # DISABLE_EMAIL_AUTH: true
      # VITE_DISABLE_SIGNUPS: true
      # SKIP_STORAGE_BUCKET_CHECK: false

      # -- GitHub (Optional) --
      # GITHUB_CLIENT_ID: github_client_id
      # GITHUB_CLIENT_SECRET: github_client_secret
      # GITHUB_CALLBACK_URL: http://localhost:3000/api/auth/github/callback

      # -- Google (Optional) --
      # GOOGLE_CLIENT_ID: google_client_id
      # GOOGLE_CLIENT_SECRET: google_client_secret
      # GOOGLE_CALLBACK_URL: http://localhost:3000/api/auth/google/callback

volumes:
  minio_data:
  postgres_data:
rTiGd2 commented 6 months ago

CHROME_URL - If you have the chrome container with web-secure, have you changed this to wss (web socket secure)?

CHROME_URL: wss://{your chorme.addr}:{your port}

AashishSinghal commented 6 months ago

I have found that when we build the application the pdf generation starts to work. I saw that when I had not built the application, not even once, the resume thumbnails were not rendering rather showing a JSON output that there was no such directory in the "dist/apps/client/index.html", can someone give it a try after building the application? Once the application is built the Preview/Generation of Resume works as expected.