STAIRS is a specialized planning tool designed for astrophotography enthusiasts with smart telescopes (like the Seestar S50) to assist with the planning of imaging sessions. It takes into account telescope specifications, target suitability, sky conditions, and user preferences to score objects.
A lot of apps will tell you what is in the sky, but not how to build an efficient imaging plan. STAIRS does both and optimizes for specific equipment.
Note
If you are looking for instructions on how to run STAIRS via Docker (the recommended method), see here.
- Optimal Window Calculation: Determines the best start/end times for targets based on altitude thresholds and environment.
- Multi-Target Sequencing: Creates a chronological plan to image multiple targets in one session.
- Session Logging: log sessions and document what you have captured
- Multi-Night Forecasting: sky conditions forecasting for multiple nights
- Multi-Location Forecasting: sky conditions forecasting for multiple locations
Click to view application screenshots
The Sky Dashboard showing current conditions and recommended targets for Nashville, TN.
- Backend/API: Python with astroplan, Astropy, DuckDB, Swagger, and others (see the pyproject.toml file for more dependencies)
- Weather Information: provided by Open-Meteo
- CLI: Python with Typer and others (see the pyproject.toml file for more info)
- Web: React (TypeScript) with Vite, Tailwind CSS v4, Chart.js, and Lucide Icons
- Docker: designed first and foremost to be run via Docker and Docker Compose
For information on how to contribute and perform a new release, see the Release Guide.
- Docker and Docker Compose (Recommended for most users)
- Python 3.14+ (For local backend development)
- Node.js 22+ (For local web development)
Before running STAIRS, you must create a configuration file:
- Clone the repository:
git clone https://github.com/thomasehardt/STAIRS.git cd STAIRS - Create your own configuration file from the example:
cp .config.yaml.example config.yaml
- Edit
config.yamland update the information accordingly (the example config is well-documented).
Running STAIRS directly on your machine without Docker is useful for development and debugging.
-
Navigate to the API directory:
cd services/api -
Create and activate a virtual environment:
python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate
-
Install dependencies in editable mode:
pip install -e . -
Run the API (from the project root):
# Return to root cd ../.. export PYTHONPATH=$(pwd)/services/api uvicorn src.api.main:app --reload
The API will be available at http://localhost:8000
Tip: You can override default paths using environment variables:
CONFIG_FILE: Path toconfig.yaml(default:config.yaml)DATA_DIR: Path to thedatadirectory (default:data)CACHE_DIR: Path to thecachedirectory (default:cache)LOG_DIR: Path to thelogsdirectory (default:logs)
- Navigate to the web directory:
cd services/web - Install dependencies:
npm install
- Run the development server:
The UI will be available at http://localhost:5173
npm run dev
- Navigate to the CLI directory:
cd services/cli - Create and activate a virtual environment:
python -m venv .venv source .venv/bin/activate - Install the CLI tool:
pip install -e . - Use the
stairscommand:stairs --help
Running with Docker Compose allows you to spin up the entire stack with a single command, building from your local source code.
docker compose up --build- Production-like UI: Available at http://localhost:3000
- Development UI (with HMR): Available at http://localhost:5173 (via
docker compose up web-dev) - API Docs: Available at http://localhost:8000/docs
docker compose run --rm -it cli statusTip: Create an alias for easier access: alias stairs-cli="docker compose run --rm -it cli"
For production or simple deployment, you can run STAIRS using pre-built images from the GitHub Container Registry.
Prior to running STAIRS via Docker, you will need to do the following:
- create a file named
config.yaml(use .config.yaml.example as a base). - create directories (this prevents Docker from creating directories/files as
root):mkdir -p logs cache
The repository provides a docker-compose.prod.yaml configured to use images from the GitHub Container Registry.
Run with:
docker compose -f docker-compose.prod.yaml up -dThis will start the Web and API layers. You can then use the CLI via the same configuration (see below for aliases).
services:
api:
image: ghcr.io/thomasehardt/stairs/stairs-api:latest
container_name: stairs-api
ports:
- "8000:8000"
volumes:
- ./config.yaml:/app/config.yaml
- ./data:/app/data:ro
- ./cache:/app_data/cache
- ./logs:/app_data/logs
restart: unless-stopped
web:
image: ghcr.io/thomasehardt/stairs/stairs-web:latest
container_name: stairs-web
ports:
- "3000:80"
environment:
- VITE_API_URL=http://localhost:8000
depends_on:
- api
restart: unless-stopped
cli:
image: ghcr.io/thomasehardt/stairs/stairs-cli:latest
container_name: stairs-cli
environment:
- API_URL=http://api:8000
depends_on:
- api
Run with:
docker compose -f docker-compose.prod.yaml up -dTo start the Web and API layers (see below for an alias to use the CLI from Docker).
Once started, the API layer will initialize a cache to store ephemeris and weather data. If you go to http://localhost:8000, you will be presented with the Swagger API page. This can be used to test and verify the application is working.
Alternatively, you can check the status (among many other things) with the cli:
docker compose run --rm -it cli status
For help with the cli application, there's a very useful help function:
docker compose run --rm -it cli --help
It is recommended that you create an alias for running the cli ... on Mac/Linux:
alias stairs-cli="docker compose run --rm -it cli"

