lago icon indicating copy to clipboard operation
lago copied to clipboard

[BUG]: Not able to pass the signup stage

Open adroual opened this issue 8 months ago • 5 comments

Describe the bug When I try to create a new user on my self hosted lago, I can't move forward with the account creation. I got the toast message "An error occurred, please reload the application" I tried with google and face the same issue.

To Reproduce Steps to reproduce the behavior:

  1. Go to 'Sign up'
  2. Click on 'Sign up'
  3. See error

Expected behavior I expect my account to be created and be redirected to Lago dashboard or main page.

Screenshots Image

Support

  • OS: macOS 15.3.1 (24D70)
  • Browser: Arc
  • Version: Version 1.90.1 (61364)

Additional context In order to avoid localhost conflict with other instance running on my docker, I install Lago with this command docker run -d --name lago -p 80:80 -p 3001:3000 getlago/lago:latest

adroual avatar Apr 13 '25 11:04 adroual

@adroual can you try to pass the LAGO_API_URL as http://localhost:3001

docker run -d --name lago -p 80:80 -p 3001:3000 -e LAGO_API_URL=http://localhost:3001 getlago/lago:latest

jdenquin avatar Apr 18 '25 00:04 jdenquin

Same error here, but we are trying to use a public IP instead of localhost

Mery-Sanz avatar May 16 '25 05:05 Mery-Sanz

@Mery-Sanz so you have to pass the ip for LAGO_API_URL and LAGO_FRONT_URL

LAGO_API_URL=http://your_ip:3000
LAGO_FRONT_URL=http://your_ip

jdenquin avatar May 16 '25 09:05 jdenquin

I have both LAGO_API_URL and LAGO_FRONT_URL set but /env-config.js still returns

window.API_URL = "http://localhost:3000"
window.LAGO_DOMAIN = ""
window.APP_ENV = "production"
window.LAGO_OAUTH_PROXY_URL = "https://proxy.getlago.com"
window.LAGO_DISABLE_SIGNUP = ""
window.NANGO_PUBLIC_KEY = ""
window.SENTRY_DSN = ""
window.LAGO_DISABLE_PDF_GENERATION = ""

and completely ignores my env

terion-name avatar Aug 28 '25 19:08 terion-name

After alot of inspecting how runner.sh setups and the generated env.sh, env-config.sh, puma.rb... I found that the Procfile in /app/api will override the API_PORT since it's not performing the env lookup. So if you were having a port collision on 3000 and performed a port binding 3001:3001 the attempt to hit localhost:3000/graphql will fail since the server isn't actually listening on that port. This is probably only an issue for the quickstart container getlago/lago:latest and a non-issue for helm.

root@lago-79dc8dcbf-5s2qv:/app/api# cat Procfile
web: bundle exec rails s -b :: -p 3000
worker: bundle exec sidekiq -C config/sidekiq/sidekiq.yml
clock: bundle exec clockwork ./clock.rb

Kubernetes manifests in what was attempted, the Procfile is probably the only changed needed but should ideally perform a loopup respecting API_PORT:

apiVersion: v1
kind: ConfigMap
metadata:
  name: lago-runner
  labels:
    app: lago
data:
  puma.rb: |
    # frozen_string_literal: true

    # Puma can serve each request in a thread from an internal thread pool.
    # The `threads` method setting takes two numbers: a minimum and maximum.
    # Any libraries that use thread pools should be configured to match
    # the maximum value specified for Puma. Default is set to 5 threads for minimum
    # and maximum; this matches the default thread size of Active Record.
    #
    max_threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
    min_threads_count = ENV.fetch("RAILS_MIN_THREADS", 0)
    threads min_threads_count, max_threads_count

    # Specifies the `worker_timeout` threshold that Puma will use to wait before
    # terminating a worker in development environments.
    #
    worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
    worker_timeout 12 if ENV.fetch("RAILS_ENV", "production") == "production"

    # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
    #
    port ENV.fetch("PORT", 3001)

    # Specifies the `environment` that Puma will run in.
    #
    environment ENV.fetch("RAILS_ENV", "development")

    # Specifies the `pidfile` that Puma will use.
    pidfile ENV.fetch("PIDFILE", "tmp/pids/server.pid")

    # Specifies the number of `workers` to boot in clustered mode.
    # Workers are forked web server processes. If using threads and workers together
    # the concurrency of the application would be max `threads` * `workers`.
    # Workers do not work on JRuby or Windows (both of which do not support
    # processes).
    #
    workers ENV.fetch("WEB_CONCURRENCY", 0)

    # Use the `preload_app!` method when specifying a `workers` number.
    # This directive tells Puma to first boot the application and load code
    # before forking the application. This takes advantage of Copy On Write
    # process behavior so workers use less memory.
    #
    preload_app! if ENV["WEB_CONCURRENCY"].present?

    # Allow puma to be restarted by `bin/rails restart` command.
    plugin :tmp_restart

    # Activate Yabeda
    activate_control_app
    plugin :yabeda
  .env.template: |
    API_URL=http://localhost:3001
  .env.sh: |
    #!/bin/bash
  
    rm -rf ./env-config.js
    touch ./env-config.js
  
    api_url_value=http://localhost:3001
    domain_value=$(echo $LAGO_DOMAIN)
    app_env_value=production
    lago_oauth_proxy_url_value=$(echo $LAGO_OAUTH_PROXY_URL)
    lago_disable_signup_value=$(echo $LAGO_DISABLE_SIGNUP)
    nango_public_key=$(echo $NANGO_PUBLIC_KEY)
    sentry_dsn_value=$(echo $SENTRY_DSN)
    lago_disable_pdf_generation=$(echo $LAGO_DISABLE_PDF_GENERATION)
  
    echo "window.API_URL = \"$api_url_value\"" >> ./env-config.js
    echo "window.LAGO_DOMAIN = \"$domain_value\"" >> ./env-config.js
    echo "window.APP_ENV = \"$app_env_value\"" >> ./env-config.js
    echo "window.LAGO_OAUTH_PROXY_URL = \"$lago_oauth_proxy_url_value\"" >> ./env-config.js
    echo "window.LAGO_DISABLE_SIGNUP = \"$lago_disable_signup_value\"" >> ./env-config.js
    echo "window.NANGO_PUBLIC_KEY = \"$nango_public_key\"" >> ./env-config.js
    echo "window.SENTRY_DSN = \"$sentry_dsn_value\"" >> ./env-config.js
    echo "window.LAGO_DISABLE_PDF_GENERATION = \"$lago_disable_pdf_generation\"" >> ./env-config.js
  runner.sh: |
    #!/bin/bash
    
    echo "Starting Lago..."
    
    declare -A ENV_VARS=(
      [RAILS_ENV]="production"
      [RAILS_LOG_TO_STDOUT]="true"
      [POSTGRES_PASSWORD]=$(openssl rand -hex 16)
      [SECRET_KEY_BASE]=$(openssl rand -base64 16)
      [LAGO_RSA_PRIVATE_KEY]=$(openssl genrsa 2048 | openssl base64 -A)
      [LAGO_DISABLE_SSL]="true"
      [LAGO_ENCRYPTION_PRIMARY_KEY]=$(openssl rand -hex 16)
      [LAGO_ENCRYPTION_DETERMINISTIC_KEY]=$(openssl rand -hex 16)
      [LAGO_ENCRYPTION_KEY_DERIVATION_SALT]=$(openssl rand -hex 16)
      [REDIS_URL]="redis://localhost:6379/0"
      [LAGO_FRONT_URL]="http://localhost:8080"
      [LAGO_API_URL]="http://localhost:3001"
      [API_URL]="http://localhost:3001"
      [LAGO_PDF_URL]="http://host.docker.internal:3002"
      [APP_ENV]="production"
      [PORT]="3001"
      [CODEGEN_API]="http://localhost:3000/graphql"
    )
    
    if [ -f "/data/.env" ]; then
      for LINE in $(cat /data/.env); do export $LINE; done
    fi
    
    # Configure data directories
    if [ -z "${DATA_DIR}" ]; then
      export DATA_DIR=/data
      mkdir -p ${DATA_DIR}
      mkdir -p ${DATA_DIR}/redis
      chown redis:redis ${DATA_DIR}/redis
      mkdir -p ${DATA_DIR}/postgresql
      touch ${DATA_DIR}/db.log
      touch ${DATA_DIR}/.env
      echo "DATA_DIR=${DATA_DIR}" >> ${DATA_DIR}/.env
    fi
    
    # Configure Redis
    sed -i "s#DATA_DIR#${DATA_DIR}#g" /etc/redis/redis.conf
    
    # Configure PG
    export PGDATA="${DATA_DIR}/postgresql"
    export PGPORT=5432
    
    # Start Redis, PG and Nginx
    service redis-server start >> /dev/null
    service postgresql restart >> /dev/null
    service nginx restart >> /dev/null
    
    # PDF Service
    if df -hT | grep -q docker.sock > /dev/null; then
      if docker ps --filter "name=lago-pdf" | grep -q lago-pdf > /dev/null; then
        docker stop lago-pdf > /dev/null
        docker rm lago-pdf > /dev/null
      fi
      docker run -d --name lago-pdf -p 3001:3000 getlago/lago-gotenberg:8 > /dev/null
    else
      echo "WARN: Docker socket is not mounted. Skipping PDF service."
    fi
    
    # Prepare Environment
    # Defaulting values
    for VAR in "${!ENV_VARS[@]}"; do
    if [ -z "${!VAR}" ]; then
      export $VAR=${ENV_VARS[$VAR]}
      echo "$VAR=${ENV_VARS[$VAR]}" >> ${DATA_DIR}/.env
    fi
    done
    
    if [ -z "${DATABASE_URL}" ]; then
      export DATABASE_URL=postgresql://lago:$POSTGRES_PASSWORD@localhost:5432/lago
      echo "DATABASE_URL=${DATABASE_URL}" >> ${DATA_DIR}/.env
    fi

    export RAILS_ENV=production
    export LAGO_FRONT_URL="http://localhost:8080"
    export LAGO_API_URL="http://localhost:3001"
    export API_URL="http://localhost:3001"
    export APP_ENV="production"
    export PORT="3001"
    export CODEGEN_API="http://localhost:3001/graphql"
    
    # Prepare Front Environment
    cd ./front
    bash -c ./.env.sh
    cd ..
    
    # Create DB User
    su -c "psql -tc \"SELECT 1 FROM pg_user WHERE usename = 'lago';\" | grep -q 1 || psql -c \"CREATE ROLE lago PASSWORD '${POSTGRES_PASSWORD}' CREATEDB LOGIN;\"" postgres >> ${DATA_DIR}/db.log
    
    # Launch BE Services
    cd ./api
    bundle exec rake db:create >> ${DATA_DIR}/db.log
    bundle exec rake db:migrate >> ${DATA_DIR}/db.log
    bundle exec rails signup:seed_organization >> ${DATA_DIR}/db.log
    rm -f ./tmp/pids/server.pid
    foreman start
  Procfile: |
    web: bundle exec rails s -b :: -p 3001
    worker: bundle exec sidekiq -C config/sidekiq/sidekiq.yml
    clock: bundle exec clockwork ./clock.rb
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: lago
  labels:
    app: lago
spec:
  replicas: 1
  selector:
    matchLabels:
      app: lago
  template:
    metadata:
      labels:
        app: lago
    spec:
      containers:
      - name: lago
        image: getlago/lago:latest
        env:
          - name: LAGO_FRONT_URL
            value: "http://localhost:8080"
          - name: FRONT_PORT
            value: "8080"
          - name: LAGO_API_URL
            value: "http://localhost:3001"
          - name: API_PORT
            value: "3001"
          - name: APP_ENV
            value: "production"
        ports:
        - name: dashboard
          containerPort: 8080
          protocol: TCP
        - name: api
          containerPort: 3001
          protocol: TCP
        volumeMounts:
        - name: runner-script
          mountPath: /app/runner.sh
          subPath: runner.sh
        - name: runner-script
          mountPath: /app/front/.env.sh
          subPath: .env.sh
        - name: runner-script
          mountPath: /app/front/.env.template
          subPath: .env.template
        - name: runner-script
          mountPath: /app/api/config/puma.rb
          subPath: puma.rb
        - name: runner-script
          mountPath: /app/api/Procfile
          subPath: Procfile
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "2Gi"
            cpu: "1000m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3001
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 3001
          initialDelaySeconds: 10
          periodSeconds: 5
      volumes:
      - name: runner-script
        configMap:
          name: lago-runner
          defaultMode: 0755
---
apiVersion: v1
kind: Service
metadata:
  name: lago
  labels:
    app: lago
spec:
  type: ClusterIP
  selector:
    app: lago
  ports:
  - name: dashboard
    port: 8080
    targetPort: 8080
    protocol: TCP
  - name: api
    port: 3001
    targetPort: 3001
    protocol: TCP

jrxFive avatar Nov 06 '25 16:11 jrxFive