Compare commits
8 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c498f2e047 | ||
![]() |
279aed2080 | ||
![]() |
2dd4994259 | ||
![]() |
81869989fb | ||
![]() |
5f94889d01 | ||
![]() |
ff36755345 | ||
![]() |
f7334f7a0e | ||
![]() |
46bf30ac7f |
10 changed files with 123 additions and 69 deletions
|
@ -1,6 +1,14 @@
|
|||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## v3.9 - 2024-12-20
|
||||
|
||||
### Improvements
|
||||
- Change the default value of ALLOWED_HOSTS from "*" to the domain part of SITE_ROOT
|
||||
|
||||
### Bug Fixes
|
||||
- Fix fetchstatus.py (again) to handle SITE_ROOT with a path (#1108)
|
||||
|
||||
## v3.8.2 - 2024-12-19
|
||||
|
||||
### Improvements
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
FROM python:3.13.1-slim-bookworm AS builder
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
COPY requirements.txt /tmp
|
||||
RUN \
|
||||
apt-get update && \
|
||||
|
@ -43,5 +45,5 @@ RUN mkdir /data && chown hc /data
|
|||
USER hc
|
||||
|
||||
ENV USE_GZIP_MIDDLEWARE=True
|
||||
HEALTHCHECK --interval=60s --retries=1 CMD ./fetchstatus.py
|
||||
HEALTHCHECK --start-period=20s --start-interval=5s --interval=60s --retries=1 CMD ./fetchstatus.py
|
||||
CMD [ "uwsgi", "/opt/healthchecks/docker/uwsgi.ini"]
|
||||
|
|
|
@ -20,7 +20,8 @@ settings.py uses for reading SITE_ROOT:
|
|||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from urllib.request import urlopen
|
||||
from urllib.parse import urlparse
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
# Read SITE_ROOT from environment, same as settings.py would do:
|
||||
SITE_ROOT = os.getenv("SITE_ROOT", "http://localhost:8000")
|
||||
|
@ -30,8 +31,10 @@ if os.path.exists("hc/local_settings.py"):
|
|||
|
||||
SITE_ROOT = getattr(local_settings, "SITE_ROOT", SITE_ROOT)
|
||||
|
||||
SITE_ROOT = SITE_ROOT.removesuffix("/")
|
||||
with urlopen(f"{SITE_ROOT}/api/v3/status/") as response:
|
||||
parsed_site_root = urlparse(SITE_ROOT.removesuffix("/"))
|
||||
url = f"http://localhost:8000{parsed_site_root.path}/api/v3/status/"
|
||||
headers = {"Host": parsed_site_root.netloc}
|
||||
with urlopen(Request(url, headers=headers)) as response:
|
||||
assert response.status == 200
|
||||
|
||||
print("Status OK")
|
||||
|
|
|
@ -5,39 +5,46 @@ from django.urls import path
|
|||
from hc.accounts import views
|
||||
|
||||
urlpatterns = [
|
||||
path("login/", views.login, name="hc-login"),
|
||||
path("login/two_factor/", views.login_webauthn, name="hc-login-webauthn"),
|
||||
path("login/two_factor/totp/", views.login_totp, name="hc-login-totp"),
|
||||
path("logout/", views.logout, name="hc-logout"),
|
||||
path("signup/csrf/", views.signup_csrf),
|
||||
path("signup/", views.signup, name="hc-signup"),
|
||||
path("login_link_sent/", views.login_link_sent, name="hc-login-link-sent"),
|
||||
path("projects/add/", views.add_project, name="hc-add-project"),
|
||||
path("projects/<uuid:code>/settings/", views.project, name="hc-project-settings"),
|
||||
path(
|
||||
"check_token/<str:username>/<str:token>/",
|
||||
"projects/<uuid:code>/remove/", views.remove_project, name="hc-remove-project"
|
||||
),
|
||||
path("accounts/login/", views.login, name="hc-login"),
|
||||
path("accounts/login/two_factor/", views.login_webauthn, name="hc-login-webauthn"),
|
||||
path("accounts/login/two_factor/totp/", views.login_totp, name="hc-login-totp"),
|
||||
path("accounts/logout/", views.logout, name="hc-logout"),
|
||||
path("accounts/signup/csrf/", views.signup_csrf),
|
||||
path("accounts/signup/", views.signup, name="hc-signup"),
|
||||
path("accounts/login_link_sent/", views.login_link_sent, name="hc-login-link-sent"),
|
||||
path(
|
||||
"accounts/check_token/<str:username>/<str:token>/",
|
||||
views.check_token,
|
||||
name="hc-check-token",
|
||||
),
|
||||
path("profile/", views.profile, name="hc-profile"),
|
||||
path("profile/appearance/", views.appearance, name="hc-appearance"),
|
||||
path("profile/notifications/", views.notifications, name="hc-notifications"),
|
||||
path("close/", views.close, name="hc-close"),
|
||||
path("accounts/profile/", views.profile, name="hc-profile"),
|
||||
path("accounts/profile/appearance/", views.appearance, name="hc-appearance"),
|
||||
path(
|
||||
"unsubscribe_reports/<str:signed_username>/",
|
||||
"accounts/profile/notifications/", views.notifications, name="hc-notifications"
|
||||
),
|
||||
path("accounts/close/", views.close, name="hc-close"),
|
||||
path(
|
||||
"accounts/unsubscribe_reports/<str:signed_username>/",
|
||||
views.unsubscribe_reports,
|
||||
name="hc-unsubscribe-reports",
|
||||
),
|
||||
path("set_password/", views.set_password, name="hc-set-password"),
|
||||
path("change_email/", views.change_email, name="hc-change-email"),
|
||||
path("accounts/set_password/", views.set_password, name="hc-set-password"),
|
||||
path("accounts/change_email/", views.change_email, name="hc-change-email"),
|
||||
path(
|
||||
"change_email/<str:signed_payload>/",
|
||||
"accounts/change_email/<str:signed_payload>/",
|
||||
views.change_email_verify,
|
||||
name="hc-change-email-verify",
|
||||
),
|
||||
path("two_factor/webauthn/", views.add_webauthn, name="hc-add-webauthn"),
|
||||
path("two_factor/totp/", views.add_totp, name="hc-add-totp"),
|
||||
path("two_factor/totp/remove/", views.remove_totp, name="hc-remove-totp"),
|
||||
path("accounts/two_factor/webauthn/", views.add_webauthn, name="hc-add-webauthn"),
|
||||
path("accounts/two_factor/totp/", views.add_totp, name="hc-add-totp"),
|
||||
path("accounts/two_factor/totp/remove/", views.remove_totp, name="hc-remove-totp"),
|
||||
path(
|
||||
"two_factor/<uuid:code>/remove/",
|
||||
"accounts/two_factor/<uuid:code>/remove/",
|
||||
views.remove_credential,
|
||||
name="hc-remove-credential",
|
||||
),
|
||||
|
|
|
@ -2,26 +2,28 @@ from __future__ import annotations
|
|||
|
||||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from django.apps import AppConfig
|
||||
from django.conf import settings
|
||||
from django.core.checks import Error, Warning, register
|
||||
from django.http.request import split_domain_port, validate_host
|
||||
|
||||
|
||||
class ApiConfig(AppConfig):
|
||||
name = "hc.api"
|
||||
|
||||
|
||||
@register() # W001, W002
|
||||
@register() # W001, W002, W005, E002
|
||||
def settings_check(
|
||||
app_configs: Sequence[AppConfig] | None,
|
||||
databases: Sequence[str] | None,
|
||||
**kwargs: dict[str, Any],
|
||||
) -> list[Warning]:
|
||||
items = []
|
||||
) -> list[Error | Warning]:
|
||||
items: list[Error | Warning] = []
|
||||
|
||||
site_root_parts = settings.SITE_ROOT.split("://")
|
||||
if site_root_parts[0] not in ("http", "https"):
|
||||
site_root_parts = urlsplit(settings.SITE_ROOT)
|
||||
if not site_root_parts.scheme:
|
||||
items.append(
|
||||
Warning(
|
||||
"Invalid settings.SITE_ROOT value",
|
||||
|
@ -30,6 +32,16 @@ def settings_check(
|
|||
)
|
||||
)
|
||||
|
||||
host, _ = split_domain_port(site_root_parts.netloc)
|
||||
if site_root_parts.scheme and not validate_host(host, settings.ALLOWED_HOSTS):
|
||||
items.append(
|
||||
Error(
|
||||
"The hostname in settings.SITE_ROOT is not found in settings.ALLOWED_HOSTS",
|
||||
hint=f"Add '{host}' to settings.ALLOWED_HOSTS",
|
||||
id="hc.api.E002",
|
||||
)
|
||||
)
|
||||
|
||||
if not settings.EMAIL_HOST:
|
||||
items.append(
|
||||
Warning(
|
||||
|
@ -45,7 +57,7 @@ def settings_check(
|
|||
Warning(
|
||||
"settings.SECURE_PROXY_SSL_HEADER is not 2-element tuple",
|
||||
hint="See https://healthchecks.io/docs/self_hosted_configuration/#SECURE_PROXY_SSL_HEADER",
|
||||
id="hc.api.W003",
|
||||
id="hc.api.W005",
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -9,10 +9,15 @@ from hc.test import BaseTestCase
|
|||
@override_settings(EMAIL_HOST="localhost")
|
||||
class SystemChecksCase(BaseTestCase):
|
||||
@override_settings(SITE_ROOT="example.com")
|
||||
def test_it_validates_site_root(self) -> None:
|
||||
def test_it_validates_site_root_syntax(self) -> None:
|
||||
ids = [item.id for item in settings_check(None, None)]
|
||||
self.assertEqual(ids, ["hc.api.W001"])
|
||||
|
||||
@override_settings(SITE_ROOT="http://surprise.example.com")
|
||||
def test_it_checks_site_root_host_is_present_in_allowed_hosts(self) -> None:
|
||||
ids = [item.id for item in settings_check(None, None)]
|
||||
self.assertEqual(ids, ["hc.api.E002"])
|
||||
|
||||
@override_settings(EMAIL_HOST=None)
|
||||
def test_it_warns_about_missing_smtp_credentials(self) -> None:
|
||||
ids = [item.id for item in settings_check(None, None)]
|
||||
|
@ -21,4 +26,4 @@ class SystemChecksCase(BaseTestCase):
|
|||
@override_settings(SECURE_PROXY_SSL_HEADER="abc")
|
||||
def test_it_checks_secure_proxy_ssl_header_tupleness(self) -> None:
|
||||
ids = [item.id for item in settings_check(None, None)]
|
||||
self.assertEqual(ids, ["hc.api.W003"])
|
||||
self.assertEqual(ids, ["hc.api.W005"])
|
||||
|
|
|
@ -13,6 +13,7 @@ from pathlib import Path
|
|||
from typing import Any
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from django.http.request import split_domain_port
|
||||
import django_stubs_ext
|
||||
|
||||
django_stubs_ext.monkeypatch()
|
||||
|
@ -38,7 +39,6 @@ def envint(s: str, default: str) -> int | None:
|
|||
SECRET_KEY = os.getenv("SECRET_KEY", "---")
|
||||
METRICS_KEY = os.getenv("METRICS_KEY")
|
||||
DEBUG = envbool("DEBUG", "True")
|
||||
ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "*").split(",")
|
||||
DEFAULT_FROM_EMAIL = os.getenv("DEFAULT_FROM_EMAIL", "healthchecks@example.org")
|
||||
SUPPORT_EMAIL = os.getenv("SUPPORT_EMAIL")
|
||||
USE_PAYMENTS = envbool("USE_PAYMENTS", "False")
|
||||
|
@ -210,6 +210,14 @@ if PING_BODY_LIMIT and PING_BODY_LIMIT > 2621440:
|
|||
_site_root_parts = urlparse(SITE_ROOT)
|
||||
LOGIN_URL = f"{_site_root_parts.path}/accounts/login/"
|
||||
STATIC_URL = f"{_site_root_parts.path}/static/"
|
||||
if v := os.getenv("ALLOWED_HOSTS"):
|
||||
# If ALLOWED_HOSTS is set in environment, use it
|
||||
ALLOWED_HOSTS = v.split(",")
|
||||
else:
|
||||
# Otherwise, populate it with the domain from SITE_ROOT
|
||||
domain, _ = split_domain_port(_site_root_parts.netloc)
|
||||
ALLOWED_HOSTS = [domain]
|
||||
|
||||
STATICFILES_DIRS = [BASE_DIR / "static"]
|
||||
STATIC_ROOT = BASE_DIR / "static-collected"
|
||||
STATICFILES_FINDERS = (
|
||||
|
|
13
hc/urls.py
13
hc/urls.py
|
@ -14,18 +14,7 @@ if _path := urlparse(settings.SITE_ROOT).path.lstrip("/"):
|
|||
urlpatterns = [
|
||||
path(f"{prefix}admin/login/", accounts_views.login),
|
||||
path(f"{prefix}admin/", admin.site.urls),
|
||||
path(f"{prefix}accounts/", include("hc.accounts.urls")),
|
||||
path(f"{prefix}projects/add/", accounts_views.add_project, name="hc-add-project"),
|
||||
path(
|
||||
f"{prefix}projects/<uuid:code>/settings/",
|
||||
accounts_views.project,
|
||||
name="hc-project-settings",
|
||||
),
|
||||
path(
|
||||
f"{prefix}projects/<uuid:code>/remove/",
|
||||
accounts_views.remove_project,
|
||||
name="hc-remove-project",
|
||||
),
|
||||
path(prefix, include("hc.accounts.urls")),
|
||||
path(prefix, include("hc.api.urls")),
|
||||
path(prefix, include("hc.front.urls")),
|
||||
path(prefix, include("hc.payments.urls")),
|
||||
|
|
|
@ -89,7 +89,7 @@ from environment variables. Below is a list of environment variables it reads an
|
|||
|
||||
<h2 id="ADMINS"><code>ADMINS</code></h2>
|
||||
<p>Default: <code>""</code> (empty string)</p>
|
||||
<p>A comma-sepparated list of email addresses to send code error notifications to.
|
||||
<p>A comma-separated list of email addresses to send code error notifications to.
|
||||
When <code>DEBUG=False</code>, Healthchecks will send the details of exceptions raised in the
|
||||
request/response cycle to the listed addresses. Example:</p>
|
||||
<div class="highlight"><pre><span></span><code><span class="na">ADMINS</span><span class="o">=</span><span class="s">alice@example.org,bob@example.org</span>
|
||||
|
@ -98,13 +98,16 @@ request/response cycle to the listed addresses. Example:</p>
|
|||
<p>Note: for error notifications to work, make sure you have also specified working
|
||||
SMTP credentials in the <code>EMAIL_...</code> environment variables.</p>
|
||||
<h2 id="ALLOWED_HOSTS"><code>ALLOWED_HOSTS</code></h2>
|
||||
<p>Default: <code>*</code></p>
|
||||
<p>The host/domain names that this site can serve. You can specify multiple domain names
|
||||
by separating them with commas:</p>
|
||||
<div class="highlight"><pre><span></span><code><span class="na">ALLOWED_HOSTS</span><span class="o">=</span><span class="s">my-hc.example.org,alternative-name.example.org</span>
|
||||
<p>Default: the domain part of <code>SITE_ROOT</code></p>
|
||||
<p>The host/domain names that this site can serve. Healthchecks populates this setting
|
||||
automatically with the domain part of <a href="#SITE_ROOT">SITE_ROOT</a>. You do not need
|
||||
to set it unless you serve Healthchecks on more than one domain.</p>
|
||||
<p>If you do serve the same Healthchecks instance on more than one domain, specify
|
||||
them all in <code>ALLOWED_HOSTS</code>, separated by commas:</p>
|
||||
<div class="highlight"><pre><span></span><code><span class="na">ALLOWED_HOSTS</span><span class="o">=</span><span class="s">first.example.org,second.example.org</span>
|
||||
</code></pre></div>
|
||||
|
||||
<p>Apart from the comma-separated syntax, this is a standard Django setting.
|
||||
<p>Aside from the comma-separated syntax, this is a standard Django setting.
|
||||
Read more about it in the
|
||||
<a href="https://docs.djangoproject.com/en/5.1/ref/settings/#allowed-hosts">Django documentation</a>.</p>
|
||||
<h2 id="APPRISE_ENABLED"><code>APPRISE_ENABLED</code></h2>
|
||||
|
@ -515,8 +518,8 @@ other guarantee that it sets/strips this header appropriately.</p>
|
|||
<p><strong>Note on using <code>local_settings.py</code>:</strong>
|
||||
When Healthchecks reads settings from environment variables, it expects
|
||||
<code>SECURE_PROXY_SSL_HEADER</code> to contain header name and value, separated with comma.
|
||||
If you set <code>SECURE_PROXY_SSL_HEADER</code> in <code>local_settings.py</code>, it should be a
|
||||
a tuple with two elements instead:</p>
|
||||
If you set <code>SECURE_PROXY_SSL_HEADER</code> in <code>local_settings.py</code>, it should be a tuple
|
||||
with two elements instead:</p>
|
||||
<div class="highlight"><pre><span></span><code><span class="c1"># in local_settings.py</span>
|
||||
<span class="na">SECURE_PROXY_SSL_HEADER</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">("HTTP_X_FORWARDED_PROTO", "https")</span>
|
||||
</code></pre></div>
|
||||
|
@ -545,7 +548,7 @@ TCP socket.</p>
|
|||
</code></pre></div>
|
||||
|
||||
<p>Healthchecks uses <a href="https://github.com/AsamK/signal-cli">signal-cli</a> to send Signal
|
||||
notifications. Healthcecks interacts with signal-cli over UNIX or TCP socket (requires
|
||||
notifications. Healthchecks interacts with signal-cli over UNIX or TCP socket (requires
|
||||
signal-cli 0.10.0 or later).</p>
|
||||
<p>To enable the Signal integration:</p>
|
||||
<ul>
|
||||
|
@ -592,9 +595,14 @@ its web UI and documentation.</p>
|
|||
<h2 id="SITE_ROOT"><code>SITE_ROOT</code></h2>
|
||||
<p>Default: <code>http://localhost:8000</code></p>
|
||||
<p>The base URL of this Healthchecks instance. Healthchecks uses <code>SITE_ROOT</code> whenever
|
||||
it needs to construct absolute URLs.</p>
|
||||
it needs to construct absolute URLs. Healthchecks also uses <code>SITE_ROOT</code> to set
|
||||
several other settings, detailed below.</p>
|
||||
<p>If the <a href="#ALLOWED_HOSTS">ALLOWED_HOSTS</a> setting is not set, Healthchecks
|
||||
automatically populates it with the domain part of <code>SITE_ROOT</code>. Under typical scenarios
|
||||
you can use the automatically populated value and do not need to set
|
||||
<code>ALLOWED_HOSTS</code> yourself.</p>
|
||||
<p>If the SITE_ROOT contains a path (for example, <code>http://localhost:8000<b>/prefix</b></code>),
|
||||
then Healthchecks will automatically set the following additional Django settings:</p>
|
||||
then Healthchecks automatically sets the following additional Django settings:</p>
|
||||
<ul>
|
||||
<li><code>LOGIN_URL=<b>/prefix</b>/accounts/login/</code>. Required
|
||||
for correct redirection to a log-in page when an unauthenticated user requests a
|
||||
|
@ -608,7 +616,8 @@ setting, read more about it in
|
|||
</ul>
|
||||
<p><strong>On using <code>local_settings.py</code>:</strong> Healthchecks only sets the above additional settings
|
||||
if you specify <code>SITE_ROOT</code> via an environment variable. If you instead specify it in
|
||||
<code>local_settings.py</code>, you will also need to set <code>LOGIN_URL</code>and <code>STATIC_URL</code> there.</p>
|
||||
<code>local_settings.py</code>, you will also need to set <code>ALLOWED_HOSTS</code>, <code>LOGIN_URL</code>, and
|
||||
<code>STATIC_URL</code> there.</p>
|
||||
<h2 id="SLACK_CLIENT_ID"><code>SLACK_CLIENT_ID</code></h2>
|
||||
<p>Default: <code>None</code></p>
|
||||
<p>The Slack Client ID, used by the Healthchecks integration for Slack.</p>
|
||||
|
|
|
@ -93,7 +93,7 @@ from environment variables. Below is a list of environment variables it reads an
|
|||
|
||||
Default: `""` (empty string)
|
||||
|
||||
A comma-sepparated list of email addresses to send code error notifications to.
|
||||
A comma-separated list of email addresses to send code error notifications to.
|
||||
When `DEBUG=False`, Healthchecks will send the details of exceptions raised in the
|
||||
request/response cycle to the listed addresses. Example:
|
||||
|
||||
|
@ -106,16 +106,20 @@ SMTP credentials in the `EMAIL_...` environment variables.
|
|||
|
||||
## `ALLOWED_HOSTS` {: #ALLOWED_HOSTS }
|
||||
|
||||
Default: `*`
|
||||
Default: the domain part of `SITE_ROOT`
|
||||
|
||||
The host/domain names that this site can serve. You can specify multiple domain names
|
||||
by separating them with commas:
|
||||
The host/domain names that this site can serve. Healthchecks populates this setting
|
||||
automatically with the domain part of [SITE_ROOT](#SITE_ROOT). You do not need
|
||||
to set it unless you serve Healthchecks on more than one domain.
|
||||
|
||||
If you do serve the same Healthchecks instance on more than one domain, specify
|
||||
them all in `ALLOWED_HOSTS`, separated by commas:
|
||||
|
||||
```ini
|
||||
ALLOWED_HOSTS=my-hc.example.org,alternative-name.example.org
|
||||
ALLOWED_HOSTS=first.example.org,second.example.org
|
||||
```
|
||||
|
||||
Apart from the comma-separated syntax, this is a standard Django setting.
|
||||
Aside from the comma-separated syntax, this is a standard Django setting.
|
||||
Read more about it in the
|
||||
[Django documentation](https://docs.djangoproject.com/en/5.1/ref/settings/#allowed-hosts).
|
||||
|
||||
|
@ -734,8 +738,8 @@ other guarantee that it sets/strips this header appropriately.
|
|||
**Note on using `local_settings.py`:**
|
||||
When Healthchecks reads settings from environment variables, it expects
|
||||
`SECURE_PROXY_SSL_HEADER` to contain header name and value, separated with comma.
|
||||
If you set `SECURE_PROXY_SSL_HEADER` in `local_settings.py`, it should be a
|
||||
a tuple with two elements instead:
|
||||
If you set `SECURE_PROXY_SSL_HEADER` in `local_settings.py`, it should be a tuple
|
||||
with two elements instead:
|
||||
|
||||
```ini
|
||||
# in local_settings.py
|
||||
|
@ -779,7 +783,7 @@ SIGNAL_CLI_SOCKET=example.org:7583
|
|||
```
|
||||
|
||||
Healthchecks uses [signal-cli](https://github.com/AsamK/signal-cli) to send Signal
|
||||
notifications. Healthcecks interacts with signal-cli over UNIX or TCP socket (requires
|
||||
notifications. Healthchecks interacts with signal-cli over UNIX or TCP socket (requires
|
||||
signal-cli 0.10.0 or later).
|
||||
|
||||
To enable the Signal integration:
|
||||
|
@ -844,10 +848,16 @@ its web UI and documentation.
|
|||
Default: `http://localhost:8000`
|
||||
|
||||
The base URL of this Healthchecks instance. Healthchecks uses `SITE_ROOT` whenever
|
||||
it needs to construct absolute URLs.
|
||||
it needs to construct absolute URLs. Healthchecks also uses `SITE_ROOT` to set
|
||||
several other settings, detailed below.
|
||||
|
||||
If the [ALLOWED_HOSTS](#ALLOWED_HOSTS) setting is not set, Healthchecks
|
||||
automatically populates it with the domain part of `SITE_ROOT`. Under typical scenarios
|
||||
you can use the automatically populated value and do not need to set
|
||||
`ALLOWED_HOSTS` yourself.
|
||||
|
||||
If the SITE_ROOT contains a path (for example, <code>http://localhost:8000<b>/prefix</b></code>),
|
||||
then Healthchecks will automatically set the following additional Django settings:
|
||||
then Healthchecks automatically sets the following additional Django settings:
|
||||
|
||||
* <code>LOGIN_URL=<b>/prefix</b>/accounts/login/</code>. Required
|
||||
for correct redirection to a log-in page when an unauthenticated user requests a
|
||||
|
@ -861,7 +871,8 @@ setting, read more about it in
|
|||
|
||||
**On using `local_settings.py`:** Healthchecks only sets the above additional settings
|
||||
if you specify `SITE_ROOT` via an environment variable. If you instead specify it in
|
||||
`local_settings.py`, you will also need to set `LOGIN_URL`and `STATIC_URL` there.
|
||||
`local_settings.py`, you will also need to set `ALLOWED_HOSTS`, `LOGIN_URL`, and
|
||||
`STATIC_URL` there.
|
||||
|
||||
## `SLACK_CLIENT_ID` {: #SLACK_CLIENT_ID }
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue