From 34d4d013fcea2eaf6d635ba22e00bd633612e14d Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Fri, 27 Sep 2024 11:37:02 +0200 Subject: [PATCH 01/27] refactor(docker-compose): extract environment variables to .env file --- docker-compose.yml | 340 +++++++++++++++++++++++---------------------- env | 57 ++++++++ 2 files changed, 228 insertions(+), 169 deletions(-) create mode 100644 env diff --git a/docker-compose.yml b/docker-compose.yml index 5d48fe23f..bf9fea474 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,3 +1,5 @@ +version: '3.8' + volumes: lago_postgres_data: lago_redis_data: @@ -9,26 +11,26 @@ services: container_name: lago-db restart: unless-stopped environment: - POSTGRES_DB: ${POSTGRES_DB:-lago} - POSTGRES_USER: ${POSTGRES_USER:-lago} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme} - PGDATA: /data/postgres - PGPORT: ${POSTGRES_PORT:-5432} - POSTGRES_SCHEMA: public + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + PGDATA: ${PGDATA} + PGPORT: ${POSTGRES_PORT} + POSTGRES_SCHEMA: ${POSTGRES_SCHEMA} volumes: - lago_postgres_data:/data/postgres ports: - - ${POSTGRES_PORT:-5432}:${POSTGRES_PORT:-5432} + - ${POSTGRES_PORT}:${POSTGRES_PORT} redis: image: redis:6-alpine container_name: lago-redis restart: unless-stopped - command: --port ${REDIS_PORT:-6379} + command: --port ${REDIS_PORT} volumes: - lago_redis_data:/data ports: - - ${REDIS_PORT:-6379}:${REDIS_PORT:-6379} + - ${REDIS_PORT}:${REDIS_PORT} api: container_name: lago-api @@ -46,48 +48,48 @@ services: # uncomment for a potentially faster startup if you have docker --version > 25.0.0 # start_interval: 2s environment: - - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} - - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} - - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + - LAGO_API_URL=${LAGO_API_URL} + - DATABASE_URL=${DATABASE_URL} + - REDIS_URL=${REDIS_URL} - REDIS_PASSWORD=${REDIS_PASSWORD} - - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} - - RAILS_ENV=production - - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} + - SECRET_KEY_BASE=${SECRET_KEY_BASE} + - RAILS_ENV=${RAILS_ENV} + - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT} - SENTRY_DSN=${SENTRY_DSN} - - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} - - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + - LAGO_FRONT_URL=${LAGO_FRONT_URL} + - RSA_PRIVATE_KEY=${RSA_PRIVATE_KEY} # Should be base64 encoded - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - LAGO_SIDEKIQ_WEB=${LAGO_SIDEKIQ_WEB} - - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} - - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} - - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} - - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} - - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} - - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} - - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} - - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} + - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY} + - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY} + - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} + - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3} + - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID} + - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY} + - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION} + - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET} - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} - - LAGO_USE_GCS=${LAGO_USE_GCS:-false} - - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} - - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} - - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} - - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} + - LAGO_USE_GCS=${LAGO_USE_GCS} + - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT} + - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET} + - LAGO_PDF_URL=${LAGO_PDF_URL} + - LAGO_REDIS_CACHE_URL=${LAGO_REDIS_CACHE_URL} - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - - LAGO_OAUTH_PROXY_URL=https://proxy.getlago.com - - LAGO_LICENSE=${LAGO_LICENSE:-} - - GOOGLE_AUTH_CLIENT_ID=${GOOGLE_AUTH_CLIENT_ID:-} - - GOOGLE_AUTH_CLIENT_SECRET=${GOOGLE_AUTH_CLIENT_SECRET:-} - - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} - # - SIDEKIQ_EVENTS=true - # - SIDEKIQ_PDFS=true + - LAGO_OAUTH_PROXY_URL=${LAGO_OAUTH_PROXY_URL} + - LAGO_LICENSE=${LAGO_LICENSE} + - GOOGLE_AUTH_CLIENT_ID=${GOOGLE_AUTH_CLIENT_ID} + - GOOGLE_AUTH_CLIENT_SECRET=${GOOGLE_AUTH_CLIENT_SECRET} + - NANGO_SECRET_KEY=${NANGO_SECRET_KEY} + # - SIDEKIQ_EVENTS=${SIDEKIQ_EVENTS} + # - SIDEKIQ_PDFS=${SIDEKIQ_PDFS} volumes: - lago_storage_data:/app/storage # If using GCS, you need to put the credentials keyfile here - #- gcs_keyfile.json:/app/gcs_keyfile.json + # - gcs_keyfile.json:/app/gcs_keyfile.json ports: - - ${API_PORT:-3000}:3000 + - ${API_PORT}:3000 front: container_name: lago-front @@ -99,15 +101,15 @@ services: api: condition: service_healthy environment: - - API_URL=${LAGO_API_URL:-http://localhost:3000} - - APP_ENV=${APP_ENV:-production} - - LAGO_DISABLE_SIGNUP=${LAGO_DISABLE_SIGNUP:-false} - - LAGO_OAUTH_PROXY_URL=https://proxy.getlago.com + - API_URL=${LAGO_API_URL} + - APP_ENV=${APP_ENV} + - LAGO_DISABLE_SIGNUP=${LAGO_DISABLE_SIGNUP} + - LAGO_OAUTH_PROXY_URL=${LAGO_OAUTH_PROXY_URL} - SENTRY_DSN=${SENTRY_DSN_FRONT} - - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} + - NANGO_SECRET_KEY=${NANGO_SECRET_KEY} ports: - - ${FRONT_PORT:-80}:80 - # - 443:443 + - ${FRONT_PORT}:80 + # - 443:443 # Using SSL with Let's Encrypt # volumes: # - ./extra/nginx-letsencrypt.conf:/etc/nginx/conf.d/default.conf @@ -139,126 +141,126 @@ services: healthcheck: test: ['CMD-SHELL', 'bundle exec sidekiqmon | grep $(hostname) || exit 1'] environment: - - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} - - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} - - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + - LAGO_API_URL=${LAGO_API_URL} + - DATABASE_URL=${DATABASE_URL} + - REDIS_URL=${REDIS_URL} - REDIS_PASSWORD=${REDIS_PASSWORD} - - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} - - RAILS_ENV=production - - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} + - SECRET_KEY_BASE=${SECRET_KEY_BASE} + - RAILS_ENV=${RAILS_ENV} + - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT} - SENTRY_DSN=${SENTRY_DSN} - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} - - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} - - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} - - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} - - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} - - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} - - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} - - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} - - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} + - RSA_PRIVATE_KEY=${RSA_PRIVATE_KEY} # Should be base64 encoded + - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY} + - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY} + - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} + - LAGO_FRONT_URL=${LAGO_FRONT_URL} + - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3} + - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID} + - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY} + - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION} + - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET} - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} - - LAGO_USE_GCS=${LAGO_USE_GCS:-false} - - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} - - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} - - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} - - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} + - LAGO_USE_GCS=${LAGO_USE_GCS} + - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT} + - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET} + - LAGO_PDF_URL=${LAGO_PDF_URL} + - LAGO_REDIS_CACHE_URL=${LAGO_REDIS_CACHE_URL} - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} - - LAGO_LICENSE=${LAGO_LICENSE:-} - # - SIDEKIQ_EVENTS=true - # - SIDEKIQ_PDFS=true + - NANGO_SECRET_KEY=${NANGO_SECRET_KEY} + - LAGO_LICENSE=${LAGO_LICENSE} + # - SIDEKIQ_EVENTS=${SIDEKIQ_EVENTS} + # - SIDEKIQ_PDFS=${SIDEKIQ_PDFS} volumes: - lago_storage_data:/app/storage # You can uncomment this if you want to use a dedicated Sidekiq worker for the event ingestion. # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. - #api-events-worker: - # container_name: lago-events-worker - # image: getlago/api:v1.12.2 - # restart: unless-stopped - # depends_on: - # api: - # condition: service_healthy - # command: ["./scripts/start.events.worker.sh"] - # environment: - # - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} - # - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} - # - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} - # - REDIS_PASSWORD=${REDIS_PASSWORD} - # - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} - # - RAILS_ENV=production - # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} - # - SENTRY_DSN=${SENTRY_DSN} - # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} - # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} - # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} - # - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} - # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} - # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} - # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} - # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} - # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} - # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} - # - LAGO_USE_GCS=${LAGO_USE_GCS:-false} - # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} - # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} - # - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} - # - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} - # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} - # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} - # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} - # - SIDEKIQ_EVENTS=true - # - LAGO_LICENSE=${LAGO_LICENSE:-} + # api-events-worker: + # container_name: lago-events-worker + # image: getlago/api:v1.12.2 + # restart: unless-stopped + # depends_on: + # api: + # condition: service_healthy + # command: ["./scripts/start.events.worker.sh"] + # environment: + # - LAGO_API_URL=${LAGO_API_URL} + # - DATABASE_URL=${DATABASE_URL} + # - REDIS_URL=${REDIS_URL} + # - REDIS_PASSWORD=${REDIS_PASSWORD} + # - SECRET_KEY_BASE=${SECRET_KEY_BASE} + # - RAILS_ENV=${RAILS_ENV} + # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT} + # - SENTRY_DSN=${SENTRY_DSN} + # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + # - RSA_PRIVATE_KEY=${RSA_PRIVATE_KEY} # Should be base64 encoded + # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY} + # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY} + # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} + # - LAGO_FRONT_URL=${LAGO_FRONT_URL} + # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3} + # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID} + # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY} + # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION} + # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET} + # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} + # - LAGO_USE_GCS=${LAGO_USE_GCS} + # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT} + # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET} + # - LAGO_PDF_URL=${LAGO_PDF_URL} + # - LAGO_REDIS_CACHE_URL=${LAGO_REDIS_CACHE_URL} + # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} + # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} + # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} + # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY} + # - SIDEKIQ_EVENTS=true + # - LAGO_LICENSE=${LAGO_LICENSE} # You can uncomment this if you want to use a dedicated Sidekiq worker for the invoices pdf creation. # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs. - #api-pdfs-worker: - # container_name: lago-pdfs-worker - # image: getlago/api:v1.12.2 - # restart: unless-stopped - # depends_on: - # api: - # condition: service_healthy - # command: ["./scripts/start.pdfs.worker.sh"] - # environment: - # - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} - # - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} - # - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} - # - REDIS_PASSWORD=${REDIS_PASSWORD} - # - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} - # - RAILS_ENV=production - # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} - # - SENTRY_DSN=${SENTRY_DSN} - # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} - # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} - # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} - # - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} - # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} - # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} - # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} - # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} - # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} - # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} - # - LAGO_USE_GCS=${LAGO_USE_GCS:-false} - # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} - # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} - # - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} - # - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} - # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} - # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} - # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} - # - SIDEKIQ_PDFS=true - # - LAGO_LICENSE=${LAGO_LICENSE:-} + # api-pdfs-worker: + # container_name: lago-pdfs-worker + # image: getlago/api:v1.12.2 + # restart: unless-stopped + # depends_on: + # api: + # condition: service_healthy + # command: ["./scripts/start.pdfs.worker.sh"] + # environment: + # - LAGO_API_URL=${LAGO_API_URL} + # - DATABASE_URL=${DATABASE_URL} + # - REDIS_URL=${REDIS_URL} + # - REDIS_PASSWORD=${REDIS_PASSWORD} + # - SECRET_KEY_BASE=${SECRET_KEY_BASE} + # - RAILS_ENV=${RAILS_ENV} + # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT} + # - SENTRY_DSN=${SENTRY_DSN} + # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + # - RSA_PRIVATE_KEY=${RSA_PRIVATE_KEY} # Should be base64 encoded + # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY} + # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY} + # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} + # - LAGO_FRONT_URL=${LAGO_FRONT_URL} + # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3} + # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID} + # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY} + # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION} + # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET} + # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} + # - LAGO_USE_GCS=${LAGO_USE_GCS} + # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT} + # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET} + # - LAGO_PDF_URL=${LAGO_PDF_URL} + # - LAGO_REDIS_CACHE_URL=${LAGO_REDIS_CACHE_URL} + # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} + # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} + # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} + # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY} + # - SIDEKIQ_PDFS=true + # - LAGO_LICENSE=${LAGO_LICENSE} api-clock: container_name: lago-clock @@ -269,23 +271,23 @@ services: condition: service_healthy command: ['./scripts/start.clock.sh'] environment: - - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} - - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} - - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + - LAGO_API_URL=${LAGO_API_URL} + - DATABASE_URL=${DATABASE_URL} + - REDIS_URL=${REDIS_URL} - REDIS_PASSWORD=${REDIS_PASSWORD} - - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} - - RAILS_ENV=production - - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} + - SECRET_KEY_BASE=${SECRET_KEY_BASE} + - RAILS_ENV=${RAILS_ENV} + - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT} - SENTRY_DSN=${SENTRY_DSN} - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} + - LAGO_REDIS_CACHE_URL=${LAGO_REDIS_CACHE_URL} - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} - - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} - - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} - - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} - - LAGO_LICENSE=${LAGO_LICENSE:-} + - RSA_PRIVATE_KEY=${RSA_PRIVATE_KEY} # Should be base64 encoded + - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY} + - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY} + - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} + - NANGO_SECRET_KEY=${NANGO_SECRET_KEY} + - LAGO_LICENSE=${LAGO_LICENSE} pdf: image: getlago/lago-gotenberg:7.8.2 @@ -300,10 +302,10 @@ services: volumes: - lago_storage_data:/app/storage environment: - - RAILS_ENV=production - - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} - - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + - RAILS_ENV=${RAILS_ENV} + - SECRET_KEY_BASE=${SECRET_KEY_BASE} + - RSA_PRIVATE_KEY=${RSA_PRIVATE_KEY} # Should be base64 encoded - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} - - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + - DATABASE_URL=${DATABASE_URL} + - REDIS_URL=${REDIS_URL} - REDIS_PASSWORD=${REDIS_PASSWORD} diff --git a/env b/env new file mode 100644 index 000000000..c54c7dd97 --- /dev/null +++ b/env @@ -0,0 +1,57 @@ +# PostgreSQL Configuration +POSTGRES_DB=lago +POSTGRES_USER=lago +POSTGRES_PASSWORD=changeme +POSTGRES_PORT=5432 +POSTGRES_HOST=db +POSTGRES_SCHEMA=public +PGDATA=/data/postgres + +# Redis Configuration +REDIS_PORT=6379 +REDIS_HOST=redis +REDIS_PASSWORD= + +# Lago API Configuration +LAGO_API_URL=http://localhost:3000 +DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA} +REDIS_URL=redis://${REDIS_HOST}:${REDIS_PORT} +SECRET_KEY_BASE=your-secret-key-base-hex-64 +RAILS_ENV=production +LAGO_RAILS_STDOUT=true +SENTRY_DSN= +LAGO_FRONT_URL=http://localhost +RSA_PRIVATE_KEY= +LAGO_RSA_PRIVATE_KEY= +LAGO_SIDEKIQ_WEB= +LAGO_ENCRYPTION_PRIMARY_KEY=your-encryption-primary-key +LAGO_ENCRYPTION_DETERMINISTIC_KEY=your-encryption-deterministic-key +LAGO_ENCRYPTION_KEY_DERIVATION_SALT=your-encryption-derivation-salt +LAGO_USE_AWS_S3=false +LAGO_AWS_S3_ACCESS_KEY_ID=azerty123456 +LAGO_AWS_S3_SECRET_ACCESS_KEY=azerty123456 +LAGO_AWS_S3_REGION=us-east-1 +LAGO_AWS_S3_BUCKET=bucket +LAGO_AWS_S3_ENDPOINT= +LAGO_USE_GCS=false +LAGO_GCS_PROJECT= +LAGO_GCS_BUCKET= +LAGO_PDF_URL=http://pdf:3000 +LAGO_REDIS_CACHE_HOST=redis +LAGO_REDIS_CACHE_PORT=6379 +LAGO_REDIS_CACHE_PASSWORD= +LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT} +LAGO_DISABLE_SEGMENT= +LAGO_DISABLE_WALLET_REFRESH= +LAGO_OAUTH_PROXY_URL=https://proxy.getlago.com +LAGO_LICENSE= +GOOGLE_AUTH_CLIENT_ID= +GOOGLE_AUTH_CLIENT_SECRET= +NANGO_SECRET_KEY= +SIDEKIQ_EVENTS= +SIDEKIQ_PDFS= +API_PORT=3000 +FRONT_PORT=80 +APP_ENV=production +LAGO_DISABLE_SIGNUP=false +SENTRY_DSN_FRONT= From 7d1a2b6bf1850afeb23676ba82265c2bdf778c98 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Mon, 30 Sep 2024 15:44:28 +0200 Subject: [PATCH 02/27] refactor(docker-compose): apply DRY principle using YAML anchors for environment variable --- docker-compose.yml | 281 ++++++++++++++------------------------------- 1 file changed, 84 insertions(+), 197 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index bf9fea474..e747a82ab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,53 @@ volumes: lago_redis_data: lago_storage_data: +x-common-environment: &common-environment + LAGO_API_URL: ${LAGO_API_URL} + DATABASE_URL: ${DATABASE_URL} + REDIS_URL: ${REDIS_URL} + REDIS_PASSWORD: ${REDIS_PASSWORD} + SECRET_KEY_BASE: ${SECRET_KEY_BASE} + RAILS_ENV: ${RAILS_ENV} + RAILS_LOG_TO_STDOUT: ${LAGO_RAILS_STDOUT} + SENTRY_DSN: ${SENTRY_DSN} + LAGO_FRONT_URL: ${LAGO_FRONT_URL} + RSA_PRIVATE_KEY: ${RSA_PRIVATE_KEY} # Should be base64 encoded + LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + LAGO_ENCRYPTION_PRIMARY_KEY: ${LAGO_ENCRYPTION_PRIMARY_KEY} + LAGO_ENCRYPTION_DETERMINISTIC_KEY: ${LAGO_ENCRYPTION_DETERMINISTIC_KEY} + LAGO_ENCRYPTION_KEY_DERIVATION_SALT: ${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} + LAGO_USE_AWS_S3: ${LAGO_USE_AWS_S3} + LAGO_AWS_S3_ACCESS_KEY_ID: ${LAGO_AWS_S3_ACCESS_KEY_ID} + LAGO_AWS_S3_SECRET_ACCESS_KEY: ${LAGO_AWS_S3_SECRET_ACCESS_KEY} + LAGO_AWS_S3_REGION: ${LAGO_AWS_S3_REGION} + LAGO_AWS_S3_BUCKET: ${LAGO_AWS_S3_BUCKET} + LAGO_AWS_S3_ENDPOINT: ${LAGO_AWS_S3_ENDPOINT} + LAGO_USE_GCS: ${LAGO_USE_GCS} + LAGO_GCS_PROJECT: ${LAGO_GCS_PROJECT} + LAGO_GCS_BUCKET: ${LAGO_GCS_BUCKET} + LAGO_PDF_URL: ${LAGO_PDF_URL} + LAGO_REDIS_CACHE_URL: ${LAGO_REDIS_CACHE_URL} + LAGO_REDIS_CACHE_PASSWORD: ${LAGO_REDIS_CACHE_PASSWORD} + LAGO_DISABLE_SEGMENT: ${LAGO_DISABLE_SEGMENT} + LAGO_DISABLE_WALLET_REFRESH: ${LAGO_DISABLE_WALLET_REFRESH} + NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} + LAGO_LICENSE: ${LAGO_LICENSE} + +x-api-environment: &api-environment + <<: *common-environment + LAGO_SIDEKIQ_WEB: ${LAGO_SIDEKIQ_WEB} + LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} + GOOGLE_AUTH_CLIENT_ID: ${GOOGLE_AUTH_CLIENT_ID} + GOOGLE_AUTH_CLIENT_SECRET: ${GOOGLE_AUTH_CLIENT_SECRET} + +x-front-environment: &front-environment + API_URL: ${LAGO_API_URL} + APP_ENV: ${APP_ENV} + LAGO_DISABLE_SIGNUP: ${LAGO_DISABLE_SIGNUP} + LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} + SENTRY_DSN: ${SENTRY_DSN_FRONT} + NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} + services: db: image: postgres:14-alpine @@ -48,42 +95,8 @@ services: # uncomment for a potentially faster startup if you have docker --version > 25.0.0 # start_interval: 2s environment: - - LAGO_API_URL=${LAGO_API_URL} - - DATABASE_URL=${DATABASE_URL} - - REDIS_URL=${REDIS_URL} - - REDIS_PASSWORD=${REDIS_PASSWORD} - - SECRET_KEY_BASE=${SECRET_KEY_BASE} - - RAILS_ENV=${RAILS_ENV} - - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT} - - SENTRY_DSN=${SENTRY_DSN} - - LAGO_FRONT_URL=${LAGO_FRONT_URL} - - RSA_PRIVATE_KEY=${RSA_PRIVATE_KEY} # Should be base64 encoded - - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - - LAGO_SIDEKIQ_WEB=${LAGO_SIDEKIQ_WEB} - - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY} - - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY} - - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} - - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3} - - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID} - - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY} - - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION} - - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET} - - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} - - LAGO_USE_GCS=${LAGO_USE_GCS} - - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT} - - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET} - - LAGO_PDF_URL=${LAGO_PDF_URL} - - LAGO_REDIS_CACHE_URL=${LAGO_REDIS_CACHE_URL} - - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} - - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} - - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - - LAGO_OAUTH_PROXY_URL=${LAGO_OAUTH_PROXY_URL} - - LAGO_LICENSE=${LAGO_LICENSE} - - GOOGLE_AUTH_CLIENT_ID=${GOOGLE_AUTH_CLIENT_ID} - - GOOGLE_AUTH_CLIENT_SECRET=${GOOGLE_AUTH_CLIENT_SECRET} - - NANGO_SECRET_KEY=${NANGO_SECRET_KEY} - # - SIDEKIQ_EVENTS=${SIDEKIQ_EVENTS} - # - SIDEKIQ_PDFS=${SIDEKIQ_PDFS} + <<: *api-environment + volumes: - lago_storage_data:/app/storage # If using GCS, you need to put the credentials keyfile here @@ -101,34 +114,9 @@ services: api: condition: service_healthy environment: - - API_URL=${LAGO_API_URL} - - APP_ENV=${APP_ENV} - - LAGO_DISABLE_SIGNUP=${LAGO_DISABLE_SIGNUP} - - LAGO_OAUTH_PROXY_URL=${LAGO_OAUTH_PROXY_URL} - - SENTRY_DSN=${SENTRY_DSN_FRONT} - - NANGO_SECRET_KEY=${NANGO_SECRET_KEY} + <<: *front-environment ports: - ${FRONT_PORT}:80 - # - 443:443 - # Using SSL with Let's Encrypt - # volumes: - # - ./extra/nginx-letsencrypt.conf:/etc/nginx/conf.d/default.conf - # - ./extra/certbot/conf:/etc/letsencrypt - # - ./extra/certbot/www:/var/www/certbot - # Using SSL with self signed certificates - # volumes: - # - ./extra/nginx-selfsigned.conf:/etc/nginx/conf.d/default.conf - # - ./extra/ssl/nginx-selfsigned.crt:/etc/ssl/certs/nginx-selfsigned.crt - # - ./extra/ssl/nginx-selfsigned.key:/etc/ssl/private/nginx-selfsigned.key - # - ./extra/ssl/dhparam.pem:/etc/ssl/certs/dhparam.pem - - # Only used for SSL support with Let's Encrypt - # certbot: - # image: certbot/certbot - # entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" - # volumes: - # - ./extra/certbot/conf:/etc/letsencrypt - # - ./extra/certbot/www:/var/www/certbot api-worker: container_name: lago-worker @@ -141,127 +129,13 @@ services: healthcheck: test: ['CMD-SHELL', 'bundle exec sidekiqmon | grep $(hostname) || exit 1'] environment: - - LAGO_API_URL=${LAGO_API_URL} - - DATABASE_URL=${DATABASE_URL} - - REDIS_URL=${REDIS_URL} - - REDIS_PASSWORD=${REDIS_PASSWORD} - - SECRET_KEY_BASE=${SECRET_KEY_BASE} - - RAILS_ENV=${RAILS_ENV} - - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT} - - SENTRY_DSN=${SENTRY_DSN} - - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - - RSA_PRIVATE_KEY=${RSA_PRIVATE_KEY} # Should be base64 encoded - - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY} - - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY} - - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} - - LAGO_FRONT_URL=${LAGO_FRONT_URL} - - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3} - - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID} - - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY} - - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION} - - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET} - - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} - - LAGO_USE_GCS=${LAGO_USE_GCS} - - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT} - - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET} - - LAGO_PDF_URL=${LAGO_PDF_URL} - - LAGO_REDIS_CACHE_URL=${LAGO_REDIS_CACHE_URL} - - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} - - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} - - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - - NANGO_SECRET_KEY=${NANGO_SECRET_KEY} - - LAGO_LICENSE=${LAGO_LICENSE} - # - SIDEKIQ_EVENTS=${SIDEKIQ_EVENTS} - # - SIDEKIQ_PDFS=${SIDEKIQ_PDFS} + <<: *common-environment + # Variables spécifiques au worker, si nécessaire + # SIDEKIQ_EVENTS: ${SIDEKIQ_EVENTS} + # SIDEKIQ_PDFS: ${SIDEKIQ_PDFS} volumes: - lago_storage_data:/app/storage - # You can uncomment this if you want to use a dedicated Sidekiq worker for the event ingestion. - # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. - # api-events-worker: - # container_name: lago-events-worker - # image: getlago/api:v1.12.2 - # restart: unless-stopped - # depends_on: - # api: - # condition: service_healthy - # command: ["./scripts/start.events.worker.sh"] - # environment: - # - LAGO_API_URL=${LAGO_API_URL} - # - DATABASE_URL=${DATABASE_URL} - # - REDIS_URL=${REDIS_URL} - # - REDIS_PASSWORD=${REDIS_PASSWORD} - # - SECRET_KEY_BASE=${SECRET_KEY_BASE} - # - RAILS_ENV=${RAILS_ENV} - # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT} - # - SENTRY_DSN=${SENTRY_DSN} - # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - RSA_PRIVATE_KEY=${RSA_PRIVATE_KEY} # Should be base64 encoded - # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY} - # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY} - # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} - # - LAGO_FRONT_URL=${LAGO_FRONT_URL} - # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3} - # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID} - # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY} - # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION} - # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET} - # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} - # - LAGO_USE_GCS=${LAGO_USE_GCS} - # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT} - # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET} - # - LAGO_PDF_URL=${LAGO_PDF_URL} - # - LAGO_REDIS_CACHE_URL=${LAGO_REDIS_CACHE_URL} - # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} - # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} - # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY} - # - SIDEKIQ_EVENTS=true - # - LAGO_LICENSE=${LAGO_LICENSE} - - # You can uncomment this if you want to use a dedicated Sidekiq worker for the invoices pdf creation. - # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs. - # api-pdfs-worker: - # container_name: lago-pdfs-worker - # image: getlago/api:v1.12.2 - # restart: unless-stopped - # depends_on: - # api: - # condition: service_healthy - # command: ["./scripts/start.pdfs.worker.sh"] - # environment: - # - LAGO_API_URL=${LAGO_API_URL} - # - DATABASE_URL=${DATABASE_URL} - # - REDIS_URL=${REDIS_URL} - # - REDIS_PASSWORD=${REDIS_PASSWORD} - # - SECRET_KEY_BASE=${SECRET_KEY_BASE} - # - RAILS_ENV=${RAILS_ENV} - # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT} - # - SENTRY_DSN=${SENTRY_DSN} - # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - RSA_PRIVATE_KEY=${RSA_PRIVATE_KEY} # Should be base64 encoded - # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY} - # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY} - # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} - # - LAGO_FRONT_URL=${LAGO_FRONT_URL} - # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3} - # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID} - # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY} - # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION} - # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET} - # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} - # - LAGO_USE_GCS=${LAGO_USE_GCS} - # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT} - # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET} - # - LAGO_PDF_URL=${LAGO_PDF_URL} - # - LAGO_REDIS_CACHE_URL=${LAGO_REDIS_CACHE_URL} - # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} - # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} - # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY} - # - SIDEKIQ_PDFS=true - # - LAGO_LICENSE=${LAGO_LICENSE} - api-clock: container_name: lago-clock image: getlago/api:v1.12.2 @@ -271,23 +145,7 @@ services: condition: service_healthy command: ['./scripts/start.clock.sh'] environment: - - LAGO_API_URL=${LAGO_API_URL} - - DATABASE_URL=${DATABASE_URL} - - REDIS_URL=${REDIS_URL} - - REDIS_PASSWORD=${REDIS_PASSWORD} - - SECRET_KEY_BASE=${SECRET_KEY_BASE} - - RAILS_ENV=${RAILS_ENV} - - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT} - - SENTRY_DSN=${SENTRY_DSN} - - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - - LAGO_REDIS_CACHE_URL=${LAGO_REDIS_CACHE_URL} - - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - - RSA_PRIVATE_KEY=${RSA_PRIVATE_KEY} # Should be base64 encoded - - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY} - - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY} - - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} - - NANGO_SECRET_KEY=${NANGO_SECRET_KEY} - - LAGO_LICENSE=${LAGO_LICENSE} + <<: *common-environment pdf: image: getlago/lago-gotenberg:7.8.2 @@ -309,3 +167,32 @@ services: - DATABASE_URL=${DATABASE_URL} - REDIS_URL=${REDIS_URL} - REDIS_PASSWORD=${REDIS_PASSWORD} + + + + # You can uncomment this if you want to use a dedicated Sidekiq worker for the event ingestion. + # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. + # api-events-worker: + # container_name: lago-events-worker + # image: getlago/api:v1.12.2 + # restart: unless-stopped + # depends_on: + # api: + # condition: service_healthy + # command: ["./scripts/start.events.worker.sh"] + # environment: + # <<: *api-environment + + + # You can uncomment this if you want to use a dedicated Sidekiq worker for the invoices pdf creation. + # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs. + # api-pdfs-worker: + # container_name: lago-pdfs-worker + # image: getlago/api:v1.12.2 + # restart: unless-stopped + # depends_on: + # api: + # condition: service_healthy + # command: ["./scripts/start.pdfs.worker.sh"] + # environment: + # <<: *api-environment \ No newline at end of file From 1021b1d4412e54073b3f25bcb6442bc864e18e11 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Wed, 2 Oct 2024 11:26:56 +0200 Subject: [PATCH 03/27] refactor(docker-compose): add healthchecks and improve dependency handling for services; remove container_name from db, redis, and api-worker --- docker-compose.yml | 126 +++++++++++++++++++++++++-------------------- env | 45 +++++++++++----- 2 files changed, 103 insertions(+), 68 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index e747a82ab..e0bdf811e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,57 +5,9 @@ volumes: lago_redis_data: lago_storage_data: -x-common-environment: &common-environment - LAGO_API_URL: ${LAGO_API_URL} - DATABASE_URL: ${DATABASE_URL} - REDIS_URL: ${REDIS_URL} - REDIS_PASSWORD: ${REDIS_PASSWORD} - SECRET_KEY_BASE: ${SECRET_KEY_BASE} - RAILS_ENV: ${RAILS_ENV} - RAILS_LOG_TO_STDOUT: ${LAGO_RAILS_STDOUT} - SENTRY_DSN: ${SENTRY_DSN} - LAGO_FRONT_URL: ${LAGO_FRONT_URL} - RSA_PRIVATE_KEY: ${RSA_PRIVATE_KEY} # Should be base64 encoded - LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - LAGO_ENCRYPTION_PRIMARY_KEY: ${LAGO_ENCRYPTION_PRIMARY_KEY} - LAGO_ENCRYPTION_DETERMINISTIC_KEY: ${LAGO_ENCRYPTION_DETERMINISTIC_KEY} - LAGO_ENCRYPTION_KEY_DERIVATION_SALT: ${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} - LAGO_USE_AWS_S3: ${LAGO_USE_AWS_S3} - LAGO_AWS_S3_ACCESS_KEY_ID: ${LAGO_AWS_S3_ACCESS_KEY_ID} - LAGO_AWS_S3_SECRET_ACCESS_KEY: ${LAGO_AWS_S3_SECRET_ACCESS_KEY} - LAGO_AWS_S3_REGION: ${LAGO_AWS_S3_REGION} - LAGO_AWS_S3_BUCKET: ${LAGO_AWS_S3_BUCKET} - LAGO_AWS_S3_ENDPOINT: ${LAGO_AWS_S3_ENDPOINT} - LAGO_USE_GCS: ${LAGO_USE_GCS} - LAGO_GCS_PROJECT: ${LAGO_GCS_PROJECT} - LAGO_GCS_BUCKET: ${LAGO_GCS_BUCKET} - LAGO_PDF_URL: ${LAGO_PDF_URL} - LAGO_REDIS_CACHE_URL: ${LAGO_REDIS_CACHE_URL} - LAGO_REDIS_CACHE_PASSWORD: ${LAGO_REDIS_CACHE_PASSWORD} - LAGO_DISABLE_SEGMENT: ${LAGO_DISABLE_SEGMENT} - LAGO_DISABLE_WALLET_REFRESH: ${LAGO_DISABLE_WALLET_REFRESH} - NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} - LAGO_LICENSE: ${LAGO_LICENSE} - -x-api-environment: &api-environment - <<: *common-environment - LAGO_SIDEKIQ_WEB: ${LAGO_SIDEKIQ_WEB} - LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} - GOOGLE_AUTH_CLIENT_ID: ${GOOGLE_AUTH_CLIENT_ID} - GOOGLE_AUTH_CLIENT_SECRET: ${GOOGLE_AUTH_CLIENT_SECRET} - -x-front-environment: &front-environment - API_URL: ${LAGO_API_URL} - APP_ENV: ${APP_ENV} - LAGO_DISABLE_SIGNUP: ${LAGO_DISABLE_SIGNUP} - LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} - SENTRY_DSN: ${SENTRY_DSN_FRONT} - NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} - services: db: image: postgres:14-alpine - container_name: lago-db restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB} @@ -68,6 +20,11 @@ services: - lago_postgres_data:/data/postgres ports: - ${POSTGRES_PORT}:${POSTGRES_PORT} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] + interval: 10s + timeout: 5s + retries: 5 redis: image: redis:6-alpine @@ -78,14 +35,21 @@ services: - lago_redis_data:/data ports: - ${REDIS_PORT}:${REDIS_PORT} + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 api: container_name: lago-api image: getlago/api:v1.12.2 restart: unless-stopped depends_on: - - db - - redis + db: + condition: service_healthy + redis: + condition: service_healthy command: ['./scripts/start.sh'] healthcheck: test: curl -f http://localhost:3000/health || exit 1 @@ -108,8 +72,6 @@ services: container_name: lago-front image: getlago/front:v1.12.2 restart: unless-stopped - # Use this command if you want to use SSL with Let's Encrypt - # command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" depends_on: api: condition: service_healthy @@ -117,6 +79,12 @@ services: <<: *front-environment ports: - ${FRONT_PORT}:80 + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:${FRONT_PORT}"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s api-worker: container_name: lago-worker @@ -130,7 +98,6 @@ services: test: ['CMD-SHELL', 'bundle exec sidekiqmon | grep $(hostname) || exit 1'] environment: <<: *common-environment - # Variables spécifiques au worker, si nécessaire # SIDEKIQ_EVENTS: ${SIDEKIQ_EVENTS} # SIDEKIQ_PDFS: ${SIDEKIQ_PDFS} volumes: @@ -154,8 +121,10 @@ services: container_name: lago-migrate image: getlago/api:v1.12.2 depends_on: - - db - - redis + db: + condition: service_healthy + redis: + condition: service_healthy command: ['./scripts/start.migrate.sh'] volumes: - lago_storage_data:/app/storage @@ -169,7 +138,54 @@ services: - REDIS_PASSWORD=${REDIS_PASSWORD} +x-common-environment: &common-environment + LAGO_API_URL: ${LAGO_API_URL} + DATABASE_URL: ${DATABASE_URL} + REDIS_URL: ${REDIS_URL} + REDIS_PASSWORD: ${REDIS_PASSWORD} + SECRET_KEY_BASE: ${SECRET_KEY_BASE} + RAILS_ENV: ${RAILS_ENV} + RAILS_LOG_TO_STDOUT: ${LAGO_RAILS_STDOUT} + SENTRY_DSN: ${SENTRY_DSN} + LAGO_FRONT_URL: ${LAGO_FRONT_URL} + RSA_PRIVATE_KEY: ${RSA_PRIVATE_KEY} # Should be base64 encoded + LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + LAGO_ENCRYPTION_PRIMARY_KEY: ${LAGO_ENCRYPTION_PRIMARY_KEY} + LAGO_ENCRYPTION_DETERMINISTIC_KEY: ${LAGO_ENCRYPTION_DETERMINISTIC_KEY} + LAGO_ENCRYPTION_KEY_DERIVATION_SALT: ${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} + LAGO_USE_AWS_S3: ${LAGO_USE_AWS_S3} + LAGO_AWS_S3_ACCESS_KEY_ID: ${LAGO_AWS_S3_ACCESS_KEY_ID} + LAGO_AWS_S3_SECRET_ACCESS_KEY: ${LAGO_AWS_S3_SECRET_ACCESS_KEY} + LAGO_AWS_S3_REGION: ${LAGO_AWS_S3_REGION} + LAGO_AWS_S3_BUCKET: ${LAGO_AWS_S3_BUCKET} + LAGO_AWS_S3_ENDPOINT: ${LAGO_AWS_S3_ENDPOINT} + LAGO_USE_GCS: ${LAGO_USE_GCS} + LAGO_GCS_PROJECT: ${LAGO_GCS_PROJECT} + LAGO_GCS_BUCKET: ${LAGO_GCS_BUCKET} + LAGO_PDF_URL: ${LAGO_PDF_URL} + LAGO_REDIS_CACHE_URL: ${LAGO_REDIS_CACHE_URL} + LAGO_REDIS_CACHE_PASSWORD: ${LAGO_REDIS_CACHE_PASSWORD} + LAGO_DISABLE_SEGMENT: ${LAGO_DISABLE_SEGMENT} + LAGO_DISABLE_WALLET_REFRESH: ${LAGO_DISABLE_WALLET_REFRESH} + NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} + LAGO_LICENSE: ${LAGO_LICENSE} + +x-api-environment: &api-environment + <<: *common-environment + LAGO_SIDEKIQ_WEB: ${LAGO_SIDEKIQ_WEB} + LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} + GOOGLE_AUTH_CLIENT_ID: ${GOOGLE_AUTH_CLIENT_ID} + GOOGLE_AUTH_CLIENT_SECRET: ${GOOGLE_AUTH_CLIENT_SECRET} + +x-front-environment: &front-environment + API_URL: ${LAGO_API_URL} + APP_ENV: ${APP_ENV} + LAGO_DISABLE_SIGNUP: ${LAGO_DISABLE_SIGNUP} + LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} + SENTRY_DSN: ${SENTRY_DSN_FRONT} + NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} + # You can uncomment this if you want to use a dedicated Sidekiq worker for the event ingestion. # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. # api-events-worker: diff --git a/env b/env index c54c7dd97..9a83b5138 100644 --- a/env +++ b/env @@ -1,17 +1,24 @@ +#See more informations here : https://doc.getlago.com/guide/self-hosted/docker + + # PostgreSQL Configuration POSTGRES_DB=lago POSTGRES_USER=lago POSTGRES_PASSWORD=changeme -POSTGRES_PORT=5432 POSTGRES_HOST=db +POSTGRES_PORT=5432 POSTGRES_SCHEMA=public PGDATA=/data/postgres # Redis Configuration -REDIS_PORT=6379 REDIS_HOST=redis +REDIS_PORT=6379 REDIS_PASSWORD= +# Application Ports +API_PORT=3000 +FRONT_PORT=80 + # Lago API Configuration LAGO_API_URL=http://localhost:3000 DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA} @@ -19,39 +26,51 @@ REDIS_URL=redis://${REDIS_HOST}:${REDIS_PORT} SECRET_KEY_BASE=your-secret-key-base-hex-64 RAILS_ENV=production LAGO_RAILS_STDOUT=true -SENTRY_DSN= LAGO_FRONT_URL=http://localhost +LAGO_PDF_URL=http://pdf:3000 +LAGO_DISABLE_SIGNUP=false +APP_ENV=production + +# Encryption Keys RSA_PRIVATE_KEY= LAGO_RSA_PRIVATE_KEY= -LAGO_SIDEKIQ_WEB= LAGO_ENCRYPTION_PRIMARY_KEY=your-encryption-primary-key LAGO_ENCRYPTION_DETERMINISTIC_KEY=your-encryption-deterministic-key LAGO_ENCRYPTION_KEY_DERIVATION_SALT=your-encryption-derivation-salt + +# AWS S3 Configuration LAGO_USE_AWS_S3=false LAGO_AWS_S3_ACCESS_KEY_ID=azerty123456 LAGO_AWS_S3_SECRET_ACCESS_KEY=azerty123456 LAGO_AWS_S3_REGION=us-east-1 LAGO_AWS_S3_BUCKET=bucket LAGO_AWS_S3_ENDPOINT= + +# Google Cloud Storage Configuration LAGO_USE_GCS=false LAGO_GCS_PROJECT= LAGO_GCS_BUCKET= -LAGO_PDF_URL=http://pdf:3000 + +# Redis Cache Configuration LAGO_REDIS_CACHE_HOST=redis LAGO_REDIS_CACHE_PORT=6379 LAGO_REDIS_CACHE_PASSWORD= LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT} + +# Sentry Configuration +SENTRY_DSN= +SENTRY_DSN_FRONT= + +# Lago Feature Flags LAGO_DISABLE_SEGMENT= LAGO_DISABLE_WALLET_REFRESH= +LAGO_SIDEKIQ_WEB= +SIDEKIQ_EVENTS= +SIDEKIQ_PDFS= + +# OAuth and Authentication LAGO_OAUTH_PROXY_URL=https://proxy.getlago.com -LAGO_LICENSE= GOOGLE_AUTH_CLIENT_ID= GOOGLE_AUTH_CLIENT_SECRET= NANGO_SECRET_KEY= -SIDEKIQ_EVENTS= -SIDEKIQ_PDFS= -API_PORT=3000 -FRONT_PORT=80 -APP_ENV=production -LAGO_DISABLE_SIGNUP=false -SENTRY_DSN_FRONT= +LAGO_LICENSE= From c4b23235460ed6911931dab0bdc2fbb7c33f572f Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Thu, 3 Oct 2024 15:42:44 +0200 Subject: [PATCH 04/27] refactor: improve environment variables management by using common and specific anchors --- docker-compose.yml | 115 +++++++++++++++++++++++---------------------- env | 4 -- 2 files changed, 60 insertions(+), 59 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index e0bdf811e..a7c455140 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,10 +1,52 @@ -version: '3.8' - volumes: lago_postgres_data: lago_redis_data: lago_storage_data: +x-common-environment: &common-environment + LAGO_API_URL: ${LAGO_API_URL} + REDIS_PASSWORD: ${REDIS_PASSWORD} + SECRET_KEY_BASE: ${SECRET_KEY_BASE} + RAILS_ENV: ${RAILS_ENV} + RAILS_LOG_TO_STDOUT: ${LAGO_RAILS_STDOUT} + SENTRY_DSN: ${SENTRY_DSN} + LAGO_FRONT_URL: ${LAGO_FRONT_URL} + LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + LAGO_ENCRYPTION_PRIMARY_KEY: ${LAGO_ENCRYPTION_PRIMARY_KEY} + LAGO_ENCRYPTION_DETERMINISTIC_KEY: ${LAGO_ENCRYPTION_DETERMINISTIC_KEY} + LAGO_ENCRYPTION_KEY_DERIVATION_SALT: ${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} + LAGO_USE_AWS_S3: ${LAGO_USE_AWS_S3} + LAGO_AWS_S3_ACCESS_KEY_ID: ${LAGO_AWS_S3_ACCESS_KEY_ID} + LAGO_AWS_S3_SECRET_ACCESS_KEY: ${LAGO_AWS_S3_SECRET_ACCESS_KEY} + LAGO_AWS_S3_REGION: ${LAGO_AWS_S3_REGION} + LAGO_AWS_S3_BUCKET: ${LAGO_AWS_S3_BUCKET} + LAGO_AWS_S3_ENDPOINT: ${LAGO_AWS_S3_ENDPOINT} + LAGO_USE_GCS: ${LAGO_USE_GCS} + LAGO_GCS_PROJECT: ${LAGO_GCS_PROJECT} + LAGO_GCS_BUCKET: ${LAGO_GCS_BUCKET} + LAGO_PDF_URL: ${LAGO_PDF_URL} + LAGO_REDIS_CACHE_PASSWORD: ${LAGO_REDIS_CACHE_PASSWORD} + LAGO_DISABLE_SEGMENT: ${LAGO_DISABLE_SEGMENT} + LAGO_DISABLE_WALLET_REFRESH: ${LAGO_DISABLE_WALLET_REFRESH} + NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} + LAGO_LICENSE: ${LAGO_LICENSE} + +x-api-environment: &api-environment + <<: *common-environment + LAGO_SIDEKIQ_WEB: ${LAGO_SIDEKIQ_WEB} + LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} + GOOGLE_AUTH_CLIENT_ID: ${GOOGLE_AUTH_CLIENT_ID} + GOOGLE_AUTH_CLIENT_SECRET: ${GOOGLE_AUTH_CLIENT_SECRET} + +x-front-environment: &front-environment + API_URL: ${LAGO_API_URL} + APP_ENV: ${APP_ENV} + LAGO_DISABLE_SIGNUP: ${LAGO_DISABLE_SIGNUP} + LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} + SENTRY_DSN: ${SENTRY_DSN_FRONT} + NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} + + services: db: image: postgres:14-alpine @@ -60,7 +102,8 @@ services: # start_interval: 2s environment: <<: *api-environment - + DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" + REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT}" volumes: - lago_storage_data:/app/storage # If using GCS, you need to put the credentials keyfile here @@ -68,6 +111,7 @@ services: ports: - ${API_PORT}:3000 + front: container_name: lago-front image: getlago/front:v1.12.2 @@ -77,6 +121,7 @@ services: condition: service_healthy environment: <<: *front-environment + ports: - ${FRONT_PORT}:80 healthcheck: @@ -98,6 +143,9 @@ services: test: ['CMD-SHELL', 'bundle exec sidekiqmon | grep $(hostname) || exit 1'] environment: <<: *common-environment + LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT}" + DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" + REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT}" # SIDEKIQ_EVENTS: ${SIDEKIQ_EVENTS} # SIDEKIQ_PDFS: ${SIDEKIQ_PDFS} volumes: @@ -113,6 +161,9 @@ services: command: ['./scripts/start.clock.sh'] environment: <<: *common-environment + LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT}" + DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" + REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT}" pdf: image: getlago/lago-gotenberg:7.8.2 @@ -129,61 +180,15 @@ services: volumes: - lago_storage_data:/app/storage environment: - - RAILS_ENV=${RAILS_ENV} - - SECRET_KEY_BASE=${SECRET_KEY_BASE} - - RSA_PRIVATE_KEY=${RSA_PRIVATE_KEY} # Should be base64 encoded - - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - - DATABASE_URL=${DATABASE_URL} - - REDIS_URL=${REDIS_URL} - - REDIS_PASSWORD=${REDIS_PASSWORD} + RAILS_ENV: ${RAILS_ENV} + SECRET_KEY_BASE: ${SECRET_KEY_BASE} + LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" + REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT}" + REDIS_PASSWORD: ${REDIS_PASSWORD} -x-common-environment: &common-environment - LAGO_API_URL: ${LAGO_API_URL} - DATABASE_URL: ${DATABASE_URL} - REDIS_URL: ${REDIS_URL} - REDIS_PASSWORD: ${REDIS_PASSWORD} - SECRET_KEY_BASE: ${SECRET_KEY_BASE} - RAILS_ENV: ${RAILS_ENV} - RAILS_LOG_TO_STDOUT: ${LAGO_RAILS_STDOUT} - SENTRY_DSN: ${SENTRY_DSN} - LAGO_FRONT_URL: ${LAGO_FRONT_URL} - RSA_PRIVATE_KEY: ${RSA_PRIVATE_KEY} # Should be base64 encoded - LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - LAGO_ENCRYPTION_PRIMARY_KEY: ${LAGO_ENCRYPTION_PRIMARY_KEY} - LAGO_ENCRYPTION_DETERMINISTIC_KEY: ${LAGO_ENCRYPTION_DETERMINISTIC_KEY} - LAGO_ENCRYPTION_KEY_DERIVATION_SALT: ${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} - LAGO_USE_AWS_S3: ${LAGO_USE_AWS_S3} - LAGO_AWS_S3_ACCESS_KEY_ID: ${LAGO_AWS_S3_ACCESS_KEY_ID} - LAGO_AWS_S3_SECRET_ACCESS_KEY: ${LAGO_AWS_S3_SECRET_ACCESS_KEY} - LAGO_AWS_S3_REGION: ${LAGO_AWS_S3_REGION} - LAGO_AWS_S3_BUCKET: ${LAGO_AWS_S3_BUCKET} - LAGO_AWS_S3_ENDPOINT: ${LAGO_AWS_S3_ENDPOINT} - LAGO_USE_GCS: ${LAGO_USE_GCS} - LAGO_GCS_PROJECT: ${LAGO_GCS_PROJECT} - LAGO_GCS_BUCKET: ${LAGO_GCS_BUCKET} - LAGO_PDF_URL: ${LAGO_PDF_URL} - LAGO_REDIS_CACHE_URL: ${LAGO_REDIS_CACHE_URL} - LAGO_REDIS_CACHE_PASSWORD: ${LAGO_REDIS_CACHE_PASSWORD} - LAGO_DISABLE_SEGMENT: ${LAGO_DISABLE_SEGMENT} - LAGO_DISABLE_WALLET_REFRESH: ${LAGO_DISABLE_WALLET_REFRESH} - NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} - LAGO_LICENSE: ${LAGO_LICENSE} - -x-api-environment: &api-environment - <<: *common-environment - LAGO_SIDEKIQ_WEB: ${LAGO_SIDEKIQ_WEB} - LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} - GOOGLE_AUTH_CLIENT_ID: ${GOOGLE_AUTH_CLIENT_ID} - GOOGLE_AUTH_CLIENT_SECRET: ${GOOGLE_AUTH_CLIENT_SECRET} -x-front-environment: &front-environment - API_URL: ${LAGO_API_URL} - APP_ENV: ${APP_ENV} - LAGO_DISABLE_SIGNUP: ${LAGO_DISABLE_SIGNUP} - LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} - SENTRY_DSN: ${SENTRY_DSN_FRONT} - NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} # You can uncomment this if you want to use a dedicated Sidekiq worker for the event ingestion. diff --git a/env b/env index 9a83b5138..cf81b77b0 100644 --- a/env +++ b/env @@ -21,8 +21,6 @@ FRONT_PORT=80 # Lago API Configuration LAGO_API_URL=http://localhost:3000 -DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA} -REDIS_URL=redis://${REDIS_HOST}:${REDIS_PORT} SECRET_KEY_BASE=your-secret-key-base-hex-64 RAILS_ENV=production LAGO_RAILS_STDOUT=true @@ -32,7 +30,6 @@ LAGO_DISABLE_SIGNUP=false APP_ENV=production # Encryption Keys -RSA_PRIVATE_KEY= LAGO_RSA_PRIVATE_KEY= LAGO_ENCRYPTION_PRIMARY_KEY=your-encryption-primary-key LAGO_ENCRYPTION_DETERMINISTIC_KEY=your-encryption-deterministic-key @@ -55,7 +52,6 @@ LAGO_GCS_BUCKET= LAGO_REDIS_CACHE_HOST=redis LAGO_REDIS_CACHE_PORT=6379 LAGO_REDIS_CACHE_PASSWORD= -LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT} # Sentry Configuration SENTRY_DSN= From 30aabdd8a9a9c9925c2de00e8eb54748b04fb9cd Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Fri, 4 Oct 2024 10:37:14 +0200 Subject: [PATCH 05/27] feat(docker-compose): integrate Traefik for SSL management and improve service configurations --- docker-compose.yml | 182 ++++++++++++++++++++++----------------------- 1 file changed, 87 insertions(+), 95 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index a7c455140..a5d1bfe25 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,6 +2,8 @@ volumes: lago_postgres_data: lago_redis_data: lago_storage_data: + traefik_certificates: + traefik_config: x-common-environment: &common-environment LAGO_API_URL: ${LAGO_API_URL} @@ -11,7 +13,7 @@ x-common-environment: &common-environment RAILS_LOG_TO_STDOUT: ${LAGO_RAILS_STDOUT} SENTRY_DSN: ${SENTRY_DSN} LAGO_FRONT_URL: ${LAGO_FRONT_URL} - LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} LAGO_ENCRYPTION_PRIMARY_KEY: ${LAGO_ENCRYPTION_PRIMARY_KEY} LAGO_ENCRYPTION_DETERMINISTIC_KEY: ${LAGO_ENCRYPTION_DETERMINISTIC_KEY} LAGO_ENCRYPTION_KEY_DERIVATION_SALT: ${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} @@ -46,42 +48,32 @@ x-front-environment: &front-environment SENTRY_DSN: ${SENTRY_DSN_FRONT} NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} - services: - db: - image: postgres:14-alpine + traefik: + image: traefik:v2.5 + container_name: traefik restart: unless-stopped - environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - PGDATA: ${PGDATA} - PGPORT: ${POSTGRES_PORT} - POSTGRES_SCHEMA: ${POSTGRES_SCHEMA} - volumes: - - lago_postgres_data:/data/postgres + command: + - "--api.insecure=true" + - "--providers.docker=true" + - "--entrypoints.web.address=:80" + - "--entrypoints.websecure.address=:443" + - "--entrypoints.web.http.redirections.entrypoint.to=websecure" + - "--certificatesresolvers.selfsigned.acme.tlschallenge=true" + - "--certificatesresolvers.selfsigned.acme.email=your-email@example.com" + - "--certificatesresolvers.selfsigned.acme.storage=/letsencrypt/acme.json" ports: - - ${POSTGRES_PORT}:${POSTGRES_PORT} - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] - interval: 10s - timeout: 5s - retries: 5 - - redis: - image: redis:6-alpine - container_name: lago-redis - restart: unless-stopped - command: --port ${REDIS_PORT} + - "80:80" + - "8443:443" volumes: - - lago_redis_data:/data - ports: - - ${REDIS_PORT}:${REDIS_PORT} - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 10s - timeout: 5s - retries: 5 + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - traefik_certificates:/letsencrypt + - traefik_config:/traefik + + labels: + - "traefik.http.routers.api.entrypoints=websecure" + - "traefik.http.routers.api.rule=Host(`localhost`)" + - "traefik.http.services.api.loadbalancer.server.port=3000" api: container_name: lago-api @@ -93,24 +85,24 @@ services: redis: condition: service_healthy command: ['./scripts/start.sh'] - healthcheck: - test: curl -f http://localhost:3000/health || exit 1 - interval: 10s - start_period: 30s - timeout: 60s - # uncomment for a potentially faster startup if you have docker --version > 25.0.0 - # start_interval: 2s environment: <<: *api-environment DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" - REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT}" + REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000/health"] + interval: 10s + timeout: 60s + retries: 5 + ports: + - ${API_PORT}:3000 + labels: + - "traefik.enable=true" + - "traefik.http.routers.api.entrypoints=websecure" + - "traefik.http.routers.api.rule=Host(`localhost`)" + - "traefik.http.services.api.loadbalancer.server.port=3000" volumes: - lago_storage_data:/app/storage - # If using GCS, you need to put the credentials keyfile here - # - gcs_keyfile.json:/app/gcs_keyfile.json - ports: - - ${API_PORT}:3000 - front: container_name: lago-front @@ -121,15 +113,54 @@ services: condition: service_healthy environment: <<: *front-environment - - ports: - - ${FRONT_PORT}:80 healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:${FRONT_PORT}"] + test: ["CMD", "curl", "-f", "http://localhost:${FRONT_PORT}"] interval: 30s timeout: 10s retries: 3 - start_period: 10s + labels: + - "traefik.enable=true" + - "traefik.http.routers.front.entrypoints=websecure" + - "traefik.http.routers.front.rule=Host(`localhost`)" + - "traefik.http.services.front.loadbalancer.server.port=80" + volumes: + - lago_storage_data:/app/storage + ports: + - ${FRONT_PORT:-8080}:80 + db: + image: postgres:14-alpine + restart: unless-stopped + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + PGDATA: ${PGDATA} + PGPORT: ${POSTGRES_PORT} + POSTGRES_SCHEMA: ${POSTGRES_SCHEMA} + volumes: + - lago_postgres_data:/data/postgres + ports: + - ${POSTGRES_PORT}:${POSTGRES_PORT} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis:6-alpine + container_name: lago-redis + restart: unless-stopped + command: --port ${REDIS_PORT:-6379} + volumes: + - lago_redis_data:/data + ports: + - ${REDIS_PORT:-6379}:${REDIS_PORT:-6379} + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 api-worker: container_name: lago-worker @@ -139,15 +170,13 @@ services: api: condition: service_healthy command: ['./scripts/start.worker.sh'] - healthcheck: - test: ['CMD-SHELL', 'bundle exec sidekiqmon | grep $(hostname) || exit 1'] environment: <<: *common-environment LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT}" DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" - REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT}" - # SIDEKIQ_EVENTS: ${SIDEKIQ_EVENTS} - # SIDEKIQ_PDFS: ${SIDEKIQ_PDFS} + REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" + healthcheck: + test: ['CMD-SHELL', 'bundle exec sidekiqmon | grep $(hostname) || exit 1'] volumes: - lago_storage_data:/app/storage @@ -163,7 +192,7 @@ services: <<: *common-environment LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT}" DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" - REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT}" + REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" pdf: image: getlago/lago-gotenberg:7.8.2 @@ -179,41 +208,4 @@ services: command: ['./scripts/start.migrate.sh'] volumes: - lago_storage_data:/app/storage - environment: - RAILS_ENV: ${RAILS_ENV} - SECRET_KEY_BASE: ${SECRET_KEY_BASE} - LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" - REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT}" - REDIS_PASSWORD: ${REDIS_PASSWORD} - - - - - - # You can uncomment this if you want to use a dedicated Sidekiq worker for the event ingestion. - # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. - # api-events-worker: - # container_name: lago-events-worker - # image: getlago/api:v1.12.2 - # restart: unless-stopped - # depends_on: - # api: - # condition: service_healthy - # command: ["./scripts/start.events.worker.sh"] - # environment: - # <<: *api-environment - - - # You can uncomment this if you want to use a dedicated Sidekiq worker for the invoices pdf creation. - # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs. - # api-pdfs-worker: - # container_name: lago-pdfs-worker - # image: getlago/api:v1.12.2 - # restart: unless-stopped - # depends_on: - # api: - # condition: service_healthy - # command: ["./scripts/start.pdfs.worker.sh"] - # environment: - # <<: *api-environment \ No newline at end of file + From 7be44df4cf37675ad7189aac4e4655d4141357cc Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Mon, 7 Oct 2024 10:48:59 +0200 Subject: [PATCH 06/27] chore(docker-compose): update Traefik config for Let's Encrypt and domain templating - Enable Let's Encrypt support with ACME resolver 'myresolver' - Update Traefik rules to support templated DOMAIN variable - Remove unnecessary port mappings from API and frontend services - Secure Traefik dashboard and disable 'exposedbydefault' for improved security --- docker-compose.yml | 41 ++++++++++++++++++++--------------------- env | 6 ++++-- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index a5d1bfe25..4f2b49669 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -54,26 +54,27 @@ services: container_name: traefik restart: unless-stopped command: - - "--api.insecure=true" + - "--api.insecure=false" + - "--api.dashboard=true" - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - - "--certificatesresolvers.selfsigned.acme.tlschallenge=true" - - "--certificatesresolvers.selfsigned.acme.email=your-email@example.com" - - "--certificatesresolvers.selfsigned.acme.storage=/letsencrypt/acme.json" + - "--certificatesresolvers.myresolver.acme.tlschallenge=true" + - "--certificatesresolvers.myresolver.acme.email=your_email@domain.tld" + - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" ports: - "80:80" - - "8443:443" + - "443:443" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" - traefik_certificates:/letsencrypt - traefik_config:/traefik - labels: - - "traefik.http.routers.api.entrypoints=websecure" - - "traefik.http.routers.api.rule=Host(`localhost`)" - - "traefik.http.services.api.loadbalancer.server.port=3000" + - "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)" + - "traefik.http.routers.traefik.entrypoints=websecure" + - "traefik.http.routers.traefik.tls.certresolver=myresolver" + - "traefik.http.services.traefik.loadbalancer.server.port=8080" api: container_name: lago-api @@ -94,12 +95,11 @@ services: interval: 10s timeout: 60s retries: 5 - ports: - - ${API_PORT}:3000 labels: - "traefik.enable=true" - "traefik.http.routers.api.entrypoints=websecure" - - "traefik.http.routers.api.rule=Host(`localhost`)" + - "traefik.http.routers.api.rule=Host(`api.${DOMAIN}`)" + - "traefik.http.routers.api.tls.certresolver=myresolver" - "traefik.http.services.api.loadbalancer.server.port=3000" volumes: - lago_storage_data:/app/storage @@ -114,19 +114,19 @@ services: environment: <<: *front-environment healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:${FRONT_PORT}"] + test: ["CMD", "curl", "-f", "http://localhost:80"] interval: 30s timeout: 10s retries: 3 labels: - "traefik.enable=true" - "traefik.http.routers.front.entrypoints=websecure" - - "traefik.http.routers.front.rule=Host(`localhost`)" + - "traefik.http.routers.front.rule=Host(`app.${DOMAIN}`)" + - "traefik.http.routers.front.tls.certresolver=myresolver" - "traefik.http.services.front.loadbalancer.server.port=80" volumes: - lago_storage_data:/app/storage - ports: - - ${FRONT_PORT:-8080}:80 + db: image: postgres:14-alpine restart: unless-stopped @@ -140,7 +140,7 @@ services: volumes: - lago_postgres_data:/data/postgres ports: - - ${POSTGRES_PORT}:${POSTGRES_PORT} + - "${POSTGRES_PORT}:${POSTGRES_PORT}" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 10s @@ -155,7 +155,7 @@ services: volumes: - lago_redis_data:/data ports: - - ${REDIS_PORT:-6379}:${REDIS_PORT:-6379} + - "${REDIS_PORT:-6379}:${REDIS_PORT:-6379}" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s @@ -207,5 +207,4 @@ services: condition: service_healthy command: ['./scripts/start.migrate.sh'] volumes: - - lago_storage_data:/app/storage - + - lago_storage_data:/app/storage \ No newline at end of file diff --git a/env b/env index cf81b77b0..5a412cb7b 100644 --- a/env +++ b/env @@ -19,12 +19,14 @@ REDIS_PASSWORD= API_PORT=3000 FRONT_PORT=80 + # Lago API Configuration -LAGO_API_URL=http://localhost:3000 +DOMAIN=yourdomain.told +LAGO_API_URL=https://api.yourdomain.tld +LAGO_FRONT_URL=https://app.yourdomain.tld SECRET_KEY_BASE=your-secret-key-base-hex-64 RAILS_ENV=production LAGO_RAILS_STDOUT=true -LAGO_FRONT_URL=http://localhost LAGO_PDF_URL=http://pdf:3000 LAGO_DISABLE_SIGNUP=false APP_ENV=production From a72c8d269ab1acdbbcef7843cc19ae7d116c5f1b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Mon, 7 Oct 2024 14:55:12 +0200 Subject: [PATCH 07/27] feat(docker-compose): configure Traefik to route API and frontend under a single domain - Update Traefik rules to use a single domain with path prefixes - Add middleware to strip '/api' prefix for the API service - Set router priorities to resolve routing conflicts --- docker-compose-old.yml | 309 +++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 18 ++- 2 files changed, 320 insertions(+), 7 deletions(-) create mode 100644 docker-compose-old.yml diff --git a/docker-compose-old.yml b/docker-compose-old.yml new file mode 100644 index 000000000..5d48fe23f --- /dev/null +++ b/docker-compose-old.yml @@ -0,0 +1,309 @@ +volumes: + lago_postgres_data: + lago_redis_data: + lago_storage_data: + +services: + db: + image: postgres:14-alpine + container_name: lago-db + restart: unless-stopped + environment: + POSTGRES_DB: ${POSTGRES_DB:-lago} + POSTGRES_USER: ${POSTGRES_USER:-lago} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme} + PGDATA: /data/postgres + PGPORT: ${POSTGRES_PORT:-5432} + POSTGRES_SCHEMA: public + volumes: + - lago_postgres_data:/data/postgres + ports: + - ${POSTGRES_PORT:-5432}:${POSTGRES_PORT:-5432} + + redis: + image: redis:6-alpine + container_name: lago-redis + restart: unless-stopped + command: --port ${REDIS_PORT:-6379} + volumes: + - lago_redis_data:/data + ports: + - ${REDIS_PORT:-6379}:${REDIS_PORT:-6379} + + api: + container_name: lago-api + image: getlago/api:v1.12.2 + restart: unless-stopped + depends_on: + - db + - redis + command: ['./scripts/start.sh'] + healthcheck: + test: curl -f http://localhost:3000/health || exit 1 + interval: 10s + start_period: 30s + timeout: 60s + # uncomment for a potentially faster startup if you have docker --version > 25.0.0 + # start_interval: 2s + environment: + - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} + - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} + - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + - REDIS_PASSWORD=${REDIS_PASSWORD} + - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} + - RAILS_ENV=production + - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} + - SENTRY_DSN=${SENTRY_DSN} + - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} + - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + - LAGO_SIDEKIQ_WEB=${LAGO_SIDEKIQ_WEB} + - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} + - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} + - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} + - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} + - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} + - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} + - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} + - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} + - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} + - LAGO_USE_GCS=${LAGO_USE_GCS:-false} + - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} + - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} + - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} + - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} + - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} + - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} + - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} + - LAGO_OAUTH_PROXY_URL=https://proxy.getlago.com + - LAGO_LICENSE=${LAGO_LICENSE:-} + - GOOGLE_AUTH_CLIENT_ID=${GOOGLE_AUTH_CLIENT_ID:-} + - GOOGLE_AUTH_CLIENT_SECRET=${GOOGLE_AUTH_CLIENT_SECRET:-} + - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} + # - SIDEKIQ_EVENTS=true + # - SIDEKIQ_PDFS=true + volumes: + - lago_storage_data:/app/storage + # If using GCS, you need to put the credentials keyfile here + #- gcs_keyfile.json:/app/gcs_keyfile.json + ports: + - ${API_PORT:-3000}:3000 + + front: + container_name: lago-front + image: getlago/front:v1.12.2 + restart: unless-stopped + # Use this command if you want to use SSL with Let's Encrypt + # command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" + depends_on: + api: + condition: service_healthy + environment: + - API_URL=${LAGO_API_URL:-http://localhost:3000} + - APP_ENV=${APP_ENV:-production} + - LAGO_DISABLE_SIGNUP=${LAGO_DISABLE_SIGNUP:-false} + - LAGO_OAUTH_PROXY_URL=https://proxy.getlago.com + - SENTRY_DSN=${SENTRY_DSN_FRONT} + - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} + ports: + - ${FRONT_PORT:-80}:80 + # - 443:443 + # Using SSL with Let's Encrypt + # volumes: + # - ./extra/nginx-letsencrypt.conf:/etc/nginx/conf.d/default.conf + # - ./extra/certbot/conf:/etc/letsencrypt + # - ./extra/certbot/www:/var/www/certbot + # Using SSL with self signed certificates + # volumes: + # - ./extra/nginx-selfsigned.conf:/etc/nginx/conf.d/default.conf + # - ./extra/ssl/nginx-selfsigned.crt:/etc/ssl/certs/nginx-selfsigned.crt + # - ./extra/ssl/nginx-selfsigned.key:/etc/ssl/private/nginx-selfsigned.key + # - ./extra/ssl/dhparam.pem:/etc/ssl/certs/dhparam.pem + + # Only used for SSL support with Let's Encrypt + # certbot: + # image: certbot/certbot + # entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" + # volumes: + # - ./extra/certbot/conf:/etc/letsencrypt + # - ./extra/certbot/www:/var/www/certbot + + api-worker: + container_name: lago-worker + image: getlago/api:v1.12.2 + restart: unless-stopped + depends_on: + api: + condition: service_healthy + command: ['./scripts/start.worker.sh'] + healthcheck: + test: ['CMD-SHELL', 'bundle exec sidekiqmon | grep $(hostname) || exit 1'] + environment: + - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} + - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} + - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + - REDIS_PASSWORD=${REDIS_PASSWORD} + - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} + - RAILS_ENV=production + - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} + - SENTRY_DSN=${SENTRY_DSN} + - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} + - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} + - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} + - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} + - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} + - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} + - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} + - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} + - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} + - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} + - LAGO_USE_GCS=${LAGO_USE_GCS:-false} + - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} + - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} + - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} + - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} + - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} + - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} + - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} + - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} + - LAGO_LICENSE=${LAGO_LICENSE:-} + # - SIDEKIQ_EVENTS=true + # - SIDEKIQ_PDFS=true + volumes: + - lago_storage_data:/app/storage + + # You can uncomment this if you want to use a dedicated Sidekiq worker for the event ingestion. + # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. + #api-events-worker: + # container_name: lago-events-worker + # image: getlago/api:v1.12.2 + # restart: unless-stopped + # depends_on: + # api: + # condition: service_healthy + # command: ["./scripts/start.events.worker.sh"] + # environment: + # - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} + # - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} + # - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + # - REDIS_PASSWORD=${REDIS_PASSWORD} + # - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} + # - RAILS_ENV=production + # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} + # - SENTRY_DSN=${SENTRY_DSN} + # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + # - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} + # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} + # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} + # - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} + # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} + # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} + # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} + # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} + # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} + # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} + # - LAGO_USE_GCS=${LAGO_USE_GCS:-false} + # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} + # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} + # - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} + # - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} + # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} + # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} + # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} + # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} + # - SIDEKIQ_EVENTS=true + # - LAGO_LICENSE=${LAGO_LICENSE:-} + + # You can uncomment this if you want to use a dedicated Sidekiq worker for the invoices pdf creation. + # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs. + #api-pdfs-worker: + # container_name: lago-pdfs-worker + # image: getlago/api:v1.12.2 + # restart: unless-stopped + # depends_on: + # api: + # condition: service_healthy + # command: ["./scripts/start.pdfs.worker.sh"] + # environment: + # - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} + # - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} + # - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + # - REDIS_PASSWORD=${REDIS_PASSWORD} + # - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} + # - RAILS_ENV=production + # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} + # - SENTRY_DSN=${SENTRY_DSN} + # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + # - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} + # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} + # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} + # - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} + # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} + # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} + # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} + # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} + # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} + # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} + # - LAGO_USE_GCS=${LAGO_USE_GCS:-false} + # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} + # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} + # - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} + # - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} + # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} + # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} + # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} + # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} + # - SIDEKIQ_PDFS=true + # - LAGO_LICENSE=${LAGO_LICENSE:-} + + api-clock: + container_name: lago-clock + image: getlago/api:v1.12.2 + restart: unless-stopped + depends_on: + api: + condition: service_healthy + command: ['./scripts/start.clock.sh'] + environment: + - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} + - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} + - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + - REDIS_PASSWORD=${REDIS_PASSWORD} + - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} + - RAILS_ENV=production + - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} + - SENTRY_DSN=${SENTRY_DSN} + - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} + - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} + - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} + - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} + - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} + - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} + - LAGO_LICENSE=${LAGO_LICENSE:-} + + pdf: + image: getlago/lago-gotenberg:7.8.2 + + migrate: + container_name: lago-migrate + image: getlago/api:v1.12.2 + depends_on: + - db + - redis + command: ['./scripts/start.migrate.sh'] + volumes: + - lago_storage_data:/app/storage + environment: + - RAILS_ENV=production + - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} + - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} + - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + - REDIS_PASSWORD=${REDIS_PASSWORD} diff --git a/docker-compose.yml b/docker-compose.yml index 4f2b49669..65987b697 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -61,7 +61,7 @@ services: - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.myresolver.acme.tlschallenge=true" - - "--certificatesresolvers.myresolver.acme.email=your_email@domain.tld" + - "--certificatesresolvers.myresolver.acme.email=youremail@domain.tld" - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" ports: - "80:80" @@ -96,11 +96,14 @@ services: timeout: 60s retries: 5 labels: - - "traefik.enable=true" - - "traefik.http.routers.api.entrypoints=websecure" - - "traefik.http.routers.api.rule=Host(`api.${DOMAIN}`)" - - "traefik.http.routers.api.tls.certresolver=myresolver" - - "traefik.http.services.api.loadbalancer.server.port=3000" + - "traefik.enable=true" + - "traefik.http.routers.api.entrypoints=websecure" + - "traefik.http.routers.api.rule=Host(`${DOMAIN}`) && PathPrefix(`/api`)" + - "traefik.http.routers.api.tls.certresolver=myresolver" + - "traefik.http.routers.api.priority=100" + - "traefik.http.services.api.loadbalancer.server.port=3000" + - "traefik.http.middlewares.api-strip-prefix.stripprefix.prefixes=/api" + - "traefik.http.routers.api.middlewares=api-strip-prefix" volumes: - lago_storage_data:/app/storage @@ -119,9 +122,10 @@ services: timeout: 10s retries: 3 labels: + - "traefik.http.routers.front.priority=50" - "traefik.enable=true" - "traefik.http.routers.front.entrypoints=websecure" - - "traefik.http.routers.front.rule=Host(`app.${DOMAIN}`)" + - "traefik.http.routers.front.rule=Host(`${DOMAIN}`) && PathPrefix(`/`)" - "traefik.http.routers.front.tls.certresolver=myresolver" - "traefik.http.services.front.loadbalancer.server.port=80" volumes: From 7cbfdd8d94ac7228077692bc65234047314c5397 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Mon, 7 Oct 2024 14:57:46 +0200 Subject: [PATCH 08/27] refactor(docker-compose): re-adding old api worker --- docker-compose.yml | 61 +++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 62dc17950..31f54c556 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -183,6 +183,36 @@ services: test: ['CMD-SHELL', 'bundle exec sidekiqmon | grep $(hostname) || exit 1'] volumes: - lago_storage_data:/app/storage + + + api-clock: + container_name: lago-clock + image: getlago/api:v1.12.3 + restart: unless-stopped + depends_on: + api: + condition: service_healthy + command: ['./scripts/start.clock.sh'] + environment: + <<: *common-environment + LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT}" + DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" + REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" + + pdf: + image: getlago/lago-gotenberg:7.8.2 + + migrate: + container_name: lago-migrate + image: getlago/api:v1.12.3 + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + command: ['./scripts/start.migrate.sh'] + volumes: + - lago_storage_data:/app/storage # You can uncomment this if you want to use a dedicated Sidekiq worker for the event ingestion. # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. @@ -268,33 +298,4 @@ services: # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} # - SIDEKIQ_PDFS=true - # - LAGO_LICENSE=${LAGO_LICENSE:-} - - api-clock: - container_name: lago-clock - image: getlago/api:v1.12.3 - restart: unless-stopped - depends_on: - api: - condition: service_healthy - command: ['./scripts/start.clock.sh'] - environment: - <<: *common-environment - LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT}" - DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" - REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" - - pdf: - image: getlago/lago-gotenberg:7.8.2 - - migrate: - container_name: lago-migrate - image: getlago/api:v1.12.3 - depends_on: - db: - condition: service_healthy - redis: - condition: service_healthy - command: ['./scripts/start.migrate.sh'] - volumes: - - lago_storage_data:/app/storage \ No newline at end of file + # - LAGO_LICENSE=${LAGO_LICENSE:-} \ No newline at end of file From d661cd82f898bc48ece77c580cf8cf4fdb4945da Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Tue, 15 Oct 2024 15:06:38 +0200 Subject: [PATCH 09/27] refactor(docker-compose): update docker images --- docker-compose.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 31f54c556..9c13869e9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -78,7 +78,7 @@ services: api: container_name: lago-api - image: getlago/api:v1.12.3 + image: getlago/api:v1.13.1 restart: unless-stopped depends_on: db: @@ -109,7 +109,7 @@ services: front: container_name: lago-front - image: getlago/front:v1.12.3 + image: getlago/front:v1.13.1 restart: unless-stopped depends_on: api: @@ -168,7 +168,7 @@ services: api-worker: container_name: lago-worker - image: getlago/api:v1.12.3 + image: getlago/api:v1.13.1 restart: unless-stopped depends_on: api: @@ -187,7 +187,7 @@ services: api-clock: container_name: lago-clock - image: getlago/api:v1.12.3 + image: getlago/api:v1.13.1 restart: unless-stopped depends_on: api: @@ -204,7 +204,7 @@ services: migrate: container_name: lago-migrate - image: getlago/api:v1.12.3 + image: getlago/api:v1.13.1 depends_on: db: condition: service_healthy @@ -218,7 +218,7 @@ services: # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. #api-events-worker: # container_name: lago-events-worker - # image: getlago/api:v1.12.3 + # image: getlago/api:v1.13.1 # restart: unless-stopped # depends_on: # api: @@ -261,7 +261,7 @@ services: # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs. #api-pdfs-worker: # container_name: lago-pdfs-worker - # image: getlago/api:v1.12.3 + # image: getlago/api:v1.13.1 # restart: unless-stopped # depends_on: # api: From f279fb579bc0d978b37ff879cf80a430d98fec26 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Tue, 15 Oct 2024 15:07:40 +0200 Subject: [PATCH 10/27] refactor(docker-compose): update docker images --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index c39363811..9c13869e9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -298,4 +298,4 @@ services: # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} # - SIDEKIQ_PDFS=true - # - LAGO_LICENSE=${LAGO_LICENSE:-} + # - LAGO_LICENSE=${LAGO_LICENSE:-} \ No newline at end of file From af95c18d6328ae7128e9d53a7769d7481561ba75 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Thu, 17 Oct 2024 11:49:15 +0200 Subject: [PATCH 11/27] feat(docker-compose): adding lago version inside a variable inside .env --- docker-compose-old.yml => docker-compose.old.yml | 0 docker-compose.yml | 14 +++++++------- env | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) rename docker-compose-old.yml => docker-compose.old.yml (100%) diff --git a/docker-compose-old.yml b/docker-compose.old.yml similarity index 100% rename from docker-compose-old.yml rename to docker-compose.old.yml diff --git a/docker-compose.yml b/docker-compose.yml index 9c13869e9..9a2ed83a3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -78,7 +78,7 @@ services: api: container_name: lago-api - image: getlago/api:v1.13.1 + image: getlago/api:${LAGO_VERSION} restart: unless-stopped depends_on: db: @@ -109,7 +109,7 @@ services: front: container_name: lago-front - image: getlago/front:v1.13.1 + image: getlago/front:${LAGO_VERSION} restart: unless-stopped depends_on: api: @@ -168,7 +168,7 @@ services: api-worker: container_name: lago-worker - image: getlago/api:v1.13.1 + image: getlago/api:${LAGO_VERSION} restart: unless-stopped depends_on: api: @@ -187,7 +187,7 @@ services: api-clock: container_name: lago-clock - image: getlago/api:v1.13.1 + image: getlago/api:${LAGO_VERSION} restart: unless-stopped depends_on: api: @@ -204,7 +204,7 @@ services: migrate: container_name: lago-migrate - image: getlago/api:v1.13.1 + image: getlago/api:${LAGO_VERSION} depends_on: db: condition: service_healthy @@ -218,7 +218,7 @@ services: # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. #api-events-worker: # container_name: lago-events-worker - # image: getlago/api:v1.13.1 + # image: getlago/api:${LAGO_VERSION} # restart: unless-stopped # depends_on: # api: @@ -261,7 +261,7 @@ services: # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs. #api-pdfs-worker: # container_name: lago-pdfs-worker - # image: getlago/api:v1.13.1 + # image: getlago/api:${LAGO_VERSION} # restart: unless-stopped # depends_on: # api: diff --git a/env b/env index 5a412cb7b..5caae1ba6 100644 --- a/env +++ b/env @@ -1,5 +1,6 @@ #See more informations here : https://doc.getlago.com/guide/self-hosted/docker +LAGO_VERSION=v1.13.1 # PostgreSQL Configuration POSTGRES_DB=lago From 8089195c9e700efc831d96788dee45a87782ce6e Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Tue, 22 Oct 2024 15:01:43 +0200 Subject: [PATCH 12/27] feat(docker-compose): Moving the new docker compose to docker-compose.new.yaml to let user time to migrate --- .env.example | 75 ++++++++++ docker-compose.new.yml | 301 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 376 insertions(+) create mode 100644 .env.example create mode 100644 docker-compose.new.yml diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..5caae1ba6 --- /dev/null +++ b/.env.example @@ -0,0 +1,75 @@ +#See more informations here : https://doc.getlago.com/guide/self-hosted/docker + +LAGO_VERSION=v1.13.1 + +# PostgreSQL Configuration +POSTGRES_DB=lago +POSTGRES_USER=lago +POSTGRES_PASSWORD=changeme +POSTGRES_HOST=db +POSTGRES_PORT=5432 +POSTGRES_SCHEMA=public +PGDATA=/data/postgres + +# Redis Configuration +REDIS_HOST=redis +REDIS_PORT=6379 +REDIS_PASSWORD= + +# Application Ports +API_PORT=3000 +FRONT_PORT=80 + + +# Lago API Configuration +DOMAIN=yourdomain.told +LAGO_API_URL=https://api.yourdomain.tld +LAGO_FRONT_URL=https://app.yourdomain.tld +SECRET_KEY_BASE=your-secret-key-base-hex-64 +RAILS_ENV=production +LAGO_RAILS_STDOUT=true +LAGO_PDF_URL=http://pdf:3000 +LAGO_DISABLE_SIGNUP=false +APP_ENV=production + +# Encryption Keys +LAGO_RSA_PRIVATE_KEY= +LAGO_ENCRYPTION_PRIMARY_KEY=your-encryption-primary-key +LAGO_ENCRYPTION_DETERMINISTIC_KEY=your-encryption-deterministic-key +LAGO_ENCRYPTION_KEY_DERIVATION_SALT=your-encryption-derivation-salt + +# AWS S3 Configuration +LAGO_USE_AWS_S3=false +LAGO_AWS_S3_ACCESS_KEY_ID=azerty123456 +LAGO_AWS_S3_SECRET_ACCESS_KEY=azerty123456 +LAGO_AWS_S3_REGION=us-east-1 +LAGO_AWS_S3_BUCKET=bucket +LAGO_AWS_S3_ENDPOINT= + +# Google Cloud Storage Configuration +LAGO_USE_GCS=false +LAGO_GCS_PROJECT= +LAGO_GCS_BUCKET= + +# Redis Cache Configuration +LAGO_REDIS_CACHE_HOST=redis +LAGO_REDIS_CACHE_PORT=6379 +LAGO_REDIS_CACHE_PASSWORD= + +# Sentry Configuration +SENTRY_DSN= +SENTRY_DSN_FRONT= + +# Lago Feature Flags +LAGO_DISABLE_SEGMENT= +LAGO_DISABLE_WALLET_REFRESH= +LAGO_SIDEKIQ_WEB= +SIDEKIQ_EVENTS= +SIDEKIQ_PDFS= + +# OAuth and Authentication +LAGO_OAUTH_PROXY_URL=https://proxy.getlago.com +GOOGLE_AUTH_CLIENT_ID= +GOOGLE_AUTH_CLIENT_SECRET= +NANGO_SECRET_KEY= +LAGO_LICENSE= diff --git a/docker-compose.new.yml b/docker-compose.new.yml new file mode 100644 index 000000000..bb75ae3b2 --- /dev/null +++ b/docker-compose.new.yml @@ -0,0 +1,301 @@ +volumes: + lago_postgres_data: + lago_redis_data: + lago_storage_data: + traefik_certificates: + traefik_config: + +x-common-environment: &common-environment + LAGO_API_URL: ${LAGO_API_URL} + REDIS_PASSWORD: ${REDIS_PASSWORD} + SECRET_KEY_BASE: ${SECRET_KEY_BASE} + RAILS_ENV: ${RAILS_ENV} + RAILS_LOG_TO_STDOUT: ${LAGO_RAILS_STDOUT} + SENTRY_DSN: ${SENTRY_DSN} + LAGO_FRONT_URL: ${LAGO_FRONT_URL} + LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} + LAGO_ENCRYPTION_PRIMARY_KEY: ${LAGO_ENCRYPTION_PRIMARY_KEY} + LAGO_ENCRYPTION_DETERMINISTIC_KEY: ${LAGO_ENCRYPTION_DETERMINISTIC_KEY} + LAGO_ENCRYPTION_KEY_DERIVATION_SALT: ${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} + LAGO_USE_AWS_S3: ${LAGO_USE_AWS_S3} + LAGO_AWS_S3_ACCESS_KEY_ID: ${LAGO_AWS_S3_ACCESS_KEY_ID} + LAGO_AWS_S3_SECRET_ACCESS_KEY: ${LAGO_AWS_S3_SECRET_ACCESS_KEY} + LAGO_AWS_S3_REGION: ${LAGO_AWS_S3_REGION} + LAGO_AWS_S3_BUCKET: ${LAGO_AWS_S3_BUCKET} + LAGO_AWS_S3_ENDPOINT: ${LAGO_AWS_S3_ENDPOINT} + LAGO_USE_GCS: ${LAGO_USE_GCS} + LAGO_GCS_PROJECT: ${LAGO_GCS_PROJECT} + LAGO_GCS_BUCKET: ${LAGO_GCS_BUCKET} + LAGO_PDF_URL: ${LAGO_PDF_URL} + LAGO_REDIS_CACHE_PASSWORD: ${LAGO_REDIS_CACHE_PASSWORD} + LAGO_DISABLE_SEGMENT: ${LAGO_DISABLE_SEGMENT} + LAGO_DISABLE_WALLET_REFRESH: ${LAGO_DISABLE_WALLET_REFRESH} + NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} + LAGO_LICENSE: ${LAGO_LICENSE} + +x-api-environment: &api-environment + <<: *common-environment + LAGO_SIDEKIQ_WEB: ${LAGO_SIDEKIQ_WEB} + LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} + GOOGLE_AUTH_CLIENT_ID: ${GOOGLE_AUTH_CLIENT_ID} + GOOGLE_AUTH_CLIENT_SECRET: ${GOOGLE_AUTH_CLIENT_SECRET} + +x-front-environment: &front-environment + API_URL: ${LAGO_API_URL} + APP_ENV: ${APP_ENV} + LAGO_DISABLE_SIGNUP: ${LAGO_DISABLE_SIGNUP} + LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} + SENTRY_DSN: ${SENTRY_DSN_FRONT} + NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} + +services: + traefik: + image: traefik:v2.5 + container_name: traefik + restart: unless-stopped + command: + - "--api.insecure=false" + - "--api.dashboard=true" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--entrypoints.web.address=:80" + - "--entrypoints.websecure.address=:443" + - "--certificatesresolvers.lagoresolver.acme.tlschallenge=true" + - "--certificatesresolvers.lagoresolver.acme.email=youremail@domain.tld" + - "--certificatesresolvers.lagoresolver.acme.storage=/letsencrypt/acme.json" + ports: + - "80:80" + - "443:443" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - traefik_certificates:/letsencrypt + - traefik_config:/traefik + labels: + - "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)" + - "traefik.http.routers.traefik.entrypoints=websecure" + - "traefik.http.routers.traefik.tls.certresolver=lagoresolver" + - "traefik.http.services.traefik.loadbalancer.server.port=8080" + + api: + container_name: lago-api + image: getlago/api:${LAGO_VERSION} + restart: unless-stopped + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + command: ['./scripts/start.sh'] + environment: + <<: *api-environment + DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" + REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000/health"] + interval: 10s + timeout: 60s + retries: 5 + labels: + - "traefik.enable=true" + - "traefik.http.routers.api.entrypoints=websecure" + - "traefik.http.routers.api.rule=Host(`${DOMAIN}`) && PathPrefix(`/api`)" + - "traefik.http.routers.api.tls.certresolver=lagoresolver" + - "traefik.http.routers.api.priority=100" + - "traefik.http.services.api.loadbalancer.server.port=3000" + - "traefik.http.middlewares.api-strip-prefix.stripprefix.prefixes=/api" + - "traefik.http.routers.api.middlewares=api-strip-prefix" + volumes: + - lago_storage_data:/app/storage + + front: + container_name: lago-front + image: getlago/front:${LAGO_VERSION} + restart: unless-stopped + depends_on: + api: + condition: service_healthy + environment: + <<: *front-environment + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:80"] + interval: 30s + timeout: 10s + retries: 3 + labels: + - "traefik.http.routers.front.priority=50" + - "traefik.enable=true" + - "traefik.http.routers.front.entrypoints=websecure" + - "traefik.http.routers.front.rule=Host(`${DOMAIN}`) && PathPrefix(`/`)" + - "traefik.http.routers.front.tls.certresolver=lagoresolver" + - "traefik.http.services.front.loadbalancer.server.port=80" + volumes: + - lago_storage_data:/app/storage + + db: + image: postgres:14-alpine + restart: unless-stopped + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + PGDATA: ${PGDATA} + PGPORT: ${POSTGRES_PORT} + POSTGRES_SCHEMA: ${POSTGRES_SCHEMA} + volumes: + - lago_postgres_data:/data/postgres + ports: + - "${POSTGRES_PORT}:${POSTGRES_PORT}" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis:6-alpine + container_name: lago-redis + restart: unless-stopped + command: --port ${REDIS_PORT:-6379} + volumes: + - lago_redis_data:/data + ports: + - "${REDIS_PORT:-6379}:${REDIS_PORT:-6379}" + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + + api-worker: + container_name: lago-worker + image: getlago/api:${LAGO_VERSION} + restart: unless-stopped + depends_on: + api: + condition: service_healthy + command: ['./scripts/start.worker.sh'] + environment: + <<: *common-environment + LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT}" + DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" + REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" + healthcheck: + test: ['CMD-SHELL', 'bundle exec sidekiqmon | grep $(hostname) || exit 1'] + volumes: + - lago_storage_data:/app/storage + + + api-clock: + container_name: lago-clock + image: getlago/api:${LAGO_VERSION} + restart: unless-stopped + depends_on: + api: + condition: service_healthy + command: ['./scripts/start.clock.sh'] + environment: + <<: *common-environment + LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT}" + DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" + REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" + + pdf: + image: getlago/lago-gotenberg:7.8.2 + + migrate: + container_name: lago-migrate + image: getlago/api:${LAGO_VERSION} + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + command: ['./scripts/start.migrate.sh'] + volumes: + - lago_storage_data:/app/storage + + # You can uncomment this if you want to use a dedicated Sidekiq worker for the event ingestion. + # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. + #api-events-worker: + # container_name: lago-events-worker + # image: getlago/api:${LAGO_VERSION} + # restart: unless-stopped + # depends_on: + # api: + # condition: service_healthy + # command: ["./scripts/start.events.worker.sh"] + # environment: + # - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} + # - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} + # - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + # - REDIS_PASSWORD=${REDIS_PASSWORD} + # - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} + # - RAILS_ENV=production + # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} + # - SENTRY_DSN=${SENTRY_DSN} + # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + # - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} + # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} + # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} + # - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} + # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} + # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} + # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} + # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} + # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} + # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} + # - LAGO_USE_GCS=${LAGO_USE_GCS:-false} + # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} + # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} + # - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} + # - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} + # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} + # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} + # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} + # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} + # - SIDEKIQ_EVENTS=true + # - LAGO_LICENSE=${LAGO_LICENSE:-} + + # You can uncomment this if you want to use a dedicated Sidekiq worker for the invoices pdf creation. + # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs. + #api-pdfs-worker: + # container_name: lago-pdfs-worker + # image: getlago/api:${LAGO_VERSION} + # restart: unless-stopped + # depends_on: + # api: + # condition: service_healthy + # command: ["./scripts/start.pdfs.worker.sh"] + # environment: + # - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} + # - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} + # - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + # - REDIS_PASSWORD=${REDIS_PASSWORD} + # - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} + # - RAILS_ENV=production + # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} + # - SENTRY_DSN=${SENTRY_DSN} + # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + # - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded + # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} + # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} + # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} + # - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} + # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} + # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} + # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} + # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} + # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} + # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} + # - LAGO_USE_GCS=${LAGO_USE_GCS:-false} + # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} + # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} + # - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} + # - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} + # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} + # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} + # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} + # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} + # - SIDEKIQ_PDFS=true + # - LAGO_LICENSE=${LAGO_LICENSE:-} \ No newline at end of file From 9bb07d5b371826ba254c0859e468a316d876ba6b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Tue, 22 Oct 2024 15:07:38 +0200 Subject: [PATCH 13/27] chore(docker-compose) adding jeremy review and adding a warning inside docker-compose.old.yml --- .env.example | 4 +- docker-compose.old.yml | 30 ++++ docker-compose.yml | 301 ----------------------------------------- env | 75 ---------- 4 files changed, 32 insertions(+), 378 deletions(-) delete mode 100644 docker-compose.yml delete mode 100644 env diff --git a/.env.example b/.env.example index 5caae1ba6..15410519a 100644 --- a/.env.example +++ b/.env.example @@ -23,8 +23,8 @@ FRONT_PORT=80 # Lago API Configuration DOMAIN=yourdomain.told -LAGO_API_URL=https://api.yourdomain.tld -LAGO_FRONT_URL=https://app.yourdomain.tld +LAGO_API_URL=https://yourdomain.tld/api +LAGO_FRONT_URL=https://yourdomain.tld SECRET_KEY_BASE=your-secret-key-base-hex-64 RAILS_ENV=production LAGO_RAILS_STDOUT=true diff --git a/docker-compose.old.yml b/docker-compose.old.yml index 5d48fe23f..2f5902f82 100644 --- a/docker-compose.old.yml +++ b/docker-compose.old.yml @@ -1,3 +1,33 @@ +############################################## +# # +# !!! WARNING !!! # +# # +# This file 'docker-compose.old.yaml' # +# is DEPRECATED and has been replaced by # +# the new 'docker-compose.yml'. # +# # +# Please migrate to the new version by # +# following the steps below: # +# # +# 1. Perform a backup of the current # +# volumes. This step is mandatory! # +# # +# 2. Most variables will be set in the # +# '.env' file (see '.env.example' # +# for more information). # +# # +# 3. Change the 'apiUrl' variable, which # +# no longer uses 'api.', but now ends # +# with '/api' after the domain name. # +# # +# 4. SSL certificate management is now # +# automatic. There's nothing more to # +# do on this subject unless you are # +# using 'localhost'. # +# # +############################################## + + volumes: lago_postgres_data: lago_redis_data: diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 9a2ed83a3..000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,301 +0,0 @@ -volumes: - lago_postgres_data: - lago_redis_data: - lago_storage_data: - traefik_certificates: - traefik_config: - -x-common-environment: &common-environment - LAGO_API_URL: ${LAGO_API_URL} - REDIS_PASSWORD: ${REDIS_PASSWORD} - SECRET_KEY_BASE: ${SECRET_KEY_BASE} - RAILS_ENV: ${RAILS_ENV} - RAILS_LOG_TO_STDOUT: ${LAGO_RAILS_STDOUT} - SENTRY_DSN: ${SENTRY_DSN} - LAGO_FRONT_URL: ${LAGO_FRONT_URL} - LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} - LAGO_ENCRYPTION_PRIMARY_KEY: ${LAGO_ENCRYPTION_PRIMARY_KEY} - LAGO_ENCRYPTION_DETERMINISTIC_KEY: ${LAGO_ENCRYPTION_DETERMINISTIC_KEY} - LAGO_ENCRYPTION_KEY_DERIVATION_SALT: ${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} - LAGO_USE_AWS_S3: ${LAGO_USE_AWS_S3} - LAGO_AWS_S3_ACCESS_KEY_ID: ${LAGO_AWS_S3_ACCESS_KEY_ID} - LAGO_AWS_S3_SECRET_ACCESS_KEY: ${LAGO_AWS_S3_SECRET_ACCESS_KEY} - LAGO_AWS_S3_REGION: ${LAGO_AWS_S3_REGION} - LAGO_AWS_S3_BUCKET: ${LAGO_AWS_S3_BUCKET} - LAGO_AWS_S3_ENDPOINT: ${LAGO_AWS_S3_ENDPOINT} - LAGO_USE_GCS: ${LAGO_USE_GCS} - LAGO_GCS_PROJECT: ${LAGO_GCS_PROJECT} - LAGO_GCS_BUCKET: ${LAGO_GCS_BUCKET} - LAGO_PDF_URL: ${LAGO_PDF_URL} - LAGO_REDIS_CACHE_PASSWORD: ${LAGO_REDIS_CACHE_PASSWORD} - LAGO_DISABLE_SEGMENT: ${LAGO_DISABLE_SEGMENT} - LAGO_DISABLE_WALLET_REFRESH: ${LAGO_DISABLE_WALLET_REFRESH} - NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} - LAGO_LICENSE: ${LAGO_LICENSE} - -x-api-environment: &api-environment - <<: *common-environment - LAGO_SIDEKIQ_WEB: ${LAGO_SIDEKIQ_WEB} - LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} - GOOGLE_AUTH_CLIENT_ID: ${GOOGLE_AUTH_CLIENT_ID} - GOOGLE_AUTH_CLIENT_SECRET: ${GOOGLE_AUTH_CLIENT_SECRET} - -x-front-environment: &front-environment - API_URL: ${LAGO_API_URL} - APP_ENV: ${APP_ENV} - LAGO_DISABLE_SIGNUP: ${LAGO_DISABLE_SIGNUP} - LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} - SENTRY_DSN: ${SENTRY_DSN_FRONT} - NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} - -services: - traefik: - image: traefik:v2.5 - container_name: traefik - restart: unless-stopped - command: - - "--api.insecure=false" - - "--api.dashboard=true" - - "--providers.docker=true" - - "--providers.docker.exposedbydefault=false" - - "--entrypoints.web.address=:80" - - "--entrypoints.websecure.address=:443" - - "--certificatesresolvers.myresolver.acme.tlschallenge=true" - - "--certificatesresolvers.myresolver.acme.email=youremail@domain.tld" - - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" - ports: - - "80:80" - - "443:443" - volumes: - - "/var/run/docker.sock:/var/run/docker.sock:ro" - - traefik_certificates:/letsencrypt - - traefik_config:/traefik - labels: - - "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)" - - "traefik.http.routers.traefik.entrypoints=websecure" - - "traefik.http.routers.traefik.tls.certresolver=myresolver" - - "traefik.http.services.traefik.loadbalancer.server.port=8080" - - api: - container_name: lago-api - image: getlago/api:${LAGO_VERSION} - restart: unless-stopped - depends_on: - db: - condition: service_healthy - redis: - condition: service_healthy - command: ['./scripts/start.sh'] - environment: - <<: *api-environment - DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" - REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3000/health"] - interval: 10s - timeout: 60s - retries: 5 - labels: - - "traefik.enable=true" - - "traefik.http.routers.api.entrypoints=websecure" - - "traefik.http.routers.api.rule=Host(`${DOMAIN}`) && PathPrefix(`/api`)" - - "traefik.http.routers.api.tls.certresolver=myresolver" - - "traefik.http.routers.api.priority=100" - - "traefik.http.services.api.loadbalancer.server.port=3000" - - "traefik.http.middlewares.api-strip-prefix.stripprefix.prefixes=/api" - - "traefik.http.routers.api.middlewares=api-strip-prefix" - volumes: - - lago_storage_data:/app/storage - - front: - container_name: lago-front - image: getlago/front:${LAGO_VERSION} - restart: unless-stopped - depends_on: - api: - condition: service_healthy - environment: - <<: *front-environment - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:80"] - interval: 30s - timeout: 10s - retries: 3 - labels: - - "traefik.http.routers.front.priority=50" - - "traefik.enable=true" - - "traefik.http.routers.front.entrypoints=websecure" - - "traefik.http.routers.front.rule=Host(`${DOMAIN}`) && PathPrefix(`/`)" - - "traefik.http.routers.front.tls.certresolver=myresolver" - - "traefik.http.services.front.loadbalancer.server.port=80" - volumes: - - lago_storage_data:/app/storage - - db: - image: postgres:14-alpine - restart: unless-stopped - environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - PGDATA: ${PGDATA} - PGPORT: ${POSTGRES_PORT} - POSTGRES_SCHEMA: ${POSTGRES_SCHEMA} - volumes: - - lago_postgres_data:/data/postgres - ports: - - "${POSTGRES_PORT}:${POSTGRES_PORT}" - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] - interval: 10s - timeout: 5s - retries: 5 - - redis: - image: redis:6-alpine - container_name: lago-redis - restart: unless-stopped - command: --port ${REDIS_PORT:-6379} - volumes: - - lago_redis_data:/data - ports: - - "${REDIS_PORT:-6379}:${REDIS_PORT:-6379}" - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 10s - timeout: 5s - retries: 5 - - api-worker: - container_name: lago-worker - image: getlago/api:${LAGO_VERSION} - restart: unless-stopped - depends_on: - api: - condition: service_healthy - command: ['./scripts/start.worker.sh'] - environment: - <<: *common-environment - LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT}" - DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" - REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" - healthcheck: - test: ['CMD-SHELL', 'bundle exec sidekiqmon | grep $(hostname) || exit 1'] - volumes: - - lago_storage_data:/app/storage - - - api-clock: - container_name: lago-clock - image: getlago/api:${LAGO_VERSION} - restart: unless-stopped - depends_on: - api: - condition: service_healthy - command: ['./scripts/start.clock.sh'] - environment: - <<: *common-environment - LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT}" - DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" - REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" - - pdf: - image: getlago/lago-gotenberg:7.8.2 - - migrate: - container_name: lago-migrate - image: getlago/api:${LAGO_VERSION} - depends_on: - db: - condition: service_healthy - redis: - condition: service_healthy - command: ['./scripts/start.migrate.sh'] - volumes: - - lago_storage_data:/app/storage - - # You can uncomment this if you want to use a dedicated Sidekiq worker for the event ingestion. - # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. - #api-events-worker: - # container_name: lago-events-worker - # image: getlago/api:${LAGO_VERSION} - # restart: unless-stopped - # depends_on: - # api: - # condition: service_healthy - # command: ["./scripts/start.events.worker.sh"] - # environment: - # - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} - # - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} - # - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} - # - REDIS_PASSWORD=${REDIS_PASSWORD} - # - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} - # - RAILS_ENV=production - # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} - # - SENTRY_DSN=${SENTRY_DSN} - # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} - # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} - # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} - # - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} - # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} - # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} - # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} - # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} - # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} - # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} - # - LAGO_USE_GCS=${LAGO_USE_GCS:-false} - # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} - # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} - # - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} - # - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} - # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} - # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} - # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} - # - SIDEKIQ_EVENTS=true - # - LAGO_LICENSE=${LAGO_LICENSE:-} - - # You can uncomment this if you want to use a dedicated Sidekiq worker for the invoices pdf creation. - # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs. - #api-pdfs-worker: - # container_name: lago-pdfs-worker - # image: getlago/api:${LAGO_VERSION} - # restart: unless-stopped - # depends_on: - # api: - # condition: service_healthy - # command: ["./scripts/start.pdfs.worker.sh"] - # environment: - # - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} - # - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} - # - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} - # - REDIS_PASSWORD=${REDIS_PASSWORD} - # - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} - # - RAILS_ENV=production - # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} - # - SENTRY_DSN=${SENTRY_DSN} - # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} - # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} - # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} - # - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} - # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} - # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} - # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} - # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} - # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} - # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} - # - LAGO_USE_GCS=${LAGO_USE_GCS:-false} - # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} - # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} - # - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} - # - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} - # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} - # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} - # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} - # - SIDEKIQ_PDFS=true - # - LAGO_LICENSE=${LAGO_LICENSE:-} \ No newline at end of file diff --git a/env b/env deleted file mode 100644 index 5caae1ba6..000000000 --- a/env +++ /dev/null @@ -1,75 +0,0 @@ -#See more informations here : https://doc.getlago.com/guide/self-hosted/docker - -LAGO_VERSION=v1.13.1 - -# PostgreSQL Configuration -POSTGRES_DB=lago -POSTGRES_USER=lago -POSTGRES_PASSWORD=changeme -POSTGRES_HOST=db -POSTGRES_PORT=5432 -POSTGRES_SCHEMA=public -PGDATA=/data/postgres - -# Redis Configuration -REDIS_HOST=redis -REDIS_PORT=6379 -REDIS_PASSWORD= - -# Application Ports -API_PORT=3000 -FRONT_PORT=80 - - -# Lago API Configuration -DOMAIN=yourdomain.told -LAGO_API_URL=https://api.yourdomain.tld -LAGO_FRONT_URL=https://app.yourdomain.tld -SECRET_KEY_BASE=your-secret-key-base-hex-64 -RAILS_ENV=production -LAGO_RAILS_STDOUT=true -LAGO_PDF_URL=http://pdf:3000 -LAGO_DISABLE_SIGNUP=false -APP_ENV=production - -# Encryption Keys -LAGO_RSA_PRIVATE_KEY= -LAGO_ENCRYPTION_PRIMARY_KEY=your-encryption-primary-key -LAGO_ENCRYPTION_DETERMINISTIC_KEY=your-encryption-deterministic-key -LAGO_ENCRYPTION_KEY_DERIVATION_SALT=your-encryption-derivation-salt - -# AWS S3 Configuration -LAGO_USE_AWS_S3=false -LAGO_AWS_S3_ACCESS_KEY_ID=azerty123456 -LAGO_AWS_S3_SECRET_ACCESS_KEY=azerty123456 -LAGO_AWS_S3_REGION=us-east-1 -LAGO_AWS_S3_BUCKET=bucket -LAGO_AWS_S3_ENDPOINT= - -# Google Cloud Storage Configuration -LAGO_USE_GCS=false -LAGO_GCS_PROJECT= -LAGO_GCS_BUCKET= - -# Redis Cache Configuration -LAGO_REDIS_CACHE_HOST=redis -LAGO_REDIS_CACHE_PORT=6379 -LAGO_REDIS_CACHE_PASSWORD= - -# Sentry Configuration -SENTRY_DSN= -SENTRY_DSN_FRONT= - -# Lago Feature Flags -LAGO_DISABLE_SEGMENT= -LAGO_DISABLE_WALLET_REFRESH= -LAGO_SIDEKIQ_WEB= -SIDEKIQ_EVENTS= -SIDEKIQ_PDFS= - -# OAuth and Authentication -LAGO_OAUTH_PROXY_URL=https://proxy.getlago.com -GOOGLE_AUTH_CLIENT_ID= -GOOGLE_AUTH_CLIENT_SECRET= -NANGO_SECRET_KEY= -LAGO_LICENSE= From f6b251d4eab48d79adda14ed68f70be6c0813d25 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Tue, 22 Oct 2024 15:09:01 +0200 Subject: [PATCH 14/27] chore(docker-compose) moving domain to lagodomain --- .env.example | 2 +- docker-compose.new.yml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.env.example b/.env.example index 15410519a..a3bfc4750 100644 --- a/.env.example +++ b/.env.example @@ -22,7 +22,7 @@ FRONT_PORT=80 # Lago API Configuration -DOMAIN=yourdomain.told +LAGO_DOMAIN=yourdomain.told LAGO_API_URL=https://yourdomain.tld/api LAGO_FRONT_URL=https://yourdomain.tld SECRET_KEY_BASE=your-secret-key-base-hex-64 diff --git a/docker-compose.new.yml b/docker-compose.new.yml index bb75ae3b2..3db732e4c 100644 --- a/docker-compose.new.yml +++ b/docker-compose.new.yml @@ -61,7 +61,7 @@ services: - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.lagoresolver.acme.tlschallenge=true" - - "--certificatesresolvers.lagoresolver.acme.email=youremail@domain.tld" + - "--certificatesresolvers.lagoresolver.acme.email=youremail@lagoddomain.tld" - "--certificatesresolvers.lagoresolver.acme.storage=/letsencrypt/acme.json" ports: - "80:80" @@ -71,7 +71,7 @@ services: - traefik_certificates:/letsencrypt - traefik_config:/traefik labels: - - "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)" + - "traefik.http.routers.traefik.rule=Host(`traefik.${LAGO_DOMAIN}`)" - "traefik.http.routers.traefik.entrypoints=websecure" - "traefik.http.routers.traefik.tls.certresolver=lagoresolver" - "traefik.http.services.traefik.loadbalancer.server.port=8080" @@ -98,7 +98,7 @@ services: labels: - "traefik.enable=true" - "traefik.http.routers.api.entrypoints=websecure" - - "traefik.http.routers.api.rule=Host(`${DOMAIN}`) && PathPrefix(`/api`)" + - "traefik.http.routers.api.rule=Host(`${LAGO_DOMAIN}`) && PathPrefix(`/api`)" - "traefik.http.routers.api.tls.certresolver=lagoresolver" - "traefik.http.routers.api.priority=100" - "traefik.http.services.api.loadbalancer.server.port=3000" @@ -125,7 +125,7 @@ services: - "traefik.http.routers.front.priority=50" - "traefik.enable=true" - "traefik.http.routers.front.entrypoints=websecure" - - "traefik.http.routers.front.rule=Host(`${DOMAIN}`) && PathPrefix(`/`)" + - "traefik.http.routers.front.rule=Host(`${LAGO_DOMAIN}`) && PathPrefix(`/`)" - "traefik.http.routers.front.tls.certresolver=lagoresolver" - "traefik.http.services.front.loadbalancer.server.port=80" volumes: From 1e5a117b128a4320b4dbee53b617b57edfaf091d Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Tue, 22 Oct 2024 15:11:17 +0200 Subject: [PATCH 15/27] chore(docker-compose) renaming commentary --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index a3bfc4750..26ce58afd 100644 --- a/.env.example +++ b/.env.example @@ -21,7 +21,7 @@ API_PORT=3000 FRONT_PORT=80 -# Lago API Configuration +# Lago Global Configuration LAGO_DOMAIN=yourdomain.told LAGO_API_URL=https://yourdomain.tld/api LAGO_FRONT_URL=https://yourdomain.tld From 6e7cb8e2c8a288a740f68e56e9dd4dd42140ec4a Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Tue, 22 Oct 2024 15:14:18 +0200 Subject: [PATCH 16/27] chore(docker-compose) updating version on old version --- docker-compose.old.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docker-compose.old.yml b/docker-compose.old.yml index 2f5902f82..c002ed2c0 100644 --- a/docker-compose.old.yml +++ b/docker-compose.old.yml @@ -62,7 +62,7 @@ services: api: container_name: lago-api - image: getlago/api:v1.12.2 + image: getlago/api:v1.13.1 restart: unless-stopped depends_on: - db @@ -121,7 +121,7 @@ services: front: container_name: lago-front - image: getlago/front:v1.12.2 + image: getlago/front:v1.13.1 restart: unless-stopped # Use this command if you want to use SSL with Let's Encrypt # command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" @@ -160,7 +160,7 @@ services: api-worker: container_name: lago-worker - image: getlago/api:v1.12.2 + image: getlago/api:v1.13.1 restart: unless-stopped depends_on: api: @@ -208,7 +208,7 @@ services: # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. #api-events-worker: # container_name: lago-events-worker - # image: getlago/api:v1.12.2 + # image: getlago/api:v1.13.1 # restart: unless-stopped # depends_on: # api: @@ -251,7 +251,7 @@ services: # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs. #api-pdfs-worker: # container_name: lago-pdfs-worker - # image: getlago/api:v1.12.2 + # image: getlago/api:v1.13.1 # restart: unless-stopped # depends_on: # api: @@ -292,7 +292,7 @@ services: api-clock: container_name: lago-clock - image: getlago/api:v1.12.2 + image: getlago/api:v1.13.1 restart: unless-stopped depends_on: api: @@ -322,7 +322,7 @@ services: migrate: container_name: lago-migrate - image: getlago/api:v1.12.2 + image: getlago/api:v1.13.1 depends_on: - db - redis From 492edf708b82b3e93c559bcc1846875a4c67fcea Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Tue, 22 Oct 2024 15:22:43 +0200 Subject: [PATCH 17/27] chore(docker-compose) updating warning of older docker-compose --- docker-compose.old.yml | 62 +++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/docker-compose.old.yml b/docker-compose.old.yml index c002ed2c0..7b31ac550 100644 --- a/docker-compose.old.yml +++ b/docker-compose.old.yml @@ -1,31 +1,37 @@ -############################################## -# # -# !!! WARNING !!! # -# # -# This file 'docker-compose.old.yaml' # -# is DEPRECATED and has been replaced by # -# the new 'docker-compose.yml'. # -# # -# Please migrate to the new version by # -# following the steps below: # -# # -# 1. Perform a backup of the current # -# volumes. This step is mandatory! # -# # -# 2. Most variables will be set in the # -# '.env' file (see '.env.example' # -# for more information). # -# # -# 3. Change the 'apiUrl' variable, which # -# no longer uses 'api.', but now ends # -# with '/api' after the domain name. # -# # -# 4. SSL certificate management is now # -# automatic. There's nothing more to # -# do on this subject unless you are # -# using 'localhost'. # -# # -############################################## +############################################################ +# # +# !!! WARNING !!! # +# # +# This file 'docker-compose.old.yaml' is DEPRECATED # +# and will be permanently removed from the repository # +# on January 1st, 2025. The 'docker-compose.new.yaml' # +# will then become 'docker-compose.yaml'. # +# # +# Please migrate to the new version by following # +# the steps below: # +# # +# 1. Perform a backup of the current volumes. # +# This step is mandatory! # +# # +# 2. Most variables will be set in the '.env' file # +# (see '.env.example' for more information). # +# # +# 3. Change the 'apiUrl' variable, which no longer # +# uses 'api.', but now ends with '/api' after # +# the domain name. # +# # +# 4. SSL certificate management is now automatic. # +# There's nothing more to do on this subject unless # +# you are using 'localhost'. # +# # +# 5. IMPORTANT: Only migrate to the new docker-compose # +# if you are using a recent version of the # +# application (at least v1.13.1). Otherwise, please # +# first run 'docker-compose.old.yaml' with updated # +# image versions before switching to the new one. # +# # +############################################################ + volumes: From b6c47579551eaa48719a3f296ab155b1e8b8228a Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Sun, 3 Nov 2024 13:09:39 +0100 Subject: [PATCH 18/27] feat(compose): Adding QA Review, adding default values, updating documentation --- .env.example | 103 +++++++++--------- README.md | 41 +++++-- docker-compose.new.yml | 236 ++++++++++++++--------------------------- 3 files changed, 163 insertions(+), 217 deletions(-) diff --git a/.env.example b/.env.example index 26ce58afd..7f4bd2052 100644 --- a/.env.example +++ b/.env.example @@ -1,75 +1,74 @@ -#See more informations here : https://doc.getlago.com/guide/self-hosted/docker +# See more information here: https://doc.getlago.com/guide/self-hosted/docker -LAGO_VERSION=v1.13.1 +# LAGO_VERSION=v1.13.1 # PostgreSQL Configuration -POSTGRES_DB=lago -POSTGRES_USER=lago -POSTGRES_PASSWORD=changeme -POSTGRES_HOST=db -POSTGRES_PORT=5432 -POSTGRES_SCHEMA=public -PGDATA=/data/postgres +# POSTGRES_DB=lago +# POSTGRES_USER=lago +# POSTGRES_PASSWORD=changeme +# POSTGRES_HOST=db +# POSTGRES_PORT=5432 +# POSTGRES_SCHEMA=public +# PGDATA=/data/postgres # Redis Configuration -REDIS_HOST=redis -REDIS_PORT=6379 -REDIS_PASSWORD= +# REDIS_HOST=redis +# REDIS_PORT=6379 +# REDIS_PASSWORD= # Application Ports -API_PORT=3000 -FRONT_PORT=80 - +# API_PORT=3000 +# FRONT_PORT=80 # Lago Global Configuration -LAGO_DOMAIN=yourdomain.told -LAGO_API_URL=https://yourdomain.tld/api -LAGO_FRONT_URL=https://yourdomain.tld -SECRET_KEY_BASE=your-secret-key-base-hex-64 -RAILS_ENV=production -LAGO_RAILS_STDOUT=true -LAGO_PDF_URL=http://pdf:3000 -LAGO_DISABLE_SIGNUP=false -APP_ENV=production +# LAGO_DOMAIN=yourdomain.tld +# LAGO_API_URL=https://yourdomain.tld/api +# LAGO_FRONT_URL=https://yourdomain.tld +# SECRET_KEY_BASE=your-secret-key-base-hex-64 +# RAILS_ENV=production +# LAGO_RAILS_STDOUT=true +# LAGO_PDF_URL=http://pdf:3000 +# LAGO_DISABLE_SIGNUP=false +# APP_ENV=production # Encryption Keys -LAGO_RSA_PRIVATE_KEY= -LAGO_ENCRYPTION_PRIMARY_KEY=your-encryption-primary-key -LAGO_ENCRYPTION_DETERMINISTIC_KEY=your-encryption-deterministic-key -LAGO_ENCRYPTION_KEY_DERIVATION_SALT=your-encryption-derivation-salt +# LAGO_RSA_PRIVATE_KEY= +# LAGO_ENCRYPTION_PRIMARY_KEY=your-encryption-primary-key +# LAGO_ENCRYPTION_DETERMINISTIC_KEY=your-encryption-deterministic-key +# LAGO_ENCRYPTION_KEY_DERIVATION_SALT=your-encryption-derivation-salt # AWS S3 Configuration -LAGO_USE_AWS_S3=false -LAGO_AWS_S3_ACCESS_KEY_ID=azerty123456 -LAGO_AWS_S3_SECRET_ACCESS_KEY=azerty123456 -LAGO_AWS_S3_REGION=us-east-1 -LAGO_AWS_S3_BUCKET=bucket -LAGO_AWS_S3_ENDPOINT= +# LAGO_USE_AWS_S3=false +# LAGO_AWS_S3_ACCESS_KEY_ID=azerty123456 +# LAGO_AWS_S3_SECRET_ACCESS_KEY=azerty123456 +# LAGO_AWS_S3_REGION=us-east-1 +# LAGO_AWS_S3_BUCKET=bucket +# LAGO_AWS_S3_ENDPOINT= # Google Cloud Storage Configuration -LAGO_USE_GCS=false -LAGO_GCS_PROJECT= -LAGO_GCS_BUCKET= +# LAGO_USE_GCS=false +# LAGO_GCS_PROJECT= +# LAGO_GCS_BUCKET= # Redis Cache Configuration -LAGO_REDIS_CACHE_HOST=redis -LAGO_REDIS_CACHE_PORT=6379 -LAGO_REDIS_CACHE_PASSWORD= +# LAGO_REDIS_CACHE_HOST=redis +# LAGO_REDIS_CACHE_PORT=6379 +# LAGO_REDIS_CACHE_PASSWORD= # Sentry Configuration -SENTRY_DSN= -SENTRY_DSN_FRONT= +# SENTRY_DSN= +# SENTRY_DSN_FRONT= # Lago Feature Flags -LAGO_DISABLE_SEGMENT= -LAGO_DISABLE_WALLET_REFRESH= -LAGO_SIDEKIQ_WEB= -SIDEKIQ_EVENTS= -SIDEKIQ_PDFS= +# LAGO_DISABLE_SEGMENT= +# LAGO_DISABLE_WALLET_REFRESH= +# LAGO_SIDEKIQ_WEB= +# SIDEKIQ_EVENTS= +# SIDEKIQ_PDFS= # OAuth and Authentication -LAGO_OAUTH_PROXY_URL=https://proxy.getlago.com -GOOGLE_AUTH_CLIENT_ID= -GOOGLE_AUTH_CLIENT_SECRET= -NANGO_SECRET_KEY= -LAGO_LICENSE= +# LAGO_OAUTH_PROXY_URL=https://proxy.getlago.com +# GOOGLE_AUTH_CLIENT_ID= +# GOOGLE_AUTH_CLIENT_SECRET= +# NANGO_SECRET_KEY= +# LAGO_LICENSE= diff --git a/README.md b/README.md index 91e1638c0..a45602ea1 100644 --- a/README.md +++ b/README.md @@ -105,32 +105,55 @@ To start using Lago, run the following commands in a shell: #### On a fresh install + +##### 1 :Clone the Repository: + ```bash # Get the code git clone --depth 1 https://github.com/getlago/lago.git # Go to Lago folder cd lago +``` -# Set up environment configuration -echo "LAGO_RSA_PRIVATE_KEY=\"`openssl genrsa 2048 | base64`\"" >> .env -source .env +##### 2 : Set Up Environment Variables: Run the following script to copy the example .env file, generate necessary keys, and populate the .env file: -# Start the api -docker compose up -d api -# Create the database +```bash +# Copy the example .env file and populate keys +cp .env.example .env +echo "SECRET_KEY_BASE=\"$(openssl rand -hex 64)\"" >> .env +echo "LAGO_RSA_PRIVATE_KEY=\"$(openssl genrsa 2048 | base64)\"" >> .env +echo "LAGO_ENCRYPTION_PRIMARY_KEY=\"$(openssl rand -base64 32)\"" >> .env +echo "LAGO_ENCRYPTION_DETERMINISTIC_KEY=\"$(openssl rand -base64 32)\"" >> .env +echo "LAGO_ENCRYPTION_KEY_DERIVATION_SALT=\"$(openssl rand -base64 32)\"" >> .env +``` + +##### 3 : Launch the API Service: + +```bash +docker compose -f docker-compose.new.yml up -d api +``` + +##### 4 : Create and Migrate the Database: + +```bash docker compose exec api rails db:create docker compose exec api rails db:migrate +``` -# Start all other components -docker compose up +##### 5 : Launch All Services: + + +```bash +docker compose -f docker-compose.new.yml up -d ``` + #### After an update ```bash -docker compose up +docker compose -f docker-compose.new.yml up -d ``` You can now open your browser and go to http://localhost to connect to the application. Lago's API is exposed at http://localhost:3000. diff --git a/docker-compose.new.yml b/docker-compose.new.yml index 3db732e4c..25880bbfe 100644 --- a/docker-compose.new.yml +++ b/docker-compose.new.yml @@ -5,48 +5,49 @@ volumes: traefik_certificates: traefik_config: -x-common-environment: &common-environment - LAGO_API_URL: ${LAGO_API_URL} - REDIS_PASSWORD: ${REDIS_PASSWORD} - SECRET_KEY_BASE: ${SECRET_KEY_BASE} - RAILS_ENV: ${RAILS_ENV} - RAILS_LOG_TO_STDOUT: ${LAGO_RAILS_STDOUT} - SENTRY_DSN: ${SENTRY_DSN} - LAGO_FRONT_URL: ${LAGO_FRONT_URL} +x-backend-x: &backend-environment + LAGO_API_URL: ${LAGO_API_URL:-http://localhost/api} + REDIS_PASSWORD: ${REDIS_PASSWORD:-changeme} + SECRET_KEY_BASE: ${SECRET_KEY_BASE:-your-secret-key-base-hex-64} + RAILS_ENV: ${RAILS_ENV:-production} + RAILS_LOG_TO_STDOUT: ${LAGO_RAILS_STDOUT:-true} + SENTRY_DSN: ${SENTRY_DSN:-} + LAGO_FRONT_URL: ${LAGO_FRONT_URL:-http://localhost} LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} - LAGO_ENCRYPTION_PRIMARY_KEY: ${LAGO_ENCRYPTION_PRIMARY_KEY} - LAGO_ENCRYPTION_DETERMINISTIC_KEY: ${LAGO_ENCRYPTION_DETERMINISTIC_KEY} - LAGO_ENCRYPTION_KEY_DERIVATION_SALT: ${LAGO_ENCRYPTION_KEY_DERIVATION_SALT} - LAGO_USE_AWS_S3: ${LAGO_USE_AWS_S3} - LAGO_AWS_S3_ACCESS_KEY_ID: ${LAGO_AWS_S3_ACCESS_KEY_ID} - LAGO_AWS_S3_SECRET_ACCESS_KEY: ${LAGO_AWS_S3_SECRET_ACCESS_KEY} - LAGO_AWS_S3_REGION: ${LAGO_AWS_S3_REGION} - LAGO_AWS_S3_BUCKET: ${LAGO_AWS_S3_BUCKET} - LAGO_AWS_S3_ENDPOINT: ${LAGO_AWS_S3_ENDPOINT} - LAGO_USE_GCS: ${LAGO_USE_GCS} - LAGO_GCS_PROJECT: ${LAGO_GCS_PROJECT} - LAGO_GCS_BUCKET: ${LAGO_GCS_BUCKET} - LAGO_PDF_URL: ${LAGO_PDF_URL} - LAGO_REDIS_CACHE_PASSWORD: ${LAGO_REDIS_CACHE_PASSWORD} - LAGO_DISABLE_SEGMENT: ${LAGO_DISABLE_SEGMENT} - LAGO_DISABLE_WALLET_REFRESH: ${LAGO_DISABLE_WALLET_REFRESH} - NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} - LAGO_LICENSE: ${LAGO_LICENSE} + LAGO_ENCRYPTION_PRIMARY_KEY: ${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} + LAGO_ENCRYPTION_DETERMINISTIC_KEY: ${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} + LAGO_ENCRYPTION_KEY_DERIVATION_SALT: ${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} + LAGO_USE_AWS_S3: ${LAGO_USE_AWS_S3:-false} + LAGO_AWS_S3_ACCESS_KEY_ID: ${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} + LAGO_AWS_S3_SECRET_ACCESS_KEY: ${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} + LAGO_AWS_S3_REGION: ${LAGO_AWS_S3_REGION:-us-east-1} + LAGO_AWS_S3_BUCKET: ${LAGO_AWS_S3_BUCKET:-bucket} + LAGO_AWS_S3_ENDPOINT: ${LAGO_AWS_S3_ENDPOINT:-http://s3.amazonaws.com} + LAGO_USE_GCS: ${LAGO_USE_GCS:-false} + LAGO_GCS_PROJECT: ${LAGO_GCS_PROJECT:-your-gcs-project} + LAGO_GCS_BUCKET: ${LAGO_GCS_BUCKET:-your-gcs-bucket} + LAGO_PDF_URL: ${LAGO_PDF_URL:-http://pdf:3000} + LAGO_REDIS_CACHE_PASSWORD: ${LAGO_REDIS_CACHE_PASSWORD:-changeme} + LAGO_DISABLE_SEGMENT: ${LAGO_DISABLE_SEGMENT:-false} + LAGO_DISABLE_WALLET_REFRESH: ${LAGO_DISABLE_WALLET_REFRESH:-false} + NANGO_SECRET_KEY: ${NANGO_SECRET_KEY:-your-nango-secret-key} + LAGO_LICENSE: ${LAGO_LICENSE:-your-lago-license} x-api-environment: &api-environment - <<: *common-environment - LAGO_SIDEKIQ_WEB: ${LAGO_SIDEKIQ_WEB} - LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} - GOOGLE_AUTH_CLIENT_ID: ${GOOGLE_AUTH_CLIENT_ID} - GOOGLE_AUTH_CLIENT_SECRET: ${GOOGLE_AUTH_CLIENT_SECRET} + <<: *backend-environment + LAGO_SIDEKIQ_WEB: ${LAGO_SIDEKIQ_WEB:-true} + LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL:-https://proxy.getlago.com} + GOOGLE_AUTH_CLIENT_ID: ${GOOGLE_AUTH_CLIENT_ID:-} + GOOGLE_AUTH_CLIENT_SECRET: ${GOOGLE_AUTH_CLIENT_SECRET:-} x-front-environment: &front-environment - API_URL: ${LAGO_API_URL} - APP_ENV: ${APP_ENV} - LAGO_DISABLE_SIGNUP: ${LAGO_DISABLE_SIGNUP} - LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL} - SENTRY_DSN: ${SENTRY_DSN_FRONT} - NANGO_SECRET_KEY: ${NANGO_SECRET_KEY} + API_URL: ${LAGO_API_URL:-http://localhost/api} + APP_ENV: ${APP_ENV:-production} + LAGO_DISABLE_SIGNUP: ${LAGO_DISABLE_SIGNUP:-false} + LAGO_OAUTH_PROXY_URL: ${LAGO_OAUTH_PROXY_URL:-https://proxy.getlago.com} + SENTRY_DSN: ${SENTRY_DSN_FRONT:-} + NANGO_SECRET_KEY: ${NANGO_SECRET_KEY:-} + services: traefik: @@ -71,14 +72,14 @@ services: - traefik_certificates:/letsencrypt - traefik_config:/traefik labels: - - "traefik.http.routers.traefik.rule=Host(`traefik.${LAGO_DOMAIN}`)" - - "traefik.http.routers.traefik.entrypoints=websecure" + - "traefik.http.routers.traefik.rule=Host(`${LAGO_DOMAIN:-localhost}`)" + - "traefik.http.routers.traefik.entrypoints=web" - "traefik.http.routers.traefik.tls.certresolver=lagoresolver" - "traefik.http.services.traefik.loadbalancer.server.port=8080" api: container_name: lago-api - image: getlago/api:${LAGO_VERSION} + image: getlago/api:${LAGO_VERSION:-v1.15.1} restart: unless-stopped depends_on: db: @@ -86,21 +87,24 @@ services: redis: condition: service_healthy command: ['./scripts/start.sh'] + ports: + - ${API_PORT:-3000}:3000 environment: <<: *api-environment - DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" - REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" + DATABASE_URL: "postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public}" + REDIS_URL: "redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379}" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 10s timeout: 60s retries: 5 labels: - - "traefik.enable=true" - - "traefik.http.routers.api.entrypoints=websecure" - - "traefik.http.routers.api.rule=Host(`${LAGO_DOMAIN}`) && PathPrefix(`/api`)" - - "traefik.http.routers.api.tls.certresolver=lagoresolver" + # SSL + # - "traefik.http.routers.api.entrypoints=websecure" + - "traefik.http.routers.api.entrypoints=web" - "traefik.http.routers.api.priority=100" + - "traefik.enable=true" + - "traefik.http.routers.api.rule=Host(`${LAGO_DOMAIN:-localhost}`) && PathPrefix(`/api`)" - "traefik.http.services.api.loadbalancer.server.port=3000" - "traefik.http.middlewares.api-strip-prefix.stripprefix.prefixes=/api" - "traefik.http.routers.api.middlewares=api-strip-prefix" @@ -109,7 +113,7 @@ services: front: container_name: lago-front - image: getlago/front:${LAGO_VERSION} + image: getlago/front:${LAGO_VERSION:-v1.15.1} restart: unless-stopped depends_on: api: @@ -124,9 +128,8 @@ services: labels: - "traefik.http.routers.front.priority=50" - "traefik.enable=true" - - "traefik.http.routers.front.entrypoints=websecure" - - "traefik.http.routers.front.rule=Host(`${LAGO_DOMAIN}`) && PathPrefix(`/`)" - - "traefik.http.routers.front.tls.certresolver=lagoresolver" + - "traefik.http.routers.front.entrypoints=web" + - "traefik.http.routers.front.rule=Host(`${LAGO_DOMAIN:-localhost}`) && PathPrefix(`/`)" - "traefik.http.services.front.loadbalancer.server.port=80" volumes: - lago_storage_data:/app/storage @@ -135,18 +138,18 @@ services: image: postgres:14-alpine restart: unless-stopped environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - PGDATA: ${PGDATA} - PGPORT: ${POSTGRES_PORT} - POSTGRES_SCHEMA: ${POSTGRES_SCHEMA} + POSTGRES_DB: ${POSTGRES_DB:-lago} + POSTGRES_USER: ${POSTGRES_USER:-lago} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme} + PGDATA: ${PGDATA:-/data/postgres} + PGPORT: ${POSTGRES_PORT:-5432} + POSTGRES_SCHEMA: ${POSTGRES_SCHEMA:-public} volumes: - lago_postgres_data:/data/postgres ports: - - "${POSTGRES_PORT}:${POSTGRES_PORT}" + - "${POSTGRES_PORT:-5432}:${POSTGRES_PORT:-5432}" healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-lago}"] interval: 10s timeout: 5s retries: 5 @@ -168,134 +171,55 @@ services: api-worker: container_name: lago-worker - image: getlago/api:${LAGO_VERSION} + image: getlago/api:${LAGO_VERSION:-v1.15.1} restart: unless-stopped depends_on: api: condition: service_healthy command: ['./scripts/start.worker.sh'] environment: - <<: *common-environment - LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT}" - DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" - REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" + <<: *backend-environment + LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379}" + DATABASE_URL: "postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public}" + REDIS_URL: "redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379}" healthcheck: test: ['CMD-SHELL', 'bundle exec sidekiqmon | grep $(hostname) || exit 1'] volumes: - lago_storage_data:/app/storage - api-clock: container_name: lago-clock - image: getlago/api:${LAGO_VERSION} + image: getlago/api:${LAGO_VERSION:-v1.15.1} restart: unless-stopped depends_on: api: condition: service_healthy command: ['./scripts/start.clock.sh'] environment: - <<: *common-environment - LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST}:${LAGO_REDIS_CACHE_PORT}" - DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA}" - REDIS_URL: "redis://${REDIS_HOST}:${REDIS_PORT:-6379}" + <<: *backend-environment + LAGO_REDIS_CACHE_URL: "redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379}" + DATABASE_URL: "postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public}" + REDIS_URL: "redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379}" pdf: image: getlago/lago-gotenberg:7.8.2 migrate: container_name: lago-migrate - image: getlago/api:${LAGO_VERSION} + image: getlago/api:${LAGO_VERSION:-v1.15.1} depends_on: db: condition: service_healthy redis: condition: service_healthy command: ['./scripts/start.migrate.sh'] + environment: + - RAILS_ENV=production + - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} + - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} + - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} + - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} + - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} + - REDIS_PASSWORD=${REDIS_PASSWORD} volumes: - lago_storage_data:/app/storage - - # You can uncomment this if you want to use a dedicated Sidekiq worker for the event ingestion. - # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs. - #api-events-worker: - # container_name: lago-events-worker - # image: getlago/api:${LAGO_VERSION} - # restart: unless-stopped - # depends_on: - # api: - # condition: service_healthy - # command: ["./scripts/start.events.worker.sh"] - # environment: - # - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} - # - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} - # - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} - # - REDIS_PASSWORD=${REDIS_PASSWORD} - # - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} - # - RAILS_ENV=production - # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} - # - SENTRY_DSN=${SENTRY_DSN} - # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} - # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} - # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} - # - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} - # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} - # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} - # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} - # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} - # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} - # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} - # - LAGO_USE_GCS=${LAGO_USE_GCS:-false} - # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} - # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} - # - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} - # - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} - # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} - # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} - # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} - # - SIDEKIQ_EVENTS=true - # - LAGO_LICENSE=${LAGO_LICENSE:-} - - # You can uncomment this if you want to use a dedicated Sidekiq worker for the invoices pdf creation. - # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs. - #api-pdfs-worker: - # container_name: lago-pdfs-worker - # image: getlago/api:${LAGO_VERSION} - # restart: unless-stopped - # depends_on: - # api: - # condition: service_healthy - # command: ["./scripts/start.pdfs.worker.sh"] - # environment: - # - LAGO_API_URL=${LAGO_API_URL:-http://localhost:3000} - # - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} - # - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} - # - REDIS_PASSWORD=${REDIS_PASSWORD} - # - SECRET_KEY_BASE=${SECRET_KEY_BASE:-your-secret-key-base-hex-64} - # - RAILS_ENV=production - # - RAILS_LOG_TO_STDOUT=${LAGO_RAILS_STDOUT:-true} - # - SENTRY_DSN=${SENTRY_DSN} - # - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} # Should be base64 encoded - # - LAGO_ENCRYPTION_PRIMARY_KEY=${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} - # - LAGO_ENCRYPTION_DETERMINISTIC_KEY=${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} - # - LAGO_ENCRYPTION_KEY_DERIVATION_SALT=${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt} - # - LAGO_FRONT_URL=${LAGO_FRONT_URL:-http://localhost} - # - LAGO_USE_AWS_S3=${LAGO_USE_AWS_S3:-false} - # - LAGO_AWS_S3_ACCESS_KEY_ID=${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456} - # - LAGO_AWS_S3_SECRET_ACCESS_KEY=${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456} - # - LAGO_AWS_S3_REGION=${LAGO_AWS_S3_REGION:-us-east-1} - # - LAGO_AWS_S3_BUCKET=${LAGO_AWS_S3_BUCKET:-bucket} - # - LAGO_AWS_S3_ENDPOINT=${LAGO_AWS_S3_ENDPOINT} - # - LAGO_USE_GCS=${LAGO_USE_GCS:-false} - # - LAGO_GCS_PROJECT=${LAGO_GCS_PROJECT:-} - # - LAGO_GCS_BUCKET=${LAGO_GCS_BUCKET:-} - # - LAGO_PDF_URL=${LAGO_PDF_URL:-http://pdf:3000} - # - LAGO_REDIS_CACHE_URL=redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379} - # - LAGO_REDIS_CACHE_PASSWORD=${LAGO_REDIS_CACHE_PASSWORD} - # - LAGO_DISABLE_SEGMENT=${LAGO_DISABLE_SEGMENT} - # - LAGO_DISABLE_WALLET_REFRESH=${LAGO_DISABLE_WALLET_REFRESH} - # - NANGO_SECRET_KEY=${NANGO_SECRET_KEY:-} - # - SIDEKIQ_PDFS=true - # - LAGO_LICENSE=${LAGO_LICENSE:-} \ No newline at end of file From 783de42cb75693ef262e9b00e66c4b7a999f0c33 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Mon, 4 Nov 2024 10:00:53 +0100 Subject: [PATCH 19/27] feat(compose): update documentation with correct .env values --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a45602ea1..31f67c2e8 100644 --- a/README.md +++ b/README.md @@ -156,13 +156,12 @@ docker compose -f docker-compose.new.yml up -d docker compose -f docker-compose.new.yml up -d ``` -You can now open your browser and go to http://localhost to connect to the application. Lago's API is exposed at http://localhost:3000. +You can now open your browser and go to http://localhost to connect to the application. Lago's API is exposed at http://localhost/api. -Note that if our docker server is not at http://localhost, the following env variables must be set: `LAGO_API_URL`. This may be on the command line or in your .env file. For example: +Note that if our docker server is not at http://localhost, the following env variables must be set: `LAGO_DOMAIN`. This may be on the command line or in your .env file. For example: ``` -LAGO_API_URL="http://192.168.122.71:3000" -LAGO_FRONT_URL="http://192.168.122.71" +LAGO_DOMAIN=yourdomain.tld" ``` ### Find your API key From b8438bae64e36a926d8c9b95516d90fd8b757f0b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Mon, 4 Nov 2024 10:31:05 +0100 Subject: [PATCH 20/27] feat(traefik): add optional TLS cert resolver for API and frontend --- docker-compose.new.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker-compose.new.yml b/docker-compose.new.yml index 25880bbfe..b34b1d118 100644 --- a/docker-compose.new.yml +++ b/docker-compose.new.yml @@ -73,6 +73,8 @@ services: - traefik_config:/traefik labels: - "traefik.http.routers.traefik.rule=Host(`${LAGO_DOMAIN:-localhost}`)" + # SSL + # - "traefik.http.routers.api.entrypoints=websecure" - "traefik.http.routers.traefik.entrypoints=web" - "traefik.http.routers.traefik.tls.certresolver=lagoresolver" - "traefik.http.services.traefik.loadbalancer.server.port=8080" @@ -100,6 +102,7 @@ services: retries: 5 labels: # SSL + # - "traefik.http.routers.api.tls.certresolver=lagoresolver" # - "traefik.http.routers.api.entrypoints=websecure" - "traefik.http.routers.api.entrypoints=web" - "traefik.http.routers.api.priority=100" @@ -128,6 +131,9 @@ services: labels: - "traefik.http.routers.front.priority=50" - "traefik.enable=true" + # SSL + # - "traefik.http.routers.api.tls.certresolver=lagoresolver" + # - "traefik.http.routers.api.entrypoints=websecure" - "traefik.http.routers.front.entrypoints=web" - "traefik.http.routers.front.rule=Host(`${LAGO_DOMAIN:-localhost}`) && PathPrefix(`/`)" - "traefik.http.services.front.loadbalancer.server.port=80" From 5f51ee906b6757ff9a9a190e54e1811aa2daaaa1 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Mon, 4 Nov 2024 14:44:56 +0100 Subject: [PATCH 21/27] chore(docs): update Docker Compose commands with missing flag --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 31f67c2e8..edfde17a7 100644 --- a/README.md +++ b/README.md @@ -138,8 +138,8 @@ docker compose -f docker-compose.new.yml up -d api ##### 4 : Create and Migrate the Database: ```bash -docker compose exec api rails db:create -docker compose exec api rails db:migrate +docker compose -f docker-compose.new.yml exec api rails db:create +docker compose -f docker-compose.new.yml exec api rails db:migrate ``` ##### 5 : Launch All Services: From 7b04442ce964a3cd7529bb4b0d7d67f478f7a201 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Mon, 4 Nov 2024 14:47:26 +0100 Subject: [PATCH 22/27] chore(compose): Adding Redis default password inside migrate --- docker-compose.new.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.new.yml b/docker-compose.new.yml index b34b1d118..b114b8db0 100644 --- a/docker-compose.new.yml +++ b/docker-compose.new.yml @@ -226,6 +226,6 @@ services: - LAGO_RSA_PRIVATE_KEY=${LAGO_RSA_PRIVATE_KEY} - DATABASE_URL=postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public} - REDIS_URL=redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379} - - REDIS_PASSWORD=${REDIS_PASSWORD} + - REDIS_PASSWORD=${REDIS_PASSWORD:-changeme} volumes: - lago_storage_data:/app/storage From d877971d54f1d085376167c1cda1e724c47495cc Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Mon, 4 Nov 2024 16:47:05 +0100 Subject: [PATCH 23/27] chore(compose): add warning for insecure Traefik dashboard access and moving back docker-compose.yml --- docker-compose.new.yml | 8 +++++++- docker-compose.old.yml => docker-compose.yml | 0 2 files changed, 7 insertions(+), 1 deletion(-) rename docker-compose.old.yml => docker-compose.yml (100%) diff --git a/docker-compose.new.yml b/docker-compose.new.yml index b114b8db0..302baecc6 100644 --- a/docker-compose.new.yml +++ b/docker-compose.new.yml @@ -55,7 +55,12 @@ services: container_name: traefik restart: unless-stopped command: - - "--api.insecure=false" + # WARNING: It is strongly discouraged to use Traefik with "--api.insecure=true" + # as this exposes the Traefik dashboard publicly without any security measures, + # which can lead to unauthorized access and potential security risks. + # For a production setup, consider enabling secure access to the dashboard + # by using authentication and restricting access to trusted IPs or networks. + - "--api.insecure=true" - "--api.dashboard=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" @@ -67,6 +72,7 @@ services: ports: - "80:80" - "443:443" + - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" - traefik_certificates:/letsencrypt diff --git a/docker-compose.old.yml b/docker-compose.yml similarity index 100% rename from docker-compose.old.yml rename to docker-compose.yml From 1ab159e4eb19f7c33bf1bcbb1f6fc44017adc21f Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Mon, 4 Nov 2024 20:22:46 +0100 Subject: [PATCH 24/27] docs: add documentation for Traefik dashboard with secure login --- README.md | 16 ++++++++++++++++ docker-compose.new.yml | 23 ++++++++++++----------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index edfde17a7..2d8044ab6 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,22 @@ Note that if our docker server is not at http://localhost, the following env var LAGO_DOMAIN=yourdomain.tld" ``` +##### Accessing Traefik Dashboard + +The Traefik dashboard is available at http://traefik.localhost (or replace `localhost` with your custom `LAGO_DOMAIN`). For security reasons, we have configured basic authentication for accessing the Traefik dashboard. The default username is `user` and the default password is `password`. We recommand you to change it : + +```shell +echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g +``` + +And modify line with your new value: + +```yaml + - "traefik.http.middlewares.test-auth.basicauth.users=user:$$2y$$05$$m2rFNkFDITSrY7oawkzjU.dV.69/w8FmvEaSeBFCtmYpvMar9UMGa" +``` + +If you want to learn more about traefik auth [here](https://doc.traefik.io/traefik/operations/dashboard/#secure-mode) + ### Find your API key Your API Key can be found directly in the UI: diff --git a/docker-compose.new.yml b/docker-compose.new.yml index 302baecc6..d6e3db30e 100644 --- a/docker-compose.new.yml +++ b/docker-compose.new.yml @@ -55,12 +55,7 @@ services: container_name: traefik restart: unless-stopped command: - # WARNING: It is strongly discouraged to use Traefik with "--api.insecure=true" - # as this exposes the Traefik dashboard publicly without any security measures, - # which can lead to unauthorized access and potential security risks. - # For a production setup, consider enabling secure access to the dashboard - # by using authentication and restricting access to trusted IPs or networks. - - "--api.insecure=true" + - "--api.insecure=false" - "--api.dashboard=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" @@ -78,12 +73,18 @@ services: - traefik_certificates:/letsencrypt - traefik_config:/traefik labels: - - "traefik.http.routers.traefik.rule=Host(`${LAGO_DOMAIN:-localhost}`)" - # SSL - # - "traefik.http.routers.api.entrypoints=websecure" - - "traefik.http.routers.traefik.entrypoints=web" - - "traefik.http.routers.traefik.tls.certresolver=lagoresolver" + - "traefik.enable=true" + - "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.${LAGO_DOMAIN:-localhost}`)" + - "traefik.http.routers.traefik-dashboard.entrypoints=web" + - "traefik.http.routers.traefik-dashboard.service=api@internal" - "traefik.http.services.traefik.loadbalancer.server.port=8080" + - "traefik.http.routers.traefik-dashboard.middlewares=test-auth" + # username : user + # password : password + # you can change it using echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g + - "traefik.http.middlewares.test-auth.basicauth.users=user:$$2y$$05$$m2rFNkFDITSrY7oawkzjU.dV.69/w8FmvEaSeBFCtmYpvMar9UMGa" + + api: container_name: lago-api From d65e2204ff5c860f1c61a2c1c9b935adede17262 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Mon, 4 Nov 2024 20:26:01 +0100 Subject: [PATCH 25/27] docs: add documentation for Traefik SSL --- docker-compose.new.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.new.yml b/docker-compose.new.yml index d6e3db30e..1abba5ab4 100644 --- a/docker-compose.new.yml +++ b/docker-compose.new.yml @@ -75,6 +75,9 @@ services: labels: - "traefik.enable=true" - "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.${LAGO_DOMAIN:-localhost}`)" + # SSL + # - "traefik.http.routers.api.tls.certresolver=lagoresolver" + # - "traefik.http.routers.api.entrypoints=websecure" - "traefik.http.routers.traefik-dashboard.entrypoints=web" - "traefik.http.routers.traefik-dashboard.service=api@internal" - "traefik.http.services.traefik.loadbalancer.server.port=8080" From c3dbb25e49e0743e9ab098d039f12e04b8a80aa7 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Mon, 4 Nov 2024 21:36:39 +0100 Subject: [PATCH 26/27] refactor(docker-compose): update Traefik labels and LAGO_FRONT_URL config --- docker-compose.new.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docker-compose.new.yml b/docker-compose.new.yml index 1abba5ab4..2cac76d76 100644 --- a/docker-compose.new.yml +++ b/docker-compose.new.yml @@ -7,12 +7,12 @@ volumes: x-backend-x: &backend-environment LAGO_API_URL: ${LAGO_API_URL:-http://localhost/api} + LAGO_FRONT_URL: ${LAGO_FRONT_URL:-http://localhost} REDIS_PASSWORD: ${REDIS_PASSWORD:-changeme} SECRET_KEY_BASE: ${SECRET_KEY_BASE:-your-secret-key-base-hex-64} RAILS_ENV: ${RAILS_ENV:-production} RAILS_LOG_TO_STDOUT: ${LAGO_RAILS_STDOUT:-true} SENTRY_DSN: ${SENTRY_DSN:-} - LAGO_FRONT_URL: ${LAGO_FRONT_URL:-http://localhost} LAGO_RSA_PRIVATE_KEY: ${LAGO_RSA_PRIVATE_KEY} LAGO_ENCRYPTION_PRIMARY_KEY: ${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key} LAGO_ENCRYPTION_DETERMINISTIC_KEY: ${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key} @@ -76,16 +76,17 @@ services: - "traefik.enable=true" - "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.${LAGO_DOMAIN:-localhost}`)" # SSL - # - "traefik.http.routers.api.tls.certresolver=lagoresolver" - # - "traefik.http.routers.api.entrypoints=websecure" + #- "traefik.http.routers.traefik-dashboard.tls.certresolver=lagoresolver" + #- "traefik.http.routers.traefik-dashboard.tls=true" + #- "traefik.http.routers.traefik-dashboard.entrypoints=websecure" - "traefik.http.routers.traefik-dashboard.entrypoints=web" - "traefik.http.routers.traefik-dashboard.service=api@internal" - "traefik.http.services.traefik.loadbalancer.server.port=8080" - - "traefik.http.routers.traefik-dashboard.middlewares=test-auth" + - "traefik.http.routers.traefik-dashboard.middlewares=auth" # username : user # password : password # you can change it using echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g - - "traefik.http.middlewares.test-auth.basicauth.users=user:$$2y$$05$$m2rFNkFDITSrY7oawkzjU.dV.69/w8FmvEaSeBFCtmYpvMar9UMGa" + - "traefik.http.middlewares.auth.basicauth.users=user:$$2y$$05$$m2rFNkFDITSrY7oawkzjU.dV.69/w8FmvEaSeBFCtmYpvMar9UMGa" @@ -112,6 +113,7 @@ services: retries: 5 labels: # SSL + # - "traefik.http.routers.api.tls=true" # - "traefik.http.routers.api.tls.certresolver=lagoresolver" # - "traefik.http.routers.api.entrypoints=websecure" - "traefik.http.routers.api.entrypoints=web" @@ -142,8 +144,9 @@ services: - "traefik.http.routers.front.priority=50" - "traefik.enable=true" # SSL - # - "traefik.http.routers.api.tls.certresolver=lagoresolver" - # - "traefik.http.routers.api.entrypoints=websecure" + # - "traefik.http.routers.front.tls=true" + # - "traefik.http.routers.front.tls.certresolver=lagoresolver" + # - "traefik.http.routers.front.entrypoints=websecure" - "traefik.http.routers.front.entrypoints=web" - "traefik.http.routers.front.rule=Host(`${LAGO_DOMAIN:-localhost}`) && PathPrefix(`/`)" - "traefik.http.services.front.loadbalancer.server.port=80" From 8d985ab93d6048f0e484b581d94444e60489f39b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste DONNETTE Date: Thu, 7 Nov 2024 09:46:36 +0100 Subject: [PATCH 27/27] fix(compose): fixing /api path to not match api-keysxxxxx.js --- docker-compose.new.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.new.yml b/docker-compose.new.yml index 2cac76d76..3e150acd5 100644 --- a/docker-compose.new.yml +++ b/docker-compose.new.yml @@ -119,9 +119,9 @@ services: - "traefik.http.routers.api.entrypoints=web" - "traefik.http.routers.api.priority=100" - "traefik.enable=true" - - "traefik.http.routers.api.rule=Host(`${LAGO_DOMAIN:-localhost}`) && PathPrefix(`/api`)" + - "traefik.http.routers.api.rule=Host(`${LAGO_DOMAIN:-localhost}`) && PathPrefix(`/api/`)" - "traefik.http.services.api.loadbalancer.server.port=3000" - - "traefik.http.middlewares.api-strip-prefix.stripprefix.prefixes=/api" + - "traefik.http.middlewares.api-strip-prefix.stripprefix.prefixes=/api/" - "traefik.http.routers.api.middlewares=api-strip-prefix" volumes: - lago_storage_data:/app/storage