Configuration
MyAstroBoard stores its runtime configuration in its database (data/myastroboard.db, see DATABASE.md); /api/config/export downloads it as config.json. All settings are managed through the App settings tab (admin only) in the UI or via the /api/config endpoint.
App settings tab layout
| Sub-tab | Content |
|---|---|
| Locations | Location presets: coordinates, timezone, sky quality, horizon profile, user attribution (see LOCATIONS.md) |
| Configuration | Astrodex privacy, SkyTonight constraints, push notification contact email, privacy & search engines, reverse proxy and external base URL, MQTT connections, Run SkyTonight now |
| Connectors | External tool connectors (AllSky, etc.) |
| Logs | Live log viewer, log levels and retention, log export |
| Users | User management, trusted networks and two-factor authentication policy (admin only) |
| Metrics | Scheduler and cache performance dashboard |
| Backup / Restore | Download and restore backup archives, 1.7 upgrade archive |
Locations (multi-location profiles)
Since v1.2, the configuration holds an admin-managed locations list (up to MAX_LOCATIONS = 5 presets) instead of a single location object. At least one preset is required before most calculations can run; editing a preset’s coordinates resets only that preset’s caches.
Full reference - data model, attribution, per-user default/active location, rate-limit analysis behind the cap: LOCATIONS.md.
Each preset carries:
| Field | Description | Default |
|---|---|---|
id | Server-generated uuid4, immutable | - |
name | Human-readable site name | "Paris" |
latitude | Decimal degrees, −90 to +90 | 48.866669 |
longitude | Decimal degrees, −180 to +180 | 2.33333 |
elevation | Altitude above sea level in metres | 35 |
timezone | IANA timezone string (e.g. Europe/Paris) | "Europe/Paris" |
bortle / sqm | Sky quality (see below) | null |
horizon_profile | Per-preset horizon mask (see below) | [] |
is_install_default | Exactly one preset carries true | first preset |
The timezone field determines how all local times (moonrise, sunset, event times…) are displayed throughout the app for users observing from that preset. GET /api/timezones returns all valid IANA timezone strings for the dropdown.
A coordinate converter is available at POST /api/convert-coordinates to translate between decimal degrees and DMS (degrees/minutes/seconds).
Legacy single-location configs are migrated automatically on first load after upgrade (the old location key and the old global horizon profile move onto the first preset - zero manual action required).
Sky quality (light pollution)
Set per location preset:
| Field | Description |
|---|---|
bortle | Bortle class 1-9 (optional). Determines the SQM midpoint estimate. |
sqm | Sky Quality Meter reading in mag/arcsec² (optional, overrides Bortle midpoint). |
See SKYTONIGHT.md - Light Pollution Integration for how these values affect AstroScore.
SkyTonight constraints
These values live under skytonight.constraints in the configuration. They define which objects are considered observable. All constraints are always active.
| Parameter | Default | Description |
|---|---|---|
altitude_constraint_min | 30° | Minimum target altitude above the horizon |
altitude_constraint_max | 80° | Maximum target altitude (avoids zenith blind spot for some mounts) |
airmass_constraint | 2.0 | Maximum airmass (≈ 30°+ elevation) |
size_constraint_min | 0 arcmin | Minimum angular size for DSOs (0 = no lower limit) |
size_constraint_max | 300 arcmin | Maximum angular size |
moon_separation_min | 45° | Minimum angular distance from the Moon |
moon_separation_use_illumination | true | When true, overrides moon_separation_min with Moon illumination % -> degrees (e.g. 60 % full Moon -> 60° separation required) |
fraction_of_time_observable_threshold | 0.50 | DSOs must be within all constraints for ≥ 50 % of the night to appear in results |
north_to_east_ccw | false | Azimuth convention: false = clockwise from North (standard); true = counter-clockwise |
Custom horizon profile
Since v1.2 the horizon profile is a per-location preset field (locations[].horizon_profile, edited in the location’s edit modal) instead of the former global skytonight.constraints.horizon_profile. It stores an array of [azimuth, altitude] pairs that describe the site’s local horizon mask - mountains, buildings, or trees that block the view at specific azimuths.
"horizon_profile": [
[0, 5],
[45, 15],
[90, 8],
[180, 2],
[270, 6],
[315, 10]
]
SkyTonight evaluates each target against the horizon profile: if the object’s altitude at a given azimuth is below the profile altitude for that direction, it counts as blocked. Targets are scored only during the fraction of time they clear both the global altitude_constraint_min and the horizon profile.
The profile is set in App settings -> Locations -> (edit a preset) -> Custom Horizon Profile. Enter points manually per location.
Scheduler configuration
Configuration key: skytonight.scheduler
| Field | Description |
|---|---|
mode | "astro" (runs at dawn+1h and dusk−1h) or "fallback-6h" (runs every 6 hours when clock is unreliable) |
server_time_valid | true when the system clock is considered accurate (NTP synced) |
See SKYTONIGHT.md - Scheduler for scheduling logic.
Dataset configuration
Configuration key: skytonight.datasets
| Field | Default | Description |
|---|---|---|
datasets.catalogues.deep_sky | true | Enable DSO catalogue processing |
datasets.catalogues.bodies | true | Enable solar-system body calculations |
datasets.catalogues.comets | true | Enable comet processing |
datasets.comets.source | "mpc+jpl" | Comet orbital data source: "mpc", "jpl", or "mpc+jpl" |
datasets.comets.auto_update | true | Automatically refresh comet elements before each calculation |
Application settings (admin)
Stored separately (database setting app_settings, see AUTHENTICATION.md):
| Setting | Default | Description |
|---|---|---|
vapid_contact_email | "" | Contact email for Web Push VAPID tokens (required for iOS push) |
trust_proxy_headers | false | Enable X-Forwarded-For / X-Forwarded-Proto forwarding (reverse proxy deployments) |
session_cookie_secure | false | Require HTTPS for session cookie |
external_base_url | "" | http(s):// address other software reaches this instance at: Astrodex stream URLs and the MyAstroShine return address (whose own callback_url_override still wins). Empty = the address of the current request. Required under the Home Assistant sidebar panel (ingress), whose URL needs an HA login. Set in App settings -> Configuration -> Reverse proxy |
search_engine_indexing | false | Allow search engines to crawl and index the login page. Off by default for privacy: /robots.txt returns Disallow: / and the login page is served with noindex, nofollow. When enabled, /robots.txt allows /login and the login page adds Open Graph/JSON-LD metadata pointing to myastroboard.org |
log_retention_days | 90 | Days a line stays in myastroboard.log and its rotated backups (0-3650). Log lines hold usernames and IP addresses, so older lines are removed once a day per process, and right away when the value is lowered. 0 disables it: only the size-based rotation (10 MB x 6 files) applies. Set in App settings -> Logs |
log_level | "INFO" | Level written to myastroboard.log (DEBUG, INFO, WARNING, ERROR, CRITICAL). Applies without a restart. The LOG_LEVEL environment variable, when set, overrides it. Set in App settings -> Logs |
console_log_level | "WARNING" | Level of the container output (docker logs, the Log tab of the Home Assistant app). The CONSOLE_LOG_LEVEL environment variable, when set, overrides it. Set in App settings -> Logs |
MQTT connections
Sub-tab: App settings -> Configuration
The MQTT brokers the MQTT connectors talk to, stored under mqtt_connections; each connector
picks one by id (connectors.mqtt.mqtt_connection_id). The password is kept in the connector
secrets store, never in the configuration. See
HOME_ASSISTANT.md and
CONNECTORS.md.
"mqtt_connections": [
{
"id": "home-assistant",
"name": "Home Assistant",
"url": "mqtt://192.168.1.10:1883",
"username": "myastroboard",
"tls_insecure": false
}
]
Connectors
Sub-tab: App settings -> Connectors
Connector configuration is stored in the configuration under connectors.<name>. See CONNECTORS.md for the full reference.
"connectors": {
"allsky": {
"url": "http://allsky.local",
"label": "My AllSky",
"enabled": true,
"image_path": "current",
"image_filename": "image.jpg",
"mqtt_connection_id": "home-assistant",
"mqtt_topic": "allsky",
"client_id": "",
"modules": {
"live_image": { "enabled": true },
"sensor_data": { "enabled": false },
"keogram": { "enabled": true },
"startrails": { "enabled": false },
"daily_timelapse": { "enabled": false }
}
}
}
Backup and restore
Sub-tab: App settings -> Backup / Restore
Download backup
GET /api/backup/download produces a ZIP archive, built from the database in the same JSON
layout as 1.6 backups:
| File / folder | Content |
|---|---|
config.json | All site configuration |
app_settings.json | App settings (App settings -> Configuration) |
users.json | All user accounts (with password hashes) |
astrodex/ | All Astrodex collections (one JSON per user + images/ subdirectory) |
equipments/ | All equipment profiles (one JSON per user per equipment type) |
observation_sessions/ | All observation logs (one JSON per user + attachments/ subdirectory) |
wishlist/ | All wishlists (one JSON per user) |
The archive is named myastroboard_backup_<timestamp>.zip.
Not included: the security settings (trusted networks, instance-wide 2FA switch) are
deliberately excluded from both the backup ZIP and /api/config/export, for the same reason as
trust_proxy_headers: a LAN CIDR block from one install is meaningless - or actively wrong - on a
restored host. Re-configure trusted networks by hand after a restore on a different machine. See
also docs/AUTHENTICATION.md.
Restore backup
POST /api/backup/restore (multipart form, field file) accepts a backup ZIP (from 1.7 or 1.6) and restores its contents. Every entry is validated before anything is written, then the database is updated in one transaction: each folder present in the archive replaces that kind of data, and users.json replaces the account list (accounts absent from it are deleted with their data). Documents of accounts that are not in the database are skipped.
After a restore: every gunicorn worker picks the restored data up on its next request. A page reload is required to reflect restored user accounts.
Logs
Sub-tab: App settings -> Logs
Live log viewer
GET /api/logs returns the tail of data/logs/myastroboard.log for live viewing in the browser. The active levels can be checked with GET /api/logs/level ({"level": <log file>, "console_level": <console>}).
Log levels
Set in App settings -> Logs: one level for the log file (default INFO) and one for the console output
(default WARNING) - see log_level / console_log_level in Application settings.
To troubleshoot, set the log file level to DEBUG, reproduce the issue, then export the logs. A change applies
right away, without a restart (the other gunicorn worker follows within a few seconds). The LOG_LEVEL /
CONSOLE_LOG_LEVEL environment variables still work and, when set, take precedence: the matching setting is
then shown disabled in the UI.
Log lines are JSONL-formatted (one JSON object per line): {"level": "INFO", "time": "...", "msg": "...", "module": "..."}.
Export logs
GET /api/logs/export downloads a ZIP archive containing:
myastroboard.log- main application logskytonight/logs/last_calculation.log- last SkyTonight run log
Attach this file to GitHub issues to help maintainers diagnose problems.
Clear logs
POST /api/logs/clear truncates the main log file (admin only).
Retention
Besides the size-based rotation, lines older than log_retention_days (default 90, see
Application settings) are removed from the main log and its backups. See
Privacy & GDPR.
Metrics
Sub-tab: App settings -> Metrics (admin only)
GET /api/metrics returns system metrics including:
| Section | Content |
|---|---|
| Cache jobs | Per-job TTL, last run time, duration, success/failure |
| Scheduler | SkyTonight scheduler status and last run |
| System | Uptime, Python version, worker count |
The metrics tab is the first place to check if a cache job is repeatedly failing or taking unexpectedly long.
App restart
POST /api/admin/restart (admin only) triggers a graceful application restart. This is needed after changes to the app settings that affect Flask configuration (e.g. enabling session_cookie_secure).
Configuration API
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /api/config | login | Read full config; also exposes the caller’s active location under location (compat shim) |
POST | /api/config | admin | Save global config; a legacy location payload updates the install default preset (its caches only are reset) |
| - | /api/locations* | admin/login | Location preset CRUD, attribution, switcher - see LOCATIONS.md and API_ENDPOINTS.md |
GET | /api/config/export | admin | Download the configuration as config.json |
GET | /api/skyquality | login | Current sky quality parameters and computed LP factor |
GET | /api/admin/app-settings | admin | Read the app settings |
POST | /api/admin/app-settings | admin | Save the app settings |
POST | /api/admin/restart | admin | Restart the app |
GET | /api/backup/download | admin | Download backup ZIP |
POST | /api/backup/restore | admin | Restore from backup ZIP |
GET | /api/logs | admin | Tail of main log file |
GET | /api/logs/level | admin | Current log level |
POST | /api/logs/clear | admin | Truncate log file |
GET | /api/logs/export | admin | Download log ZIP |
GET | /api/metrics | admin | System and cache metrics |
GET | /api/version | login | Current app version from VERSION file |
GET | /api/version/check-updates | login | Compare against latest GitHub release |
GET | /api/timezones | login | All valid IANA timezone strings |
POST | /api/convert-coordinates | login | Convert DMS <-> decimal degrees |
GET | /api/health | Public | Health check (returns {"status": "ok"}) |
GET | /api/catalogues | login | List all loaded SkyTonight catalogue counts |
Last updated 2026-11-13