A modern web application providing a user interface for the CANFAR (Canadian Advanced Network for Astronomical Research) platform. Science Portal enables researchers to access and manage JupyterLab notebooks, CARTA, Desktop (VNC), and other interactive sessions backed by CANFAR resources.
Platform load information is available, including current CPU usage and counts of running instances.
This CANFAR service provides the ability to access and manage Jupyter notebook, desktop (VNC), and CARTA sessions that back onto CANFAR resources. Using container images and current system resource values (context) provided by Skaha, you can launch and manage sessions using the container image you select. Contextualization is provided for some session types, allowing the amount of memory, number of cores, and GPU resources you designate to power your session.
- Session Management - Launch, monitor, renew, and delete computational sessions
- Container Applications - Access JupyterLab notebooks, CARTA, Desktop (VNC), and other research tools
- Resource Selection - Configure memory, CPU cores, and GPU resources with interactive controls
- Platform Monitoring - Real-time metrics for platform load and resource usage
- Storage Management - View and manage user storage quota
- Session Logs & Events - View logs and events for running sessions
- Dual Authentication - Supports both CANFAR and OIDC authentication modes
- Responsive Design - Mobile-friendly interface with light/dark theme support
All endpoints require authentication with CANFAR, and authorization to access Skaha resource allocations.
| Service | URL |
|---|---|
| Science Portal | https://www.canfar.net/science-portal |
| Skaha Web Service | https://ws-uv.canfar.net/skaha |
Science Portal supports OpenID Connect in the Next.js app (NextAuth). For registering URIs at your identity provider and for environment variables, see Deploying with OIDC under Deployment below and .env.example. Older servlet-based deployments may still document oidc settings in org.opencadc.science-portal.properties.
All workflows assume you are logged in with a CADC account.
- From the main page: https://www.canfar.net/science-portal
- Science Portal will display any sessions you currently have, including session metadata
- Clicking on a session card will connect to and forward you to the session
- From the main page: https://www.canfar.net/science-portal
- Science Portal will poll for and display any sessions you currently have
- After the form has loaded, scroll down to access the launch form
- Select the type of session you want to launch (default is 'notebook')
- The container image list will be updated for the session type
- Optionally change the name of the session, and any available context values (memory, cores, or GPU)
- Select 'Launch'
- Science Portal will request the session be started
- The new session will be added to the list at the top of the page
- From the main page: https://www.canfar.net/science-portal
- Science Portal will display any sessions you currently have
- Clicking on the trash can icon on a session card will bring up a confirmation box
- Continue to delete or cancel
- Science Portal will request the session be deleted, and will remove it from your session list
- From the main page: https://www.canfar.net/science-portal
- Science Portal will display any sessions you currently have
- Click on the clock icon on a session card
- Science Portal will request the session time frame be renewed (this is a 4-day extension from the time the request is submitted)
- Session metadata will be refreshed on the portal
- From the main page: https://www.canfar.net/science-portal
- The Platform Load panel displays current resource usage information
- Click the refresh button to refresh values
- A timestamp indicates the time of the last refresh
- From the main page: https://www.canfar.net/science-portal
- In the Active Sessions panel, each Session Card has buttons for events (flag) and logs (file)
- Click on either button
- A new tab is opened displaying the output from the Skaha service with available event list or logs
- Framework: Next.js 15 with App Router
- Language: TypeScript 5
- UI: Material-UI 7, Tailwind CSS 4
- State Management: Zustand, TanStack React Query
- Authentication: NextAuth 5 (CANFAR/OIDC modes)
- Runtime: Node.js 22+
Dependencies for building are:
- Node.js 22.11 or later
- npm or yarn
# Clone the repository
git clone git@github.com:opencadc/science-portal.git
cd science-portal
# Install dependencies
npm install
# Copy environment configuration
cp .env.example .env.localConfigure the following environment variables in .env.local:
| Variable | Description |
|---|---|
NEXT_PUBLIC_LOGIN_API |
Authentication API endpoint |
NEXT_PUBLIC_SKAHA_API |
Session/compute API endpoint |
NEXT_PUBLIC_API_TIMEOUT |
API request timeout (default: 30000ms) |
AUTH_SECRET |
NextAuth secret key |
NEXT_USE_CANFAR |
Toggle between CANFAR/OIDC auth mode |
When NEXT_USE_CANFAR=false (and matching NEXT_PUBLIC_USE_CANFAR), also configure OIDC issuer, client, NEXTAUTH_URL, NEXT_OIDC_REDIRECT_URI / NEXT_PUBLIC_OIDC_REDIRECT_URI, and NEXT_OIDC_CALLBACK_URI / NEXT_PUBLIC_OIDC_CALLBACK_URI—see .env.example. Full deployment notes including IdP redirect registration are under Deploying with OIDC.
# Start development server with Turbopack
npm run dev
# Run linting
npm run lint
# Format code
npm run formatThe application will be available at http://localhost:3000.
# Build for production
npm run build
# Start production server
npm startsrc/
├── app/ # Next.js App Router
│ ├── api/ # API routes (auth, sessions, storage)
│ ├── components/ # UI components (Material-UI based)
│ ├── science-portal/ # Main portal pages
│ ├── providers/ # React context providers
│ └── contexts/ # Shared state contexts
├── lib/ # Shared libraries
│ ├── api/ # API client functions
│ ├── auth/ # Authentication helpers
│ ├── config/ # Configuration files
│ ├── hooks/ # Custom React hooks
│ ├── stores/ # Zustand state stores
│ └── utils/ # Utility functions
└── types/ # TypeScript definitions
Build the production image (standalone Node server on port 3000):
docker build -t science-portal .Run a minimal container. The app is served under NEXT_PUBLIC_BASE_PATH (defaults to /science-portal in the Dockerfile), so open http://localhost:3000/science-portal unless you use an empty base path at build time.
docker run --rm \
-p 3000:3000 \
-e AUTH_SECRET='replace-with-a-long-random-string' \
-e NEXT_USE_CANFAR=true \
-e LOGIN_API='https://ws-cadc.canfar.net/ac' \
-e SKAHA_API='https://ws-uv.canfar.net/skaha' \
-e SERVICE_STORAGE_API='https://ws-uv.canfar.net/arc/nodes/home/' \
science-portalAdjust the three API URLs for your environment. For OIDC mode, follow Deploying with OIDC below instead of the CANFAR URLs above.
You can also use Docker Compose:
docker-compose up --buildExample compose files that wire OIDC env vars include docker-compose.oidc.example.yml.
Use OIDC mode when NEXT_USE_CANFAR=false and NEXT_PUBLIC_USE_CANFAR=false. Supply AUTH_SECRET and set NEXTAUTH_URL to the public URL visitors use for this deployment (scheme, host, and non-default port if any). Behind a reverse proxy that terminates TLS, set AUTH_TRUST_HOST=true (or AUTH_URL) so redirects and cookie security match HTTPS; align this with .env.example comments.
Define your IdP (NEXT_OIDC_URI, NEXT_OIDC_CLIENT_ID, NEXT_OIDC_CLIENT_SECRET, NEXT_OIDC_SCOPE) plus the mirrored NEXT_PUBLIC_OIDC_* values for client-side discovery. OIDC-backed deployments normally use SRC_SKAHA_API / SRC_CAVERN_API instead of CANFAR LOGIN_API/SKAHA_API—see .env.example.
Naming in this codebase:
-
Redirect URI (
NEXT_OIDC_REDIRECT_URI/NEXT_PUBLIC_OIDC_REDIRECT_URI) — OAuth 2 authorization-coderedirect_uri. Sent to the IdP and handled by Auth.js / NextAuth at/api/auth/callback/oidc. This value must exactly match an allowed redirect URI in your IdP registration (often called “Redirect URIs”, “Valid redirect URIs”, or callback URLs). -
Callback URI (
NEXT_OIDC_CALLBACK_URI/NEXT_PUBLIC_OIDC_CALLBACK_URI) — The portal’s public landing URL for this build (usually the UI root). It is required in configuration and must match how users reach the app; register it too if your IdP asks for origins, post-login URLs, or CORS/Web origins separately.
Express both using your public origin (no trailing path beyond what you need for the host) plus NEXT_PUBLIC_BASE_PATH (empty for root deployments, otherwise e.g. /science-portal):
| Concept | Typical URL |
|---|---|
| Register with IdP as OAuth redirect | {ORIGIN}{BASE}/api/auth/callback/oidc |
| Set redirect env vars to | same as the row above |
| Set callback env vars to | {ORIGIN}{BASE} (portal entry; optionally with a trailing / consistent with how you expose the app) |
Here {ORIGIN} is whatever you effectively use as the site URL (e.g. https://www.canfar.net or http://localhost:3000), and {BASE} is NEXT_PUBLIC_BASE_PATH with no duplicate slashes when concatenating.
Examples:
-
Production-style host with base path:
ORIGIN=https://www.canfar.net,BASE=/science-portal→ register and sethttps://www.canfar.net/science-portal/api/auth/callback/oidc; set callback env vars tohttps://www.canfar.net/science-portal. -
npm run devon port3000with no base path: registerhttp://localhost:3000/api/auth/callback/oidc; set callback vars tohttp://localhost:3000/(see .env.example for the exact defaults your team prefers).
Never omit {BASE} from the OAuth path when NEXT_PUBLIC_BASE_PATH is set; browsers invoke NextAuth at {BASE}/api/auth/*.
Helm charts are provided for Kubernetes deployment. See the Helm documentation for detailed instructions.
# Quick start with Helm
helm install science-portal ./helm/science-portalFor deployment mode details (CANFAR vs OIDC), refer to DEPLOYMENT-MODES.md.
- Development Guide - Local development setup and testing
- Helm Deployment - Kubernetes deployment with Helm
- Kubernetes Guide - Complete K8s deployment instructions
| Command | Description |
|---|---|
npm run dev |
Start development server with Turbopack |
npm run build |
Build for production |
npm start |
Start production server |
npm run lint |
Run ESLint |
npm run format |
Format code with Prettier |
npm run format:check |
Check code formatting |
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is part of the OpenCADC initiative and is licensed under GPL-3.0.