diff --git a/.env b/.env index aebeca8..13a851c 100644 --- a/.env +++ b/.env @@ -1,12 +1,12 @@ -COMPOSE_PROJECT_NAME=sentry_onpremise +COMPOSE_PROJECT_NAME=sentry-self-hosted SENTRY_EVENT_RETENTION_DAYS=90 # You can either use a port number or an IP:PORT combo for SENTRY_BIND # See https://docs.docker.com/compose/compose-file/#ports for more SENTRY_BIND=9000 # Set SENTRY_MAIL_HOST to a valid FQDN (host/domain name) to be able to send emails! # SENTRY_MAIL_HOST=example.com -SENTRY_IMAGE=getsentry/sentry:21.11.0 -SNUBA_IMAGE=getsentry/snuba:21.11.0 -RELAY_IMAGE=getsentry/relay:21.11.0 +SENTRY_IMAGE=getsentry/sentry:21.12.0 +SNUBA_IMAGE=getsentry/snuba:21.12.0 +RELAY_IMAGE=getsentry/relay:21.12.0 SYMBOLICATOR_IMAGE=getsentry/symbolicator:0.4.0 WAL2JSON_VERSION=latest \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 22655b7..c58204a 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,5 @@ blank_issues_enabled: false contact_links: - - name: Question about self-hosting/on-premise - url: https://forum.sentry.io - about: Please use the community forums for questions - name: Report a security vulnerability url: https://sentry.io/security/#vulnerability-disclosure about: Please see our guide for responsible disclosure. diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature-request.yml similarity index 76% rename from .github/ISSUE_TEMPLATE/feature.yml rename to .github/ISSUE_TEMPLATE/feature-request.yml index 49cfa3e..3e5de4d 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -1,28 +1,28 @@ name: πŸ’‘ Feature Request description: Tell us about a problem our software could solve but doesn't. body: - type: textarea id: problem attributes: label: Problem Statement - description: What problem could `onpremise` solve that it doesn't? + description: What problem could `self-hosted` solve that it doesn't? placeholder: |- - I want to make whirled peas, but `onpremise` doesn't blend. + I want to make whirled peas, but `self-hosted` doesn't blend. validations: required: true - type: textarea id: expected attributes: label: Solution Brainstorm description: We know you have bright ideas to share ... share away, friend. placeholder: |- - Add a blender to `onpremise`. + Add a blender to `self-hosted`. validations: required: false - type: markdown attributes: value: |- - ## Thanks πŸ™ + ## Thanks Check our [triage docs](https://open.sentry.io/triage/) for what to expect next. validations: required: false diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/problem-report.yml similarity index 91% rename from .github/ISSUE_TEMPLATE/bug.yml rename to .github/ISSUE_TEMPLATE/problem-report.yml index b1ec358..a93151f 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/problem-report.yml @@ -1,46 +1,46 @@ -name: 🐞 Bug Report -description: Tell us about something that's not working the way we (probably) intend. +name: 🐞 Problem Report +description: Tell us about something that's not working the way you expect. body: - type: input id: version attributes: label: Version placeholder: 21.7.0 ← should look like this (check the footer) description: What version of self-hosted Sentry are you running? validations: required: true - type: textarea id: repro attributes: label: Steps to Reproduce description: How can we see what you're seeing? Specific is terrific. placeholder: |- 1. foo 2. bar 3. baz validations: required: true - type: textarea id: expected attributes: label: Expected Result validations: required: true - type: textarea id: actual attributes: label: Actual Result description: Logs? Screenshots? Yes, please. placeholder: |- e.g.: - latest install logs: `ls -1 sentry_install_log-*.txt | tail -1 | xargs cat` - - `docker-compose logs` output + - `docker compose logs` output validations: required: true - type: markdown attributes: value: |- - ## Thanks πŸ™ + ## Thanks Check our [triage docs](https://open.sentry.io/triage/) for what to expect next. validations: required: false diff --git a/.gitignore b/.gitignore index 4a86daa..e1dbcd6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,93 +1,96 @@ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt sentry_install_log*.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py # Sphinx documentation docs/_build/ # PyBuilder target/ # Ipython Notebook .ipynb_checkpoints # pyenv .python-version # https://docs.docker.com/compose/extends/ docker-compose.override.yml +# https://docs.docker.com/compose/environment-variables/#using-the---env-file--option +.env.custom + *.tar data/ .vscode/tags # custom Sentry config sentry/sentry.conf.py sentry/config.yml sentry/*.bak sentry/requirements.txt relay/credentials.json relay/config.yml symbolicator/config.yml geoip/GeoIP.conf geoip/*.mmdb geoip/.geoipupdate.lock # wal2json download postgres/wal2json # integration testing _integration-test/custom-ca-roots/nginx/* sentry/test-custom-ca-roots.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 901191a..cf17e37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,60 +1,103 @@ # Changelog +## 21.12.0 + +### Support Docker Compose v2 (ongoing) + +Self-hosted Sentry mostly works with Docker Compose v2 (in addition to v1 >= 1.28.0). There is [one more bug](https://github.com/getsentry/self-hosted/issues/1133) we are trying to squash. + +By: @chadwhitacre (#1179) + +### Prevent Component Drift + +When a user runs the `install.sh` script, they get the latest version of the Sentry, Snuba, Relay and Symbolicator projects. However there is no guarantee they have pulled the latest `self-hosted` version first, and running an old one may cause problems. To mitigate this, we now perform a check during installation that the user is on the latest commit if they are on the `master` branch. You can disable this check with `--skip-commit-check`. + +By: @chadwhitacre (#1191), @aminvakil (#1186) + +### React to log4shell + +Self-hosted Sentry is [not vulnerable](https://github.com/getsentry/self-hosted/issues/1196) to the [log4shell](https://log4shell.com/) vulnerability. + +By: @chadwhitacre (#1203) + +### Forum β†’ Issues + +In the interest of reducing sources of truth, providing better support, and restarting the fire of the self-hosted Sentry community, we [deprecated the Discourse forum in favor of GitHub Issues](https://github.com/getsentry/self-hosted/issues/1151). + +By: @chadwhitacre (#1167, #1160, #1159) + +### Rename onpremise to self-hosted (ongoing) + +In the beginning we used the term "on-premise" and over time we introduced the term "self-hosted." In an effort to regain some consistency for both branding and developer mental overhead purposes, we are standardizing on the term "self-hosted." This release includes a fair portion of the work towards this across multiple repos, hopefully a future release will include the remainder. Some orphaned containers / volumes / networks are [expected](https://github.com/getsentry/self-hosted/pull/1169#discussion_r756401917). You may clean them up with `docker-compose down --remove-orphans`. + +By: @chadwhitacre (#1169) + +### Add support for custom DotEnv file + +There are several ways to [configure self-hosted Sentry](https://develop.sentry.dev/self-hosted/#configuration) and one of them is the `.env` file. In this release we add support for a `.env.custom` file that is git-ignored to make it easier for you to override keys configured this way with custom values. Thanks to @Sebi94nbg for the contribution! + +By: @Sebi94nbg (#1113) + +### Various fixes & improvements + +- Revert "Rename onpremise to self-hosted" (5495fe2e) by @chadwhitacre +- Rename onpremise to self-hosted (9ad05d87) by @chadwhitacre + ## 21.11.0 ### Various fixes & improvements - Fix #1079 - bug in reset.sh (#1134) by @chadwhitacre - ci: Enable parallel tests again, increase timeouts (#1125) by @BYK - fix: Hide compose errors during version check (#1124) by @BYK - build: Omit nightly bump commit from changelog (#1120) by @BYK - build: Set master version to nightly (d3e77857) ## 21.10.0 ### Support for Docker Compose v2 (ongoing) You asked for it and you did it! Sentry self-hosted now can work with Docker Compose v2 thanks to our community's contributions. PRs: #1116 ### Various fixes & improvements - docs: simplify Linux `sudo` instructions in README (#1096) - build: Set master version to nightly (58874cf9) ## 21.9.0 - fix(healthcheck): Increase retries to 5 (#1072) - fix(requirements): Make compose version check bw-compatible (#1068) - ci: Test with the required minimum docker-compose (#1066) Run tests using docker-compose `1.28.0` instead of latest - fix(clickhouse): Use correct HTTP port for healthcheck (#1069) Fixes the regular `Unexpected packet` errors in Clickhouse ## 21.8.0 - feat: Support custom CA roots ([#27062](https://github.com/getsentry/sentry/pull/27062)), see the [docs](https://develop.sentry.dev/self-hosted/custom-ca-roots/) for more details. - fix: Fix `curl` image to version 7.77.0 - upgrade: docker-compose version to 1.29.2 - feat: Leverage health checks for depends_on ## 21.7.0 - No documented changes. ## 21.6.3 - No documented changes. ## 21.6.2 - BREAKING CHANGE: The frontend bundle will be loaded asynchronously (via [#25744](https://github.com/getsentry/sentry/pull/25744)). This is a breaking change that can affect custom plugins that access certain globals in the django template. Please see https://forum.sentry.io/t/breaking-frontend-changes-for-custom-plugins/14184 for more information. ## 21.6.1 - No documented changes. ## 21.6.0 - feat: Add healthchecks for redis, memcached and postgres (#975) diff --git a/LICENSE b/LICENSE index cc5f571..07b3c84 100644 --- a/LICENSE +++ b/LICENSE @@ -1,104 +1,104 @@ Business Source License 1.1 Parameters Licensor: Functional Software, Inc. Licensed Work: Sentry The Licensed Work is (c) 2019 Functional Software, Inc. Additional Use Grant: You may make use of the Licensed Work, provided that you do not use the Licensed Work for an Application Monitoring Service. An "Application Monitoring Service" is a commercial offering that allows third parties (other than your employees and contractors) to access the functionality of the Licensed Work so that such third parties directly benefit from the error-reporting or application monitoring features of the Licensed Work. -Change Date: 2024-11-15 +Change Date: 2024-12-15 Change License: Apache License, Version 2.0 For information about alternative licensing arrangements for the Software, please visit: https://sentry.io/pricing/ Notice The Business Source License (this document, or the "License") is not an Open Source license. However, the Licensed Work will eventually be made available under an Open Source License, as stated in this License. License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. "Business Source License" is a trademark of MariaDB Corporation Ab. ----------------------------------------------------------------------------- Business Source License 1.1 Terms The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and make non-production use of the Licensed Work. The Licensor may make an Additional Use Grant, above, permitting limited production use. Effective on the Change Date, or the fourth anniversary of the first publicly available distribution of a specific version of the Licensed Work under this License, whichever comes first, the Licensor hereby grants you rights under the terms of the Change License, and the rights granted in the paragraph above terminate. If your use of the Licensed Work does not comply with the requirements currently in effect as described in this License, you must purchase a commercial license from the Licensor, its affiliated entities, or authorized resellers, or you must refrain from using the Licensed Work. All copies of the original and modified Licensed Work, and derivative works of the Licensed Work, are subject to this License. This License applies separately for each version of the Licensed Work and the Change Date may vary for each version of the Licensed Work released by Licensor. You must conspicuously display this License on each original or modified copy of the Licensed Work. If you receive the Licensed Work in original or modified form from a third party, the terms and conditions set forth in this License apply to your use of that work. Any use of the Licensed Work in violation of this License will automatically terminate your rights under this License for the current and all other versions of the Licensed Work. This License does not grant you any right in any trademark or logo of Licensor or its affiliates (provided that you may use a trademark or logo of Licensor as expressly required by this License). TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE. MariaDB hereby grants you permission to use this License’s text to license your works, and to refer to it using the trademark "Business Source License", as long as you comply with the Covenants of Licensor below. Covenants of Licensor In consideration of the right to use this License’s text and the "Business Source License" name and trademark, Licensor covenants to MariaDB, and to all other recipients of the licensed work to be provided by Licensor: 1. To specify as the Change License the GPL Version 2.0 or any later version, or a license that is compatible with GPL Version 2.0 or a later version, where "compatible" means that software provided under the Change License can be included in a program with software provided under GPL Version 2.0 or a later version. Licensor may specify additional Change Licenses without limitation. 2. To either: (a) specify an additional grant of rights to use that does not impose any additional restriction on the right granted in this License, as the Additional Use Grant; or (b) insert the text "None". 3. To specify a Change Date. 4. Not to modify this License in any other way. diff --git a/README.md b/README.md index ff3d896..3132a29 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,61 @@ -# Self-Hosted Sentry 21.11.0 +# Self-Hosted Sentry 21.12.0 Official bootstrap for running your own [Sentry](https://sentry.io/) with [Docker](https://www.docker.com/). ## Requirements * Docker 19.03.6+ * Compose 1.28.0+ * 4 CPU Cores * 8 GB RAM * 20 GB Free Disk Space ## Setup +### Customize DotEnv (.env) file + +Environment specific configurations can be done in the `.env.custom` file. It will be located in the root directory of the Sentry installation. + +By default, there exists no `.env.custom` file. In this case, you can manually add this file by copying the `.env` file to a new `.env.custom` file and adjust your settings in the `.env.custom` file. + +Please keep in mind to check the `.env` file for changes, when you perform an upgrade of Sentry, so that you can adjust your `.env.custom` accordingly, if required. + +### Installation + To get started with all the defaults, simply clone the repo and run `./install.sh` in your local check-out. Sentry uses Python 3 by default since December 4th, 2020 and Sentry 21.1.0 is the last version to support Python 2. -During the install, a prompt will ask if you want to create a user account. If you require that the install not be blocked by the prompt, run `./install.sh --no-user-prompt`. +During the install, a prompt will ask if you want to create a user account. If you require that the install not be blocked by the prompt, run `./install.sh --skip-user-prompt`. Please visit [our documentation](https://develop.sentry.dev/self-hosted/) for everything else. ## Tips & Tricks ### Event Retention Sentry comes with a cleanup cron job that prunes events older than `90 days` by default. If you want to change that, you can change the `SENTRY_EVENT_RETENTION_DAYS` environment variable in `.env` or simply override it in your environment. If you do not want the cleanup cron, you can remove the `sentry-cleanup` service from the `docker-compose.yml`file. ### Installing a specific SHA If you want to install a specific release of Sentry, use the tags/releases on this repo. We continously push the Docker image for each commit made into [Sentry](https://github.com/getsentry/sentry), and other services such as [Snuba](https://github.com/getsentry/snuba) or [Symbolicator](https://github.com/getsentry/symbolicator) to [our Docker Hub](https://hub.docker.com/u/getsentry) and tag the latest version on master as `:nightly`. This is also usually what we have on sentry.io and what the install script uses. You can use a custom Sentry image, such as a modified version that you have built on your own, or simply a specific commit hash by setting the `SENTRY_IMAGE` environment variable to that image name before running `./install.sh`: ```shell SENTRY_IMAGE=getsentry/sentry:83b1380 ./install.sh ``` Note that this may not work for all commit SHAs as this repository evolves with Sentry and its satellite projects. It is highly recommended to check out a version of this repository that is close to the timestamp of the Sentry commit you are installing. ### Using Linux If you are using Linux and you need to use `sudo` when running `./install.sh`, make sure to place the environment variable *after* `sudo`: ```shell sudo SENTRY_IMAGE=us.gcr.io/sentryio/sentry:83b1380 ./install.sh ``` Where you replace `83b1380` with the sha you want to use. -[build-status-image]: https://github.com/getsentry/onpremise/workflows/test/badge.svg +[build-status-image]: https://github.com/getsentry/self-hosted/workflows/test/badge.svg [build-status-url]: https://git.io/JUYkh + diff --git a/_integration-test/run.sh b/_integration-test/run.sh index 0e4547b..94f54b0 100755 --- a/_integration-test/run.sh +++ b/_integration-test/run.sh @@ -1,128 +1,128 @@ #!/usr/bin/env bash set -ex source "$(dirname $0)/../install/_lib.sh" echo "${_group}Setting up variables and helpers ..." export SENTRY_TEST_HOST="${SENTRY_TEST_HOST:-http://localhost:9000}" TEST_USER='test@example.com' TEST_PASS='test123TEST' COOKIE_FILE=$(mktemp) # Courtesy of https://stackoverflow.com/a/2183063/90297 trap_with_arg() { func="$1" ; shift for sig ; do trap "$func $sig "'$LINENO' "$sig" done } -DID_CLEAN_UP=0 -# the cleanup function will be the exit point -cleanup () { - if [ "$DID_CLEAN_UP" -eq 1 ]; then +DID_TEAR_DOWN=0 +# the teardown function will be the exit point +teardown() { + if [ "$DID_TEAR_DOWN" -eq 1 ]; then return 0; fi - DID_CLEAN_UP=1 + DID_TEAR_DOWN=1 if [ "$1" != "EXIT" ]; then echo "An error occurred, caught SIG$1 on line $2"; fi - echo "Cleaning up..." + echo "Tearing down ..." rm $COOKIE_FILE echo "Done." } -trap_with_arg cleanup ERR INT TERM EXIT +trap_with_arg teardown ERR INT TERM EXIT echo "${_endgroup}" echo "${_group}Starting Sentry for tests ..." # Disable beacon for e2e tests echo 'SENTRY_BEACON=False' >> $SENTRY_CONFIG_PY $dcr web createuser --superuser --email $TEST_USER --password $TEST_PASS || true $dc up -d printf "Waiting for Sentry to be up"; timeout 90 bash -c 'until $(curl -Isf -o /dev/null $SENTRY_TEST_HOST); do printf '.'; sleep 0.5; done' echo "" echo "${_endgroup}" echo "${_group}Running tests ..." get_csrf_token () { awk '$6 == "sc" { print $7 }' $COOKIE_FILE; } sentry_api_request () { curl -s -H 'Accept: application/json; charset=utf-8' -H "Referer: $SENTRY_TEST_HOST" -H 'Content-Type: application/json' -H "X-CSRFToken: $(get_csrf_token)" -b "$COOKIE_FILE" -c "$COOKIE_FILE" "$SENTRY_TEST_HOST/api/0/$1" ${@:2}; } login () { INITIAL_AUTH_REDIRECT=$(curl -sL -o /dev/null $SENTRY_TEST_HOST -w %{url_effective}) if [ "$INITIAL_AUTH_REDIRECT" != "$SENTRY_TEST_HOST/auth/login/sentry/" ]; then echo "Initial /auth/login/ redirect failed, exiting..." echo "$INITIAL_AUTH_REDIRECT" exit -1 fi CSRF_TOKEN_FOR_LOGIN=$(curl $SENTRY_TEST_HOST -sL -c "$COOKIE_FILE" | awk -F "['\"]" ' /csrfmiddlewaretoken/ { print $4 "=" $6; exit; }') curl -sL --data-urlencode 'op=login' --data-urlencode "username=$TEST_USER" --data-urlencode "password=$TEST_PASS" --data-urlencode "$CSRF_TOKEN_FOR_LOGIN" "$SENTRY_TEST_HOST/auth/login/sentry/" -H "Referer: $SENTRY_TEST_HOST/auth/login/sentry/" -b "$COOKIE_FILE" -c "$COOKIE_FILE"; } LOGIN_RESPONSE=$(login); declare -a LOGIN_TEST_STRINGS=( '"isAuthenticated":true' '"username":"test@example.com"' '"isSuperuser":true' ) for i in "${LOGIN_TEST_STRINGS[@]}" do echo "Testing '$i'..." echo "$LOGIN_RESPONSE" | grep "$i[,}]" >& /dev/null echo "Pass." done echo "${_endgroup}" echo "${_group}Running moar tests !!!" # Set up initial/required settings (InstallWizard request) sentry_api_request "internal/options/?query=is:required" -X PUT --data '{"mail.use-tls":false,"mail.username":"","mail.port":25,"system.admin-email":"ben@byk.im","mail.password":"","system.url-prefix":"'"$SENTRY_TEST_HOST"'","auth.allow-registration":false,"beacon.anonymous":true}' > /dev/null SENTRY_DSN=$(sentry_api_request "projects/sentry/internal/keys/" | awk 'BEGIN { RS=",|:{\n"; FS="\""; } $2 == "public" && $4 ~ "^http" { print $4; exit; }') # We ignore the protocol and the host as we already know those DSN_PIECES=(`echo $SENTRY_DSN | sed -ne 's|^https\{0,1\}://\([0-9a-z]\{1,\}\)@[^/]\{1,\}/\([0-9]\{1,\}\)$|\1 \2|p' | tr ' ' '\n'`) SENTRY_KEY=${DSN_PIECES[0]} PROJECT_ID=${DSN_PIECES[1]} TEST_EVENT_ID=$(export LC_ALL=C; head /dev/urandom | tr -dc "a-f0-9" | head -c 32) # Thanks @untitaker - https://forum.sentry.io/t/how-can-i-post-with-curl-a-sentry-event-which-authentication-credentials/4759/2?u=byk echo "Creating test event..." curl -sf --data '{"event_id": "'"$TEST_EVENT_ID"'","level":"error","message":"a failure","extra":{"object":"42"}}' -H 'Content-Type: application/json' -H "X-Sentry-Auth: Sentry sentry_version=7, sentry_key=$SENTRY_KEY, sentry_client=test-bash/0.1" "$SENTRY_TEST_HOST/api/$PROJECT_ID/store/" -o /dev/null EVENT_PATH="projects/sentry/internal/events/$TEST_EVENT_ID/" export -f sentry_api_request get_csrf_token export SENTRY_TEST_HOST COOKIE_FILE EVENT_PATH printf "Getting the test event back" timeout 60 bash -c 'until $(sentry_api_request "$EVENT_PATH" -Isf -X GET -o /dev/null); do printf '.'; sleep 0.5; done' echo " got it!"; EVENT_RESPONSE=$(sentry_api_request "$EVENT_PATH") declare -a EVENT_TEST_STRINGS=( '"eventID":"'"$TEST_EVENT_ID"'"' '"message":"a failure"' '"title":"a failure"' '"object":"42"' ) for i in "${EVENT_TEST_STRINGS[@]}" do echo "Testing '$i'..." echo "$EVENT_RESPONSE" | grep "$i[,}]" >& /dev/null echo "Pass." done echo "${_endgroup}" echo "${_group}Ensure cleanup crons are working ..." $dc ps | grep -q -E -e '\-cleanup\s+running\s+' -e '\-cleanup[_-].+\s+Up\s+' echo "${_endgroup}" echo "${_group}Test custom CAs work ..." source ./custom-ca-roots/setup.sh $dcr --no-deps web python3 /etc/sentry/test-custom-ca-roots.py source ./custom-ca-roots/teardown.sh echo "${_endgroup}" diff --git a/docker-compose.yml b/docker-compose.yml index 395a832..1c28549 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,338 +1,341 @@ x-restart-policy: &restart_policy restart: unless-stopped x-depends_on-healthy: &depends_on-healthy condition: service_healthy x-depends_on-default: &depends_on-default condition: service_started x-healthcheck-defaults: &healthcheck_defaults # Avoid setting the interval too small, as docker uses much more CPU than one would expect. # Related issues: # https://github.com/moby/moby/issues/39102 # https://github.com/moby/moby/issues/39388 - # https://github.com/getsentry/onpremise/issues/1000 + # https://github.com/getsentry/self-hosted/issues/1000 interval: 30s timeout: 5s retries: 5 start_period: 10s x-sentry-defaults: &sentry_defaults <<: *restart_policy image: "$SENTRY_IMAGE" depends_on: redis: <<: *depends_on-healthy kafka: <<: *depends_on-healthy memcached: <<: *depends_on-default snuba-api: <<: *depends_on-default snuba-consumer: <<: *depends_on-default snuba-outcomes-consumer: <<: *depends_on-default snuba-sessions-consumer: <<: *depends_on-default snuba-transactions-consumer: <<: *depends_on-default snuba-subscription-consumer-events: <<: *depends_on-default snuba-subscription-consumer-transactions: <<: *depends_on-default snuba-replacer: <<: *depends_on-default symbolicator: <<: *depends_on-default entrypoint: "/etc/sentry/entrypoint.sh" command: ["run", "web"] environment: PYTHONUSERBASE: "/data/custom-packages" SENTRY_CONF: "/etc/sentry" SNUBA: "http://snuba-api:1218" # Force everything to use the system CA bundle # This is mostly needed to support installing custom CA certs # This one is used by botocore DEFAULT_CA_BUNDLE: &ca_bundle "/etc/ssl/certs/ca-certificates.crt" # This one is used by requests REQUESTS_CA_BUNDLE: *ca_bundle # This one is used by grpc/google modules GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR: *ca_bundle # Leaving the value empty to just pass whatever is set # on the host system (or in the .env file) SENTRY_EVENT_RETENTION_DAYS: SENTRY_MAIL_HOST: volumes: - "sentry-data:/data" - "./sentry:/etc/sentry" - "./geoip:/geoip:ro" - "./certificates:/usr/local/share/ca-certificates:ro" x-snuba-defaults: &snuba_defaults <<: *restart_policy depends_on: clickhouse: <<: *depends_on-healthy kafka: <<: *depends_on-healthy redis: <<: *depends_on-healthy image: "$SNUBA_IMAGE" environment: SNUBA_SETTINGS: docker CLICKHOUSE_HOST: clickhouse DEFAULT_BROKERS: "kafka:9092" REDIS_HOST: redis UWSGI_MAX_REQUESTS: "10000" UWSGI_DISABLE_LOGGING: "true" # Leaving the value empty to just pass whatever is set # on the host system (or in the .env file) SENTRY_EVENT_RETENTION_DAYS: services: memcached: <<: *restart_policy image: "memcached:1.6.9-alpine" healthcheck: <<: *healthcheck_defaults # From: https://stackoverflow.com/a/31877626/5155484 test: echo stats | nc 127.0.0.1 11211 redis: <<: *restart_policy image: "redis:6.2.4-alpine" healthcheck: <<: *healthcheck_defaults test: redis-cli ping volumes: - "sentry-redis:/data" ulimits: nofile: soft: 10032 hard: 10032 zookeeper: <<: *restart_policy image: "confluentinc/cp-zookeeper:5.5.0" environment: ZOOKEEPER_CLIENT_PORT: "2181" CONFLUENT_SUPPORT_METRICS_ENABLE: "false" ZOOKEEPER_LOG4J_ROOT_LOGLEVEL: "WARN" ZOOKEEPER_TOOLS_LOG4J_LOGLEVEL: "WARN" KAFKA_OPTS: "-Dzookeeper.4lw.commands.whitelist=ruok" volumes: - "sentry-zookeeper:/var/lib/zookeeper/data" - "sentry-zookeeper-log:/var/lib/zookeeper/log" - "sentry-secrets:/etc/zookeeper/secrets" healthcheck: <<: *healthcheck_defaults test: ["CMD-SHELL", 'echo "ruok" | nc -w 2 -q 2 localhost 2181 | grep imok'] kafka: <<: *restart_policy depends_on: zookeeper: <<: *depends_on-healthy image: "confluentinc/cp-kafka:5.5.0" environment: KAFKA_ZOOKEEPER_CONNECT: "zookeeper:2181" KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:9092" KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1" KAFKA_OFFSETS_TOPIC_NUM_PARTITIONS: "1" KAFKA_LOG_RETENTION_HOURS: "24" KAFKA_MESSAGE_MAX_BYTES: "50000000" #50MB or bust KAFKA_MAX_REQUEST_SIZE: "50000000" #50MB on requests apparently too CONFLUENT_SUPPORT_METRICS_ENABLE: "false" KAFKA_LOG4J_LOGGERS: "kafka.cluster=WARN,kafka.controller=WARN,kafka.coordinator=WARN,kafka.log=WARN,kafka.server=WARN,kafka.zookeeper=WARN,state.change.logger=WARN" KAFKA_LOG4J_ROOT_LOGLEVEL: "WARN" KAFKA_TOOLS_LOG4J_LOGLEVEL: "WARN" volumes: - "sentry-kafka:/var/lib/kafka/data" - "sentry-kafka-log:/var/lib/kafka/log" - "sentry-secrets:/etc/kafka/secrets" healthcheck: <<: *healthcheck_defaults test: ["CMD-SHELL", "nc -z localhost 9092"] clickhouse: <<: *restart_policy image: "yandex/clickhouse-server:20.3.9.70" ulimits: nofile: soft: 262144 hard: 262144 volumes: - "sentry-clickhouse:/var/lib/clickhouse" - "sentry-clickhouse-log:/var/log/clickhouse-server" - type: bind read_only: true source: ./clickhouse/config.xml target: /etc/clickhouse-server/config.d/sentry.xml environment: # This limits Clickhouse's memory to 30% of the host memory # If you have high volume and your search return incomplete results # You might want to change this to a higher value (and ensure your host has enough memory) MAX_MEMORY_USAGE_RATIO: 0.3 healthcheck: test: [ "CMD-SHELL", "wget -nv -t1 --spider 'http://localhost:8123/' || exit 1", ] interval: 3s timeout: 600s retries: 200 geoipupdate: image: "maxmindinc/geoipupdate:v4.7.1" # Override the entrypoint in order to avoid using envvars for config. # Futz with settings so we can keep mmdb and conf in same dir on host # (image looks for them in separate dirs by default). entrypoint: ["/usr/bin/geoipupdate", "-d", "/sentry", "-f", "/sentry/GeoIP.conf"] volumes: - "./geoip:/sentry" snuba-api: <<: *snuba_defaults # Kafka consumer responsible for feeding events into Clickhouse snuba-consumer: <<: *snuba_defaults command: consumer --storage errors --auto-offset-reset=latest --max-batch-time-ms 750 # Kafka consumer responsible for feeding outcomes into Clickhouse # Use --auto-offset-reset=earliest to recover up to 7 days of TSDB data # since we did not do a proper migration snuba-outcomes-consumer: <<: *snuba_defaults command: consumer --storage outcomes_raw --auto-offset-reset=earliest --max-batch-time-ms 750 # Kafka consumer responsible for feeding session data into Clickhouse snuba-sessions-consumer: <<: *snuba_defaults command: consumer --storage sessions_raw --auto-offset-reset=latest --max-batch-time-ms 750 # Kafka consumer responsible for feeding transactions data into Clickhouse snuba-transactions-consumer: <<: *snuba_defaults command: consumer --storage transactions --consumer-group transactions_group --auto-offset-reset=latest --max-batch-time-ms 750 --commit-log-topic=snuba-commit-log snuba-replacer: <<: *snuba_defaults command: replacer --storage errors --auto-offset-reset=latest --max-batch-size 3 snuba-subscription-consumer-events: <<: *snuba_defaults command: subscriptions --auto-offset-reset=latest --consumer-group=snuba-events-subscriptions-consumers --topic=events --result-topic=events-subscription-results --dataset=events --commit-log-topic=snuba-commit-log --commit-log-group=snuba-consumers --delay-seconds=60 --schedule-ttl=60 snuba-subscription-consumer-transactions: <<: *snuba_defaults command: subscriptions --auto-offset-reset=latest --consumer-group=snuba-transactions-subscriptions-consumers --topic=events --result-topic=transactions-subscription-results --dataset=transactions --commit-log-topic=snuba-commit-log --commit-log-group=transactions_group --delay-seconds=60 --schedule-ttl=60 snuba-cleanup: <<: *snuba_defaults - image: snuba-cleanup-onpremise-local + image: snuba-cleanup-self-hosted-local build: context: ./cron args: BASE_IMAGE: "$SNUBA_IMAGE" command: '"*/5 * * * * gosu snuba snuba cleanup --storage errors --dry-run False"' snuba-transactions-cleanup: <<: *snuba_defaults - image: snuba-cleanup-onpremise-local + image: snuba-cleanup-self-hosted-local build: context: ./cron args: BASE_IMAGE: "$SNUBA_IMAGE" command: '"*/5 * * * * gosu snuba snuba cleanup --storage transactions --dry-run False"' symbolicator: <<: *restart_policy image: "$SYMBOLICATOR_IMAGE" volumes: - "sentry-symbolicator:/data" - type: bind read_only: true source: ./symbolicator target: /etc/symbolicator command: run -c /etc/symbolicator/config.yml symbolicator-cleanup: <<: *restart_policy - image: symbolicator-cleanup-onpremise-local + image: symbolicator-cleanup-self-hosted-local build: context: ./cron args: BASE_IMAGE: "$SYMBOLICATOR_IMAGE" command: '"55 23 * * * gosu symbolicator symbolicator cleanup"' volumes: - "sentry-symbolicator:/data" web: <<: *sentry_defaults healthcheck: <<: *healthcheck_defaults test: - "CMD" - "/bin/bash" - '-c' # Courtesy of https://unix.stackexchange.com/a/234089/108960 - 'exec 3<>/dev/tcp/127.0.0.1/9000 && echo -e "GET /_health/ HTTP/1.1\r\nhost: 127.0.0.1\r\n\r\n" >&3 && grep ok -s -m 1 <&3' cron: <<: *sentry_defaults command: run cron worker: <<: *sentry_defaults command: run worker ingest-consumer: <<: *sentry_defaults command: run ingest-consumer --all-consumer-types post-process-forwarder: <<: *sentry_defaults # Increase `--commit-batch-size 1` below to deal with high-load environments. command: run post-process-forwarder --commit-batch-size 1 subscription-consumer-events: <<: *sentry_defaults command: run query-subscription-consumer --commit-batch-size 1 --topic events-subscription-results subscription-consumer-transactions: <<: *sentry_defaults command: run query-subscription-consumer --commit-batch-size 1 --topic transactions-subscription-results sentry-cleanup: <<: *sentry_defaults - image: sentry-cleanup-onpremise-local + image: sentry-cleanup-self-hosted-local build: context: ./cron args: BASE_IMAGE: "$SENTRY_IMAGE" entrypoint: "/entrypoint.sh" command: '"0 0 * * * gosu sentry sentry cleanup --days $SENTRY_EVENT_RETENTION_DAYS"' nginx: <<: *restart_policy ports: - "$SENTRY_BIND:80/tcp" - image: "nginx:1.21.0-alpine" + image: "nginx:1.21.4-alpine" volumes: - type: bind read_only: true source: ./nginx target: /etc/nginx depends_on: - web - relay relay: <<: *restart_policy image: "$RELAY_IMAGE" volumes: - type: bind read_only: true source: ./relay target: /work/.relay - type: bind read_only: true source: ./geoip target: /geoip depends_on: kafka: <<: *depends_on-healthy redis: <<: *depends_on-healthy web: <<: *depends_on-healthy volumes: + # These store application data that should persist across restarts. sentry-data: external: true sentry-redis: external: true sentry-zookeeper: external: true sentry-kafka: external: true sentry-clickhouse: external: true sentry-symbolicator: external: true + + # These store ephemeral data that needn't persist across restarts. sentry-secrets: sentry-zookeeper-log: sentry-kafka-log: sentry-clickhouse-log: diff --git a/install.sh b/install.sh index 3886463..10525ef 100755 --- a/install.sh +++ b/install.sh @@ -1,29 +1,30 @@ #!/usr/bin/env bash set -e if [[ -n "$MSYSTEM" ]]; then echo "Seems like you are using an MSYS2-based system (such as Git Bash) which is not supported. Please use WSL instead."; exit 1 fi source "$(dirname $0)/install/_lib.sh" # does a `cd .../install/`, among other things source parse-cli.sh +source check-latest-commit.sh source error-handling.sh source check-minimum-requirements.sh source create-docker-volumes.sh source ensure-files-from-examples.sh source generate-secret-key.sh source replace-tsdb.sh source update-docker-images.sh source build-docker-images.sh source turn-things-off.sh source set-up-zookeeper.sh source install-wal2json.sh source bootstrap-snuba.sh source create-kafka-topics.sh source upgrade-postgres.sh source set-up-and-migrate-database.sh source migrate-file-storage.sh source relay-credentials.sh source geoip.sh source wrap-up.sh diff --git a/install/_lib.sh b/install/_lib.sh index 06bfcbb..fb7b920 100644 --- a/install/_lib.sh +++ b/install/_lib.sh @@ -1,50 +1,56 @@ set -euo pipefail test "${DEBUG:-}" && set -x # Thanks to https://unix.stackexchange.com/a/145654/108960 log_file="sentry_install_log-`date +'%Y-%m-%d_%H-%M-%S'`.txt" exec &> >(tee -a "$log_file") # Work from /install/ for install.sh, project root otherwise if [[ "$(basename $0)" = "install.sh" ]]; then cd "$(dirname $0)/install/" else cd "$(dirname $0)" # assume we're a test script or some such fi -_ENV="$(realpath ../.env)" +# Allow `.env` overrides using the `.env.custom` file +if [[ -f "../.env.custom" ]]; then + _ENV="$(realpath ../.env.custom)" +else + _ENV="$(realpath ../.env)" +fi # Read .env for default values with a tip o' the hat to https://stackoverflow.com/a/59831605/90297 t=$(mktemp) && export -p > "$t" && set -a && . $_ENV && set +a && . "$t" && rm "$t" && unset t if [ "${GITHUB_ACTIONS:-}" = "true" ]; then _group="::group::" _endgroup="::endgroup::" else _group="β–Ά " _endgroup="" fi +# Some environments still use `docker-compose` even for Docker Compose v2. dc_base="$(docker compose version &> /dev/null && echo 'docker compose' || echo 'docker-compose')" -dc="$dc_base --ansi never" +dc="$dc_base --ansi never --env-file ${_ENV}" dcr="$dc run --rm" # A couple of the config files are referenced from other subscripts, so they # get vars, while multiple subscripts call ensure_file_from_example. function ensure_file_from_example { if [[ -f "$1" ]]; then echo "$1 already exists, skipped creation." else echo "Creating $1..." cp -n $(echo "$1" | sed 's/\.[^.]*$/.example&/') "$1" # sed from https://stackoverflow.com/a/25123013/90297 fi } SENTRY_CONFIG_PY='../sentry/sentry.conf.py' SENTRY_CONFIG_YML='../sentry/config.yml' # Increase the default 10 second SIGTERM timeout # to ensure celery queues are properly drained # between upgrades as task signatures may change across # versions STOP_TIMEOUT=60 # seconds diff --git a/install/_test_setup.sh b/install/_test_setup.sh index 6fdf29e..6e83492 100644 --- a/install/_test_setup.sh +++ b/install/_test_setup.sh @@ -1,52 +1,52 @@ set -euo pipefail source "$(dirname $0)/_lib.sh" -rm -rf /tmp/sentry-onpremise-test-sandbox.* -_SANDBOX="$(mktemp -d /tmp/sentry-onpremise-test-sandbox.XXX)" +rm -rf /tmp/sentry-self-hosted-test-sandbox.* +_SANDBOX="$(mktemp -d /tmp/sentry-self-hosted-test-sandbox.XXX)" report_success() { echo "$(basename $0) - Success πŸ‘" } teardown() { test "${DEBUG:-}" || rm -rf "$_SANDBOX" } setup() { cd .. # Clone the local repo into a temp dir. FWIW `git clone --local` breaks for # me because it depends on hard-linking, which doesn't work across devices, # and I happen to have my workspace and /tmp on separate devices. git -c advice.detachedHead=false clone --depth=1 "file://$(pwd)" "$_SANDBOX" # Now propagate any local changes from the working copy to the sandbox. This # provides a pretty nice dev experience: edit the files in the working copy, # then run `DEBUG=1 some-test.sh` to leave the sandbox up for interactive # dev/debugging. git status --porcelain | while read line; do # $line here is something like `M some-script.sh`. local filepath="$(cut -f2 -d' ' <(echo $line))" local filestatus="$(cut -f1 -d' ' <(echo $line))" case $filestatus in D) rm "$_SANDBOX/$filepath" ;; A | M | AM | ??) ln -sf "$(realpath $filepath)" "$_SANDBOX/$filepath" ;; **) echo "Wuh? $line" exit 77 ;; esac done cd "$_SANDBOX/install" trap teardown EXIT } setup diff --git a/install/check-latest-commit.sh b/install/check-latest-commit.sh new file mode 100644 index 0000000..7f35660 --- /dev/null +++ b/install/check-latest-commit.sh @@ -0,0 +1,15 @@ +echo "${_group}Checking for latest commit ... " + +# Checks if we are on latest commit from github if it is running from master branch +if [[ -d "../.git" && "${SKIP_COMMIT_CHECK:-0}" != 1 ]]; then + if [[ $(git branch | sed -n '/\* /s///p') == "master" ]]; then + if [[ $(git rev-parse HEAD) != $(git ls-remote $(git rev-parse --abbrev-ref @{u} | sed 's/\// /g') | cut -f1) ]]; then + echo "Seems like you are not using the latest commit from the self-hosted repository. Please pull the latest changes and try again, or suppress this check with --skip-commit-check."; + exit 1 + fi + fi +else + echo "skipped" +fi + +echo "${_endgroup}" diff --git a/install/check-minimum-requirements.sh b/install/check-minimum-requirements.sh index 6b43d18..42689bf 100644 --- a/install/check-minimum-requirements.sh +++ b/install/check-minimum-requirements.sh @@ -1,54 +1,54 @@ echo "${_group}Checking minimum requirements ..." source "$(dirname $0)/_min-requirements.sh" -DOCKER_VERSION=$(docker version --format '{{.Server.Version}}') -# Get semantic version of Docker Compose v2 -if docker compose version &>/dev/null; then - COMPOSE_VERSION=$(docker compose version --short | sed 's/v\{0,1\}\(.\{1,\}\)/\1/') -else - # Do NOT use $dc instead of `docker-compose` below as older versions don't support certain options and fail - COMPOSE_VERSION=$(docker-compose --version | sed 's/docker-compose version \(.\{1,\}\),.*/\1/') -fi -RAM_AVAILABLE_IN_DOCKER=$(docker run --rm busybox free -m 2>/dev/null | awk '/Mem/ {print $2}'); -CPU_AVAILABLE_IN_DOCKER=$(docker run --rm busybox nproc --all); - # Compare dot-separated strings - function below is inspired by https://stackoverflow.com/a/37939589/808368 function ver () { echo "$@" | awk -F. '{ printf("%d%03d%03d", $1,$2,$3); }'; } +DOCKER_VERSION=$(docker version --format '{{.Server.Version}}') if [[ "$(ver $DOCKER_VERSION)" -lt "$(ver $MIN_DOCKER_VERSION)" ]]; then echo "FAIL: Expected minimum Docker version to be $MIN_DOCKER_VERSION but found $DOCKER_VERSION" exit 1 fi -if [[ "$(ver $COMPOSE_VERSION)" -lt "$(ver $MIN_COMPOSE_VERSION)" ]]; then - echo "FAIL: Expected minimum docker-compose version to be $MIN_COMPOSE_VERSION but found $COMPOSE_VERSION" - exit 1 +if docker compose version &>/dev/null; then + # If `docker compose` exists then it's guaranteed to be Docker Compose v2, which is good enough for us. + true +else + # If we have `docker-compose` instead then it could be either v1 or v2 (also, use portable sed). + # See https://github.com/getsentry/self-hosted/issues/1132#issuecomment-982823712 ff. for regex testing. + COMPOSE_VERSION=$(docker-compose version | head -n1 | sed -E 's/^.* version:? v?([0-9.]+),?.*$/\1/') + if [[ "$(ver $COMPOSE_VERSION)" -lt "$(ver $MIN_COMPOSE_VERSION)" ]]; then + echo "FAIL: Expected minimum docker-compose version to be $MIN_COMPOSE_VERSION but found $COMPOSE_VERSION" + exit 1 + fi fi +CPU_AVAILABLE_IN_DOCKER=$(docker run --rm busybox nproc --all); if [[ "$CPU_AVAILABLE_IN_DOCKER" -lt "$MIN_CPU_HARD" ]]; then echo "FAIL: Required minimum CPU cores available to Docker is $MIN_CPU_HARD, found $CPU_AVAILABLE_IN_DOCKER" exit 1 elif [[ "$CPU_AVAILABLE_IN_DOCKER" -lt "$MIN_CPU_SOFT" ]]; then echo "WARN: Recommended minimum CPU cores available to Docker is $MIN_CPU_SOFT, found $CPU_AVAILABLE_IN_DOCKER" fi +RAM_AVAILABLE_IN_DOCKER=$(docker run --rm busybox free -m 2>/dev/null | awk '/Mem/ {print $2}'); if [[ "$RAM_AVAILABLE_IN_DOCKER" -lt "$MIN_RAM_HARD" ]]; then echo "FAIL: Required minimum RAM available to Docker is $MIN_RAM_HARD MB, found $RAM_AVAILABLE_IN_DOCKER MB" exit 1 elif [[ "$RAM_AVAILABLE_IN_DOCKER" -lt "$MIN_RAM_SOFT" ]]; then echo "WARN: Recommended minimum RAM available to Docker is $MIN_RAM_SOFT MB, found $RAM_AVAILABLE_IN_DOCKER MB" fi #SSE4.2 required by Clickhouse (https://clickhouse.yandex/docs/en/operations/requirements/) # On KVM, cpuinfo could falsely not report SSE 4.2 support, so skip the check. https://github.com/ClickHouse/ClickHouse/issues/20#issuecomment-226849297 IS_KVM=$(docker run --rm busybox grep -c 'Common KVM processor' /proc/cpuinfo || :) if [[ "$IS_KVM" -eq 0 ]]; then SUPPORTS_SSE42=$(docker run --rm busybox grep -c sse4_2 /proc/cpuinfo || :) if [[ "$SUPPORTS_SSE42" -eq 0 ]]; then echo "FAIL: The CPU your machine is running on does not support the SSE 4.2 instruction set, which is required for one of the services Sentry uses (Clickhouse). See https://git.io/JvLDt for more info." exit 1 fi fi echo "${_endgroup}" diff --git a/install/error-handling.sh b/install/error-handling.sh index d25ee01..9121bba 100644 --- a/install/error-handling.sh +++ b/install/error-handling.sh @@ -1,35 +1,35 @@ echo "${_group}Setting up error handling ..." # Courtesy of https://stackoverflow.com/a/2183063/90297 trap_with_arg() { func="$1" ; shift for sig ; do trap "$func $sig "'$LINENO' "$sig" done } DID_CLEAN_UP=0 # the cleanup function will be the exit point cleanup () { if [[ "$DID_CLEAN_UP" -eq 1 ]]; then return 0; fi DID_CLEAN_UP=1 if [[ "$1" != "EXIT" ]]; then echo "An error occurred, caught SIG$1 on line $2"; if [[ -n "$MINIMIZE_DOWNTIME" ]]; then - echo "*NOT* cleaning up, to clean your environment run \"docker-compose stop\"." + echo "*NOT* cleaning up, to clean your environment run \"docker compose stop\"." else echo "Cleaning up..." fi fi if [[ -z "$MINIMIZE_DOWNTIME" ]]; then $dc stop -t $STOP_TIMEOUT &> /dev/null fi } trap_with_arg cleanup ERR INT TERM EXIT echo "${_endgroup}" diff --git a/install/parse-cli.sh b/install/parse-cli.sh index f1b6218..4712fd6 100644 --- a/install/parse-cli.sh +++ b/install/parse-cli.sh @@ -1,32 +1,41 @@ echo "${_group}Parsing command line ..." show_help() { cat <stdout -# redirection below and pass it through grep, ignoring all lines having this -# '-onpremise-local' suffix. -$dc pull -q --ignore-pull-failures 2>&1 | grep -v -- -onpremise-local || true +# We tag locally built images with a '-self-hosted-local' suffix. `docker +# compose pull` tries to pull these too and shows a 404 error on the console +# which is confusing and unnecessary. To overcome this, we add the +# stderr>stdout redirection below and pass it through grep, ignoring all lines +# having this '-onpremise-local' suffix. + +$dc pull -q --ignore-pull-failures 2>&1 | grep -v -- -self-hosted-local || true # We may not have the set image on the repo (local images) so allow fails docker pull ${SENTRY_IMAGE} || true; echo "${_endgroup}" diff --git a/install/wrap-up.sh b/install/wrap-up.sh index 6f1128b..91638ca 100644 --- a/install/wrap-up.sh +++ b/install/wrap-up.sh @@ -1,26 +1,30 @@ if [[ "$MINIMIZE_DOWNTIME" ]]; then echo "${_group}Waiting for Sentry to start ..." # Start the whole setup, except nginx and relay. $dc up -d --remove-orphans $($dc config --services | grep -v -E '^(nginx|relay)$') $dc restart relay $dc exec -T nginx nginx -s reload docker run --rm --network="${COMPOSE_PROJECT_NAME}_default" alpine ash \ -c 'while [[ "$(wget -T 1 -q -O- http://web:9000/_health/)" != "ok" ]]; do sleep 0.5; done' # Make sure everything is up. This should only touch relay and nginx $dc up -d echo "${_endgroup}" else echo "" echo "-----------------------------------------------------------------" echo "" echo "You're all done! Run the following command to get Sentry running:" echo "" + if [[ "${_ENV}" =~ ".env.custom" ]]; then + echo " $dc_base --env-file ${_ENV} up -d" + else echo " $dc_base up -d" + fi echo "" echo "-----------------------------------------------------------------" echo "" fi diff --git a/reset.sh b/reset.sh index e188686..cba7568 100755 --- a/reset.sh +++ b/reset.sh @@ -1,62 +1,62 @@ #!/usr/bin/env bash -# The purpose of this script is to make it easy to reset a local onpremise +# The purpose of this script is to make it easy to reset a local self-hosted # install to a clean state, optionally targeting a particular version. set -euo pipefail if [ -n "${DEBUG:-}" ]; then set -x fi cd "$(dirname $0)" function confirm () { read -p "$1 [y/n] " confirmation if [ "$confirmation" != "y" ]; then echo "Canceled. πŸ˜…" exit fi } # If we have a version given, validate it. # ---------------------------------------- # Note that arbitrary git refs won't work, because the *_IMAGE variables in # .env will almost certainly point to :latest. Tagged releases are generally # the only refs where these component versions are pinned, so enforce that # we're targeting a valid tag here. Do this early in order to fail fast. version="${1:-}" if [ -n "$version" ]; then set +e git rev-parse --verify --quiet "refs/tags/$version" > /dev/null if [ $? -gt 0 ]; then echo "Bad version: $version" exit fi set -e fi # Make sure they mean it. confirm "☠️ Warning! 😳 This is highly destructive! 😱 Are you sure you wish to proceed?" echo "Okay ... good luck! 😰" # Hit the reset button. -docker-compose down --volumes --remove-orphans --rmi local +docker compose down --volumes --remove-orphans --rmi local # Remove any remaining (likely external) volumes with name matching 'sentry-.*'. for volume in $(docker volume list --format '{{ .Name }}' | grep '^sentry-'); do docker volume remove $volume > /dev/null \ && echo "Removed volume: $volume" \ || echo "Skipped volume: $volume" done # If we have a version given, switch to it. if [ -n "$version" ]; then git checkout "$version" fi # Install. ./install.sh