diff --git a/Dockerfile b/Dockerfile index 66b1367..75d58d8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1 +1 @@ -FROM sentry:onbuild +FROM sentry:8.4-onbuild diff --git a/config.yml b/config.yml index 2606666..433b9dc 100644 --- a/config.yml +++ b/config.yml @@ -2,3 +2,45 @@ # new-style config (as of 8.0) you can also declare values here in this file # to enforce defaults or to ensure they cannot be changed via the UI. For more # information see the Sentry documentation. + +############### +# Mail Server # +############### + +# mail.backend: 'smtp' # Use dummy if you want to disable email entirely +# mail.host: 'localhost' +# mail.port: 25 +# mail.username: '' +# mail.password: '' +# mail.use-tls: false +# The email address to send on behalf of +# mail.from: 'root@localhost' + +# If you'd like to configure email replies, enable this. +# mail.enable-replies: false + +# When email-replies are enabled, this value is used in the Reply-To header +# mail.reply-hostname: '' + +# If you're using mailgun for inbound mail, set your API key and configure a +# route to forward to /api/hooks/mailgun/inbound/ +# mail.mailgun-api-key: '' + +################### +# System Settings # +################### + +# If this file ever becomes compromised, it's important to regenerate your a new key +# Changing this value will result in all current sessions being invalidated. +# A new key can be generated with `$ sentry config generate-secret-key` +# system.secret-key: 'changeme' + +# The ``redis.clusters`` setting is used, unsurprisingly, to configure Redis +# clusters. These clusters can be then referred to by name when configuring +# backends such as the cache, digests, or TSDB backend. +# redis.clusters: +# default: +# hosts: +# 0: +# host: 127.0.0.1 +# port: 6379 diff --git a/sentry.conf.py b/sentry.conf.py index 33a787f..b9f5e21 100644 --- a/sentry.conf.py +++ b/sentry.conf.py @@ -7,6 +7,10 @@ # SENTRY_DB_NAME # SENTRY_DB_USER # SENTRY_DB_PASSWORD +# SENTRY_RABBITMQ_HOST +# SENTRY_RABBITMQ_USERNAME +# SENTRY_RABBITMQ_PASSWORD +# SENTRY_RABBITMQ_VHOST # SENTRY_REDIS_HOST # SENTRY_REDIS_PORT # SENTRY_REDIS_DB @@ -19,6 +23,8 @@ # SENTRY_EMAIL_USER # SENTRY_EMAIL_PASSWORD # SENTRY_EMAIL_USE_TLS +# SENTRY_ENABLE_EMAIL_REPLIES +# SENTRY_SMTP_HOSTNAME # SENTRY_MAILGUN_API_KEY # SENTRY_SINGLE_ORGANIZATION # SENTRY_SECRET_KEY @@ -29,30 +35,31 @@ import os import os.path CONF_ROOT = os.path.dirname(__file__) +env = os.environ.get -postgres = os.environ.get('SENTRY_POSTGRES_HOST') or (os.environ.get('POSTGRES_PORT_5432_TCP_ADDR') and 'postgres') +postgres = env('SENTRY_POSTGRES_HOST') or (env('POSTGRES_PORT_5432_TCP_ADDR') and 'postgres') if postgres: DATABASES = { 'default': { 'ENGINE': 'sentry.db.postgres', 'NAME': ( - os.environ.get('SENTRY_DB_NAME') - or os.environ.get('POSTGRES_ENV_POSTGRES_USER') + env('SENTRY_DB_NAME') + or env('POSTGRES_ENV_POSTGRES_USER') or 'postgres' ), 'USER': ( - os.environ.get('SENTRY_DB_USER') - or os.environ.get('POSTGRES_ENV_POSTGRES_USER') + env('SENTRY_DB_USER') + or env('POSTGRES_ENV_POSTGRES_USER') or 'postgres' ), 'PASSWORD': ( - os.environ.get('SENTRY_DB_PASSWORD') - or os.environ.get('POSTGRES_ENV_POSTGRES_PASSWORD') + env('SENTRY_DB_PASSWORD') + or env('POSTGRES_ENV_POSTGRES_PASSWORD') or '' ), 'HOST': postgres, 'PORT': ( - os.environ.get('SENTRY_POSTGRES_PORT') + env('SENTRY_POSTGRES_PORT') or '' ), 'OPTIONS': { @@ -74,7 +81,7 @@ SENTRY_USE_BIG_INTS = True # Instruct Sentry that this install intends to be run by a single organization # and thus various UI optimizations should be enabled. -SENTRY_SINGLE_ORGANIZATION = Bool(os.environ.get('SENTRY_SINGLE_ORGANIZATION', True)) +SENTRY_SINGLE_ORGANIZATION = Bool(env('SENTRY_SINGLE_ORGANIZATION', True)) ######### # Redis # @@ -83,22 +90,26 @@ SENTRY_SINGLE_ORGANIZATION = Bool(os.environ.get('SENTRY_SINGLE_ORGANIZATION', T # Generic Redis configuration used as defaults for various things including: # Buffers, Quotas, TSDB -redis = os.environ.get('SENTRY_REDIS_HOST') or (os.environ.get('REDIS_PORT_6379_TCP_ADDR') and 'redis') +redis = env('SENTRY_REDIS_HOST') or (env('REDIS_PORT_6379_TCP_ADDR') and 'redis') if not redis: raise Exception('Error: REDIS_PORT_6379_TCP_ADDR (or SENTRY_REDIS_HOST) is undefined, did you forget to `--link` a redis container?') -redis_port = os.environ.get('SENTRY_REDIS_PORT') or '6379' -redis_db = os.environ.get('SENTRY_REDIS_DB') or '0' +redis_port = env('SENTRY_REDIS_PORT') or '6379' +redis_db = env('SENTRY_REDIS_DB') or '0' -SENTRY_REDIS_OPTIONS = { - 'hosts': { - 0: { - 'host': redis, - 'port': redis_port, - 'db': redis_db, +SENTRY_OPTIONS.update({ + 'redis.clusters': { + 'default': { + 'hosts': { + 0: { + 'host': redis, + 'port': redis_port, + 'db': redis_db, + }, + }, }, }, -} +}) ######### # Cache # @@ -107,10 +118,10 @@ SENTRY_REDIS_OPTIONS = { # Sentry currently utilizes two separate mechanisms. While CACHES is not a # requirement, it will optimize several high throughput patterns. -memcached = os.environ.get('SENTRY_MEMCACHED_HOST') or (os.environ.get('MEMCACHED_PORT_11211_TCP_ADDR') and 'memcached') +memcached = env('SENTRY_MEMCACHED_HOST') or (env('MEMCACHED_PORT_11211_TCP_ADDR') and 'memcached') if memcached: memcached_port = ( - os.environ.get('SENTRY_MEMCACHED_PORT') + env('SENTRY_MEMCACHED_PORT') or '11211' ) CACHES = { @@ -123,7 +134,6 @@ if memcached: # A primary cache is required for things such as processing events SENTRY_CACHE = 'sentry.cache.redis.RedisCache' -SENTRY_CACHE_OPTIONS = SENTRY_REDIS_OPTIONS ######### # Queue # @@ -133,8 +143,27 @@ SENTRY_CACHE_OPTIONS = SENTRY_REDIS_OPTIONS # information on configuring your queue broker and workers. Sentry relies # on a Python framework called Celery to manage queues. -CELERY_ALWAYS_EAGER = False -BROKER_URL = 'redis://' + redis + ':' + redis_port + '/' + redis_db +rabbitmq = env('SENTRY_RABBITMQ_HOST') or (env('RABBITMQ_PORT_5672_TCP_ADDR') and 'rabbitmq') + +if rabbitmq: + BROKER_URL = ( + 'amqp://' + ( + env('SENTRY_RABBITMQ_USERNAME') + or env('RABBITMQ_ENV_RABBITMQ_DEFAULT_USER') + or 'guest' + ) + ':' + ( + env('SENTRY_RABBITMQ_PASSWORD') + or env('RABBITMQ_ENV_RABBITMQ_DEFAULT_PASS') + or 'guest' + ) + '@' + rabbitmq + '/' + ( + env('SENTRY_RABBITMQ_VHOST') + or env('RABBITMQ_ENV_RABBITMQ_DEFAULT_VHOST') + or '/' + ) + ) +else: + BROKER_URL = 'redis://' + redis + ':' + redis_port + '/' + redis_db + ############### # Rate Limits # @@ -191,7 +220,7 @@ SENTRY_DIGESTS = 'sentry.digests.backends.redis.RedisBackend' SENTRY_FILESTORE = 'django.core.files.storage.FileSystemStorage' SENTRY_FILESTORE_OPTIONS = { - 'location': os.environ['SENTRY_FILESTORE_DIR'], + 'location': env('SENTRY_FILESTORE_DIR'), } ############## @@ -201,7 +230,7 @@ SENTRY_FILESTORE_OPTIONS = { # If you're using a reverse SSL proxy, you should enable the X-Forwarded-Proto # header and set `SENTRY_USE_SSL=1` -if Bool(os.environ.get('SENTRY_USE_SSL', False)): +if Bool(env('SENTRY_USE_SSL', False)): SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True @@ -216,38 +245,47 @@ SENTRY_WEB_OPTIONS = { # Mail Server # ############### -# For more information check Django's documentation: -# https://docs.djangoproject.com/en/1.6/topics/email/ -email = os.environ.get('SENTRY_EMAIL_HOST') or (os.environ.get('SMTP_PORT_25_TCP_ADDR') and 'smtp') +email = env('SENTRY_EMAIL_HOST') or (env('SMTP_PORT_25_TCP_ADDR') and 'smtp') if email: - EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' - EMAIL_HOST = email - EMAIL_HOST_PASSWORD = os.environ.get('SENTRY_EMAIL_PASSWORD') or '' - EMAIL_HOST_USER = os.environ.get('SENTRY_EMAIL_USER') or '' - EMAIL_PORT = int(os.environ.get('SENTRY_EMAIL_PORT') or 25) - EMAIL_USE_TLS = Bool(os.environ.get('SENTRY_EMAIL_USE_TLS', False)) + SENTRY_OPTIONS['mail.backend'] = 'smtp' + SENTRY_OPTIONS['mail.host'] = email + SENTRY_OPTIONS['mail.password'] = env('SENTRY_EMAIL_PASSWORD') or '' + SENTRY_OPTIONS['mail.username'] = env('SENTRY_EMAIL_USER') or '' + SENTRY_OPTIONS['mail.port'] = int(env('SENTRY_EMAIL_PORT') or 25) + SENTRY_OPTIONS['mail.use-tls'] = Bool(env('SENTRY_EMAIL_USE_TLS', False)) else: - EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend' + SENTRY_OPTIONS['mail.backend'] = 'dummy' # The email address to send on behalf of -SERVER_EMAIL = os.environ.get('SENTRY_SERVER_EMAIL') or 'root@localhost' +SENTRY_OPTIONS['mail.from'] = env('SENTRY_SERVER_EMAIL') or 'root@localhost' # If you're using mailgun for inbound mail, set your API key and configure a # route to forward to /api/hooks/mailgun/inbound/ -MAILGUN_API_KEY = os.environ.get('SENTRY_MAILGUN_API_KEY') or '' +SENTRY_OPTIONS['mail.mailgun-api-key'] = env('SENTRY_MAILGUN_API_KEY') or '' + +# If you specify a MAILGUN_API_KEY, you definitely want EMAIL_REPLIES +if SENTRY_OPTIONS['mail.mailgun-api-key']: + SENTRY_OPTIONS['mail.enable-replies'] = True +else: + SENTRY_OPTIONS['mail.enable-replies'] = Bool(env('SENTRY_ENABLE_EMAIL_REPLIES', False)) + +if SENTRY_OPTIONS['mail.enable-replies']: + SENTRY_OPTIONS['mail.reply-hostname'] = env('SENTRY_SMTP_HOSTNAME') or '' # If this value ever becomes compromised, it's important to regenerate your # SENTRY_SECRET_KEY. Changing this value will result in all current sessions # being invalidated. -SECRET_KEY = os.environ.get('SENTRY_SECRET_KEY') -if not SECRET_KEY: +secret_key = env('SENTRY_SECRET_KEY') +if not secret_key: raise Exception('Error: SENTRY_SECRET_KEY is undefined, run `generate-secret-key` and set to -e SENTRY_SECRET_KEY') -if len(SECRET_KEY) < 32: - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - print('!! CAUTION !!') - print('!! Your SECRET_KEY is potentially insecure. !!') - print('!! We recommend at least 32 characters long. !!') - print('!! Regenerate with `generate-secret-key`. !!') - print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') +if 'SENTRY_RUNNING_UWSGI' not in os.environ and len(secret_key) < 32: + print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + print('!! CAUTION !!') + print('!! Your SENTRY_SECRET_KEY is potentially insecure. !!') + print('!! We recommend at least 32 characters long. !!') + print('!! Regenerate with `generate-secret-key`. !!') + print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + +SENTRY_OPTIONS['system.secret-key'] = secret_key