From aefc440a2583a4d97a91fbb4890b93444548f241 Mon Sep 17 00:00:00 2001 From: neo773 Date: Fri, 13 Sep 2024 04:31:38 +0530 Subject: [PATCH] Add docker compose --- .env.sample | 282 ++++++++++++++++++++++++++++++++++++ .gitignore | 1 + docker-compose.yaml | 106 ++++++++++++++ lib/tasks/keygen/setup.rake | 8 +- 4 files changed, 392 insertions(+), 5 deletions(-) create mode 100644 .env.sample create mode 100644 docker-compose.yaml diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000000..6f750a88f2 --- /dev/null +++ b/.env.sample @@ -0,0 +1,282 @@ +# ------------------------------------------------------------------------------ +# Environment Variables +# Uncommented keys are mandatory. +# +# For more information, visit: https://keygen.sh/docs/self-hosting +# ------------------------------------------------------------------------------ + +# The username for the PostgreSQL database. +POSTGRES_USER= + +# The password for the PostgreSQL database. +POSTGRES_PASSWORD= + +# The name of the PostgreSQL database. +POSTGRES_DB= + +# The Redis database URL, e.g. redis://localhost:6379. +REDIS_URL= + +# An internal secret key used by Ruby on Rails. +# Use `rails secret` or `openssl rand -hex 64` to generate one. We recommend a random 64-byte secret. +SECRET_KEY_BASE= + +# The deterministic key used for at-work encryption. +# Use `rails db:encryption:init` or `openssl rand -base64 32` to generate one. We recommend a random 32-byte secret. No less than 12-bytes. +ENCRYPTION_DETERMINISTIC_KEY= + +# The primary key used for at-work encryption. +# Use `rails db:encryption:init` or `openssl rand -base64 32` to generate one. We recommend a random 32-byte secret. No less than 12-bytes. +ENCRYPTION_PRIMARY_KEY= + +# The key derivation salt used for at-work encryption. +# Use `rails db:encryption:init` or `openssl rand -base64 32` to generate one. We recommend a random 32-byte secret. No less than 20-bytes. +ENCRYPTION_KEY_DERIVATION_SALT= + +# The edition of Keygen to run: either CE for the Community Edition, or EE for the Enterprise Edition. +KEYGEN_EDITION=CE + +# The mode of Keygen: either singleplayer for single-tenant, or multiplayer for multi-tenant. +# Multiplayer mode requires a Keygen EE license with the multiplayer entitlement. +KEYGEN_MODE=singleplayer + +# The account ID used for setting the tenant of Keygen in singleplayer mode. +# Use `uuidgen` or `cat /proc/sys/kernel/random/uuid` to set a pre-determined ID. +# * Required in singleplayer mode. +KEYGEN_ACCOUNT_ID= + +# The admin email used during setup. Must be a valid email address for your organization. +KEYGEN_ADMIN_EMAIL= + +# The admin password used during setup. Must be at least 6 characters. +# Use `openssl rand -hex 16` to generate one. We recommend a random 16-byte secret. +KEYGEN_ADMIN_PASSWORD= + +# The primary host that Keygen's API will be accessible at, e.g. licensing.example.com. +KEYGEN_HOST= + +# Additional hosts that Keygen will be accessible at. +# Must be a comma-delimited list of hostnames, e.g. host1.example.com,host2.example.com. +# KEYGEN_HOSTS= + +# The path to a Keygen EE license file, e.g. /etc/keygen/ee.lic. +# * Either KEYGEN_LICENSE_FILE_PATH or KEYGEN_LICENSE_FILE are required in Keygen EE. +# KEYGEN_LICENSE_FILE_PATH= + +# A base64 encoded Keygen EE license file. This is useful when a file system is not available for KEYGEN_LICENSE_FILE_PATH, e.g. with Heroku. +# * Either KEYGEN_LICENSE_FILE_PATH or KEYGEN_LICENSE_FILE are required in Keygen EE. +# KEYGEN_LICENSE_FILE= + +# The license key used to decrypt the Keygen EE license file. +# * Required in Keygen EE. +# KEYGEN_LICENSE_KEY= + +# The primary domain Keygen's API will be accessible at. By default, this is parsed from KEYGEN_HOST, but that may result in inaccuracies under certain TLDs, e.g. co.uk. +# KEYGEN_DOMAIN= + +# The primary subdomain Keygen's API will be accessible at. By default, parsed from KEYGEN_HOST, but that may result in inaccuracies under multiple subdomains. +# KEYGEN_SUBDOMAIN= + +# The number of days that high-volume event logs are kept before being pruned. +# Set to -1 to disable pruning. +# KEYGEN_PRUNE_EVENT_BACKLOG_DAYS=90 + +# The number of days that request logs are kept before being pruned. +# Set to -1 to disable pruning. +# KEYGEN_PRUNE_REQUEST_BACKLOG_DAYS=30 + +# The number of days that webhook events are kept before being pruned. +# Set to -1 to disable pruning. +# KEYGEN_PRUNE_WEBHOOK_BACKLOG_DAYS=30 + +# The number of rows pruned per-batch during pruning. +# KEYGEN_PRUNE_BATCH_SIZE=10000 + +# The amount of time, in seconds, to wait in between batches during pruning. +# KEYGEN_PRUNE_BATCH_WAIT=1 + +# The port on which the server is available. +# PORT=3000 + +# The IP address on which the server is listening. +# E.g. 0.0.0.0 = all interfaces, 127.0.0.1 = localhost. +# BIND=0.0.0.0 + +# The Postgres database URL, e.g. postgres://postgres:postgres@localhost:5432. +# DATABASE_URL= + +# The number of database connections Keygen will use per-process. +# By default, this will equal RAILS_MAX_THREADS or SIDEKIQ_CONCURRENCY, determined by web vs worker process, respectively (i.e. each thread will have its own database connection). +# Because of this default, most applications do not need to set this. But it's there if you need to override the default behavior for some reason. +# DB_POOL= + +# The database query timeout, in ms. +# DB_TIMEOUT=5000 + +# The name of the environment variable pointing to Sidekiq's Redis. +# Set if you want to use an isolated Redis database for background jobs. +# This should be the name of an environment variable, not a Redis URL. +# REDIS_PROVIDER=REDIS_URL + +# The number of Redis connections Keygen will use per-process. +# By default, this will equal RAILS_MAX_THREADS or SIDEKIQ_CONCURRENCY, determined by web vs worker process, respectively (i.e. each thread will have its own database connection). +# Because of this default, most applications do not need to set this. But it's there if you need to override the default behavior for some reason. +# REDIS_POOL_SIZE= + +# The Redis pool timeout, in seconds. +# REDIS_POOL_TIMEOUT=5 + +# The Redis connect timeout, in seconds. +# REDIS_CONNECT_TIMEOUT=5 + +# The Redis read timeout, in seconds. +# REDIS_READ_TIMEOUT=5 + +# The Redis write timeout, in seconds. +# REDIS_WRITE_TIMEOUT=5 + +# The number of reconnect attempts for failed connections to Redis. +# REDIS_RECONNECT_ATTEMPTS=5 + +# The Cloudflare R2 access key ID. +# * Without Cloudflare R2 or AWS S3, uploading and downloading release artifacts will fail. +# CF_ACCESS_KEY_ID= + +# The Cloudflare R2 secret access key. +# * Without Cloudflare R2 or AWS S3, uploading and downloading release artifacts will fail. +# CF_SECRET_ACCESS_KEY= + +# The Cloudflare R2 account ID. +# * Without Cloudflare R2 or AWS S3, uploading and downloading release artifacts will fail. +# CF_ACCOUNT_ID= + +# The Cloudflare R2 bucket to upload artifacts to. +# * Without Cloudflare R2 or AWS S3, uploading and downloading release artifacts will fail. +# CF_BUCKET= + +# The Cloudflare R2 region. +# * Without Cloudflare R2 or AWS S3, uploading and downloading release artifacts will fail. +# CF_REGION= + +# The AWS S3 access key ID. +# * Without Cloudflare R2 or AWS S3, uploading and downloading release artifacts will fail. +# AWS_ACCESS_KEY_ID= + +# The AWS S3 secret access key. +# * Without Cloudflare R2 or AWS S3, uploading and downloading release artifacts will fail. +# AWS_SECRET_ACCESS_KEY= + +# The AWS S3 bucket to upload artifacts to. +# * Without Cloudflare R2 or AWS S3, uploading and downloading release artifacts will fail. +# AWS_BUCKET= + +# The AWS S3 region. +# * Without Cloudflare R2 or AWS S3, uploading and downloading release artifacts will fail. +# AWS_REGION= + +# The environment for Ruby on Rails. +# RAILS_ENV=production + +# The log level for Ruby on Rails. +# RAILS_LOG_LEVEL=info + +# Set this environment variable to send all application logs to stdout. +# RAILS_LOG_TO_STDOUT=1 + +# The timeout for idle connections to Puma, in seconds. +# RAILS_KEEP_ALIVE_TIMEOUT=20 + +# The maximum number of threads per Puma worker. Each thread can handle a concurrent request, thus this controls concurrency. +# Generally, you should aim to be between 1 and 5 threads per-worker; anything else and you may begin trading throughput for latency due to Ruby's GIL. +# You SHOULD NOT exceed your available CPU core count. +# RAILS_MAX_THREADS=2 + +# The minimum number of threads per Puma worker. +# RAILS_MIN_THREADS=$RAILS_MAX_THREADS + +# Set this environment variable to serve assets from the public/ directory. +# RAILS_SERVE_STATIC_FILES= + +# Enable YJIT, a just-in-time compiler for Ruby. This will increase execution speed at the cost of memory. +# When memory allows, we recommend enabling YJIT. We've seen up to a 30% improvement in execution speed with YJIT, which equals more throughput. +# RUBY_YJIT_ENABLE= + +# Configure the MRI Ruby runtime. For example, you can add flags such as `--yjit-exec-mem-size=32` to adjust YJIT memory usage, or set `-W2` to adjust warning verbosity. +# RUBYOPT= + +# The number of Puma workers. Each worker is a separate process that runs an instance of Keygen. +# The higher the worker count, the higher the memory consumption. The more workers you have, the throughput (concurrency) you will you have. +# Generally, you should have as many workers as memory allows. For the average 512MB server, that may be 2; for a more beefy 14GB server, that may be 42. +# WEB_CONCURRENCY=2 + +# The number of Sidekiq workers. The more workers, the faster background jobs are processed. The higher the worker count, the higher the memory consumption. +# SIDEKIQ_CONCURRENCY=10 + +# The username for accessing the Sidekiq monitoring UI. +# SIDEKIQ_WEB_USER= + +# The password for accessing the Sidekiq monitoring UI. +# SIDEKIQ_WEB_PASSWORD= + +# Documentation for rack-timeout can be found here. +# RACK_TIMEOUT_SERVICE_TIMEOUT=15 + +# Documentation for rack-timeout can be found here. +# RACK_TIMEOUT_WAIT_TIMEOUT=30 + +# Documentation for rack-timeout can be found here. +# RACK_TIMEOUT_WAIT_OVERTIME=60 + +# Documentation for rack-timeout can be found here. +# RACK_TIMEOUT_SERVICE_PAST_WAIT=0 + +# Documentation for rack-timeout can be found here. +# RACK_TIMEOUT_TERM_ON_TIMEOUT=0 + +# Comma-delimited list of IP addresses or IP ranges that are whitelisted by the internal rate limiter. These IPs will never be rate limited. +# RACK_ATTACK_IP_WHITELIST= + +# Comma-delimited list of IP addresses or IP ranges that are blacklisted by the internal rate limiter. These IPs will always be blocked. +# RACK_ATTACK_IP_BLACKLIST= + +# The maximum number of requests per-second that a given IP address can make before being rate limited. Set to -1 to disable this rate limiter. +# RACK_ATTACK_MAX_RPS=-1 + +# The maximum number of requests per-minute that a given IP address can make before being rate limited. Set to -1 to disable this rate limiter. +# RACK_ATTACK_MAX_RPM=-1 + +# Set this environment variable to completely disable the rate limiter. +# NO_RACK_ATTACK= + +# Set this environment variable to disable Sentry. +# NO_SENTRY= + +# The DSN for Sentry, for error reporting and performance monitoring. +# SENTRY_DSN= + +# Trace sample rate for Sentry performance monitoring (APM). We recommend a value under 0.2, but it will ultimately depend on your production load. +# SENTRY_TRACES_SAMPLE_RATE=0.0 + +# Profile sample rate for Sentry performance monitoring (APM). We recommend a value of 0.1, but it will ultimately depend on your production load. +# SENTRY_PROFILES_SAMPLE_RATE=0.0 + +# The URL for Judoscale (Rails Autoscale), an autoscaler for Heroku, Render, and other PaaS providers. +# JUDOSCALE_URL= + +# Set this environment variable to disable Judoscale. +# NO_JUDOSCALE= + +# The API key for Cronitor, a background job monitor. +# CRONITOR_API_KEY= + +# Set this environment variable to disable Cronitor. +# NO_CRONITOR= + +# The API key for SendGrid, for sending transactional email. +# SENDGRID_API_KEY= + +# Set this environment variable to disable SendGrid. +# NO_SENDGRID= + +# A comma-delimited list of trusted proxy IP addresses. +# TRUSTED_PROXIES= diff --git a/.gitignore b/.gitignore index 8f8a59b0ba..e798a2d605 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ # Ignore environment files /.env* +!.env.sample # Ignore Redis/DB dumps /*.dump diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000000..6e0d5104c3 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,106 @@ +version: '3.8' +services: + setup: + profiles: [ "setup" ] + image: keygen/api:latest + environment: + DATABASE_URL: "postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}" + DISABLE_DATABASE_ENVIRONMENT_CHECK: 1 + env_file: + - .env + command: > + sh -c " + until pg_isready -h postgres -U ${POSTGRES_USER}; do + echo 'Waiting for PostgreSQL...' + sleep 1 + done + bundle exec rails keygen:setup + " + depends_on: [ postgres ] + tty: true + stdin_open: true + + postgres: + image: postgres:9.6 + ports: + - "5432:5432" + environment: + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: ${POSTGRES_DB} + volumes: + - postgres:/var/lib/postgresql/data + + redis: + image: redis + ports: + - "6379:6379" + volumes: + - redis:/data + + web: + image: keygen/api:latest + ports: + - "3000:3000" + networks: + - default + - web_network + command: "web" + env_file: + - .env + environment: + DATABASE_URL: "postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}" + volumes: + - keygen:/etc/keygen + depends_on: + - postgres + - redis + + worker: + image: keygen/api:latest + command: "worker" + env_file: + - .env + environment: + DATABASE_URL: "postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}" + volumes: + - keygen:/etc/keygen + depends_on: + - postgres + - redis + + caddy: + image: caddy:latest + restart: unless-stopped + ports: + - "80:80" + - "443:443" + volumes: + - caddy_data:/data + - caddy_config:/config + env_file: + - .env + command: > + sh -c ' + echo "${KEYGEN_HOST}$${KEYGEN_HOSTS:+,} $${KEYGEN_HOSTS//,/, } { + tls internal + reverse_proxy web:3000 + }" > /etc/caddy/Caddyfile && + caddy run --config /etc/caddy/Caddyfile + ' + depends_on: + - web + networks: + - default + - web_network + +networks: + web_network: + name: web_network + +volumes: + keygen: + postgres: + redis: + caddy_data: + caddy_config: diff --git a/lib/tasks/keygen/setup.rake b/lib/tasks/keygen/setup.rake index 22d0750082..b7e7687aa0 100644 --- a/lib/tasks/keygen/setup.rake +++ b/lib/tasks/keygen/setup.rake @@ -104,9 +104,9 @@ namespace :keygen do end puts <<~MSG - To complete setup, run the following in a shell, or add it to a shell profile: + To complete setup, add the following env vars in your shell or to .env: - #{config.reduce(+'') { |s, (k, v)| s << "export #{k}=#{v}\n " }.strip.chomp} + #{config.reduce(+'') { |s, (k, v)| s << "#{k}=#{v}\n " }.strip.chomp} MSG @@ -122,9 +122,7 @@ namespace :keygen do end puts <<~MSG - Then run the following to start the server: - - rails s + Then start the web and worker processes. *keygen music intensifies* MSG