diff --git a/.travis.yml b/.travis.yml index 055ef08..a6e4034 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ language: python python: "2.7" sudo: false +before_install: + # required for xmlsec python package + - sudo apt-get -y install libxmlsec1-dev install: - pip install --upgrade pip - pip install -r requirements.txt diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..509f790 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM sentry:9.1.2-onbuild + +RUN groupadd -r dokku && useradd -r -m -u 32768 -g dokku dokku +USER dokku diff --git a/app.json b/app.json index e5cba67..ea3c7ec 100644 --- a/app.json +++ b/app.json @@ -7,46 +7,10 @@ "logging", "error" ], - "addons": [ - "heroku-postgresql:hobby-dev", - "heroku-redis:premium-0", - "sendgrid:starter" - ], - "env": { - "SECRET_KEY": { - "description": "A secret key for a particular Django installation. This is used to provide cryptographic signing, and should be set to a unique, unpredictable value.", - "generator": "secret" - }, - "SENTRY_URL_PREFIX": { - "description": "Your applications URL, no trailing slash", - "value": "https://YOURAPPNAME.herokuapp.com" - }, - "SERVER_EMAIL": { - "description": "Reply to address for outgoing email", - "value": "root@localhost" - }, - "SENTRY_ADMIN_EMAIL": { - "description": "The administrative email for this installation. Note: This will be reported back to getsentry.com as the point of contact. See the beacon documentation for more information.", - "value": "", - "required": false - }, - "AWS_ACCESS_KEY_ID": { - "description": "Your Amazon Web Services access key", - "value": "", - "required": false - }, - "AWS_SECRET_ACCESS_KEY": { - "description": "Your Amazon Web Services secret access key", - "value": "", - "required": false - }, - "AWS_STORAGE_BUCKET_NAME": { - "description": "Your Amazon Web Services storage bucket name", - "value": "", - "required": false - } - }, + "env": {}, "scripts": { - "postdeploy": "sentry --config=sentry.conf.py upgrade --noinput" + "dokku": { + "postdeploy": "sentry --config=sentry.conf.py upgrade --noinput" + } } } diff --git a/config.yml b/config.yml new file mode 100644 index 0000000..8a08445 --- /dev/null +++ b/config.yml @@ -0,0 +1,63 @@ +# While a lot of configuration in Sentry can be changed via the UI, for all +# 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 + +################ +# File storage # +################ + +# Uploaded media uses these `filestore` settings. The available +# backends are either `filesystem` or `s3`. + +# filestore.backend: 'filesystem' +# filestore.options: +# location: '/tmp/sentry-files' + +# filestore.backend: 's3' +# filestore.options: +# access_key: 'AKIXXXXXX' +# secret_key: 'XXXXXXX' +# bucket_name: 's3-bucket-name' diff --git a/requirements.in b/requirements.in deleted file mode 100644 index 5b3c527..0000000 --- a/requirements.in +++ /dev/null @@ -1,14 +0,0 @@ -boto -dj-database-url -django-bcrypt -django-secure -django-storages -ndg-httpsclient # required by requests -psycopg2 -dj-database-url -redis-py-cluster==1.3.4 -cryptography==1.9 -uwsgi==2.0.17.1 -sentry==9.0.0 --e git://github.com/getsentry/sentry-auth-google.git@578432dfeb7b16a681b4aeddbefd3cd2dbf5759f#egg=sentry-auth-google -sentry-github diff --git a/requirements.txt b/requirements.txt index 3e49abb..2f3e4fd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,107 +1,23 @@ -# -# This file is autogenerated by pip-compile -# To update, run: -# -# pip-compile --output-file requirements.txt requirements.in -# --e git+git://github.com/getsentry/sentry-auth-google.git@578432dfeb7b16a681b4aeddbefd3cd2dbf5759f#egg=sentry-auth-google -amqp==1.4.9 # via kombu -anyjson==0.3.3 # via kombu -asn1crypto==0.24.0 # via cryptography -attrs==18.1.0 # via pytest -beautifulsoup==3.2.1 # via sentry -billiard==3.3.0.23 # via celery -boto3==1.4.4 # via sentry -boto==2.43.0 -botocore==1.5.70 # via boto3, s3transfer, sentry -celery==3.1.18 # via sentry -certifi==2018.8.24 # via requests -cffi==1.8.3 # via cryptography, milksnake -chardet==3.0.4 # via requests -click==6.6 # via sentry -contextlib2==0.5.4 # via raven -cryptography==1.9 -cssselect==1.0.0 # via toronado -cssutils==0.9.10 # via sentry, toronado -dj-database-url==0.4.1 -django-bcrypt==0.9.2 -django-crispy-forms==1.4.0 # via sentry -django-jsonfield==0.9.13 # via sentry -django-picklefield==0.3.2 # via sentry -django-secure==1.0.1 -django-storages==1.5.1 -django-sudo==2.1.0 # via sentry -django-templatetag-sugar==1.0 # via sentry -django==1.6.11 # via django-secure, sentry -djangorestframework==2.4.8 # via sentry -docutils==0.13.1 # via botocore -email-reply-parser==0.2.0 # via sentry -enum34==1.1.6 # via cryptography, python-u2flib-server, sentry -exam==0.10.6 # via sentry -funcsigs==1.0.2 # via mock, pytest -functools32==3.2.3.post2 # via jsonschema, sentry -futures==3.2.0 # via s3transfer, sentry -hiredis==0.1.6 # via sentry -honcho==1.0.1 # via sentry -httplib2==0.9.2 # via oauth2 -idna==2.6 # via cryptography, requests -ipaddress==1.0.17 # via cryptography, sentry -jmespath==0.9.3 # via boto3, botocore -jsonschema==2.6.0 # via sentry -kombu==3.0.35 # via celery, sentry -loremipsum==1.0.5 # via sentry -lxml==3.6.4 # via sentry, toronado -milksnake==0.1.5 # via semaphore, symbolic -mmh3==2.3.1 # via sentry -mock==2.0.0 # via exam, sentry -more-itertools==4.3.0 # via pytest -ndg-httpsclient==0.4.2 -oauth2==1.9.0.post1 # via sentry -parsimonious==0.8.0 # via sentry -pbr==4.2.0 # via mock -percy==1.3.0 # via sentry -petname==2.0 # via sentry -pillow==3.2.0 # via sentry -pluggy==0.6.0 # via pytest -progressbar2==3.10.1 # via sentry -psycopg2==2.7.1 -py-bcrypt==0.4 # via django-bcrypt -py==1.6.0 # via pytest -pycparser==2.16 # via cffi -pyjwt==1.5.3 # via sentry -pyopenssl==16.2.0 # via ndg-httpsclient, requests -pytest-django==2.9.1 # via sentry -pytest-html==1.9.0 # via sentry -pytest==3.5.1 # via pytest-django, pytest-html, sentry -python-dateutil==2.5.3 # via botocore, sentry -python-memcached==1.58 # via sentry -python-openid==2.2.5 # via sentry -python-u2flib-server==4.0.1 # via sentry -python-utils==2.0.0 # via progressbar2 -pytz==2016.7 # via celery -pyyaml==3.11 # via sentry -qrcode==5.3 # via sentry -querystring-parser==1.2.3 # via sentry -raven==6.4.0 # via sentry -rb==1.7 # via sentry +uwsgi==2.0.18 + +boto +dj-database-url +django-bcrypt +django-secure +django-storages +ndg-httpsclient # required by requests + +# https://github.com/getsentry/sentry/blob/9.0.0/requirements-base.txt#L36 +# and https://github.com/psycopg/psycopg2-wheels/issues/2 +psycopg2-binary>=2.8.3,<2.9.0 + +dj-database-url redis-py-cluster==1.3.4 -redis==2.10.5 # via rb, redis-py-cluster, sentry -requests[security]==2.18.4 # via percy, querystring-parser, sentry -s3transfer==0.1.10 # via boto3 -selenium==3.11.0 # via sentry -semaphore==0.1.3 # via sentry -sentry-github==0.1.2 -sentry==9.0.0 -setproctitle==1.1.10 # via sentry -simplejson==3.8.2 # via sentry -six==1.10.0 # via cryptography, mock, more-itertools, parsimonious, pyopenssl, pytest, python-dateutil, python-memcached, python-utils, qrcode, sentry, structlog -sqlparse==0.1.19 # via sentry -statsd==3.1 # via sentry -strict-rfc3339==0.7 # via sentry -structlog==16.1.0 # via sentry -symbolic==5.1.2 # via sentry -toronado==0.0.11 # via sentry -ua-parser==0.7.1 # via sentry -unidiff==0.5.5 # via sentry -urllib3==1.22 # via requests, sentry -uwsgi==2.0.17.1 + +# 2.4.2 is needed to resolve "conflicting types for ‘BIO_callback_ctrl’" with herokuish-18 +# see https://github.com/apache/incubator-superset/issues/4870#issuecomment-444189653 +cryptography==2.4.2 +django-environ==0.4.5 + +sentry-plugins==9.1.0 +sentry-auth-google diff --git a/sentry.conf.py b/sentry.conf.py index c68b28f..0fbd449 100644 --- a/sentry.conf.py +++ b/sentry.conf.py @@ -47,6 +47,21 @@ # } # A primary cache is required for things such as processing events + +redis_url = urlparse(os.environ['REDIS_URL']) +SENTRY_OPTIONS['redis.clusters'] = { + 'default': { + 'hosts': { + 0: { + 'host': redis_url.hostname, + 'port': redis_url.port, + 'password': redis_url.password, + 'db': 0, + } + } + } +} + SENTRY_CACHE = 'sentry.cache.redis.RedisCache' ######### @@ -105,6 +120,22 @@ SENTRY_DIGESTS = 'sentry.digests.backends.redis.RedisBackend' +################ +# File storage # +################ + +# Uploaded media uses these `filestore` settings. The available +# backends are either `filesystem` or `s3`. + +SENTRY_OPTIONS['filestore.backend'] = 's3' +SENTRY_OPTIONS['filestore.options'] = { + 'access_key': os.environ.get('AWS_ACCESS_KEY_ID'), + 'secret_key': os.environ.get('AWS_SECRET_ACCESS_KEY'), + 'bucket_name': os.environ.get('AWS_STORAGE_BUCKET_NAME'), + 'signature_version': 's3v4' +} +AWS_DEFAULT_ACL = 'private' + ############## # Web Server # ############## @@ -120,7 +151,7 @@ # FORCE_SCRIPT_NAME = '/sentry' SENTRY_WEB_HOST = '0.0.0.0' -SENTRY_WEB_PORT = int(os.environ.get('PORT', '3000')) +SENTRY_WEB_PORT = int(os.environ.get('PORT', '9000')) SENTRY_WEB_OPTIONS = { 'secure_scheme_headers': {'X-FORWARDED-PROTO': 'https'}, 'worker_class': 'gevent', @@ -128,34 +159,9 @@ # 'protocol': 'uwsgi', # Enable uwsgi protocol instead of http } -################## -# Sentry Options # -################## -SENTRY_OPTIONS['system.secret-key'] = os.environ['SECRET_KEY'] -SENTRY_OPTIONS['system.url-prefix'] = os.environ['SENTRY_URL_PREFIX'] -SENTRY_OPTIONS['system.admin-email'] = os.environ.get('SENTRY_ADMIN_EMAIL', '') -SENTRY_OPTIONS['filestore.backend'] = 's3' -SENTRY_OPTIONS['filestore.options'] = { - 'access_key': os.environ.get('AWS_ACCESS_KEY_ID'), - 'secret_key': os.environ.get('AWS_SECRET_ACCESS_KEY'), - 'bucket_name': os.environ.get('AWS_STORAGE_BUCKET_NAME'), - 'signature_version': 's3v4' -} -AWS_DEFAULT_ACL = 'private' - -redis_url = urlparse(os.environ['REDIS_URL']) -SENTRY_OPTIONS['redis.clusters'] = { - 'default': { - 'hosts': { - 0: { - 'host': redis_url.hostname, - 'port': redis_url.port, - 'password': redis_url.password, - 'db': 0, - } - } - } -} +############### +# Mail Server # +############### SENTRY_OPTIONS['mail.backend'] = 'django.core.mail.backends.smtp.EmailBackend' if 'MAILJET_HOST' in os.environ: @@ -172,6 +178,13 @@ # route to forward to /api/hooks/mailgun/inbound/ SENTRY_OPTIONS['mail.mailgun-api-key'] = os.environ.get('MAILGUN_API_KEY', '') +################## +# Sentry Options # +################## +SENTRY_OPTIONS['system.secret-key'] = os.environ['SECRET_KEY'] +SENTRY_OPTIONS['system.url-prefix'] = os.environ['SENTRY_URL_PREFIX'] +SENTRY_OPTIONS['system.admin-email'] = os.environ.get('SENTRY_ADMIN_EMAIL', '') + ################### # Sentry Features # ################### diff --git a/uwsgi.ini b/uwsgi.ini index 964ce1b..9a570e6 100644 --- a/uwsgi.ini +++ b/uwsgi.ini @@ -22,3 +22,6 @@ enable-threads = true single-interpreter = true lazy-apps = true log-x-forwarded-for = true + +; Run nightly cron +cron = 0 3 -1 -1 -1 sentry cleanup --days=90