Files
urapt/urapt-web/README.md
T
owen 2a1ed3af04
CI / Test (linux/amd64) (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Cross-build (darwin/amd64) (push) Waiting to run
CI / Cross-build (linux/amd64) (push) Waiting to run
CI / Cross-build (darwin/arm64) (push) Waiting to run
CI / Cross-build (linux/arm64) (push) Waiting to run
Normalize Railway upstream URL for web proxy
2026-06-29 20:37:33 -05:00

135 lines
4.3 KiB
Markdown

# urapt-web
The web UI for [urapt](https://github.com/owenqwenstarsky/urapt), a self-hostable
APT repository server. A React single-page app that talks to a urapt-server's
REST API (`/api/v1`) to manage repositories, members, distributions, packages,
tokens, and users — full management parity with the `urapt` CLI.
## Stack
- **Vite** + **React 18** + **TypeScript**
- **Tailwind CSS** + **shadcn/ui** (New York, neutral)
- **React Router v7**, **TanStack Query v5**, **Zustand**, **Vitest**
## Requirements
- Node.js 20+ (see `.nvmrc`) and pnpm 10+
## Development
Start a local urapt-server (from the repo root):
```bash
make run-server # listens on 0.0.0.0:8080
```
Then in `urapt-web/`:
```bash
pnpm install
pnpm dev # http://localhost:5173
```
Vite proxies `/api` and `/apt` to `http://localhost:8080` (override with the
`URAPT_SERVER` env var), so the UI is same-origin with the API in dev — no CORS
needed. If `needs_setup` is true (no users yet), you'll be sent to the first-run
setup screen to create the admin account.
## Scripts
| Script | Description |
| ---------------- | ------------------------------------ |
| `pnpm dev` | Start the Vite dev server |
| `pnpm build` | Type-check and build to `dist/` |
| `pnpm preview` | Preview the production build locally |
| `pnpm typecheck` | Run `tsc` with no emit |
| `pnpm lint` | Run ESLint |
| `pnpm format` | Run Prettier (write) |
| `pnpm test` | Run Vitest once |
## Configuration
| Env var | Default | Notes |
| ------------------- | ----------------------- | -------------------------------------------------------------------------------- |
| `VITE_API_BASE_URL` | `/api/v1` | REST API base. Override only for cross-origin dev (requires CORS on the server). |
| `URAPT_SERVER` | `http://localhost:8080` | Dev proxy target only. |
## Deployment (same-origin)
The UI is designed to be served from the **same origin** as a urapt-server,
behind a reverse proxy that serves the SPA from `dist/` and forwards `/api/v1`
and `/apt` to `urapt-server`. No CORS, no server changes — the API base is just
`/api/v1`.
```bash
pnpm build # outputs dist/
```
### Railway
`urapt-web/` includes a Dockerfile for deploying the UI as a separate Railway
service. The container builds the Vite app and serves it with Caddy, proxying
`/api/*` and `/apt/*` to an existing `urapt-server` service.
In Railway, create a new service from this repo with:
- Root Directory: `urapt-web`
- Environment variable: `URAPT_SERVER_URL=https://your-urapt-server.up.railway.app`
A trailing slash is okay; the container normalizes it before starting Caddy.
Do not set `VITE_API_BASE_URL` for this deployment; the UI should keep using the
default same-origin `/api/v1` path.
### Caddy
```caddy
apt.example.com {
# SPA
root * /srv/urapt-web/dist
try_files {path} /index.html
file_server
# REST API + APT endpoint
reverse_proxy /api/* 127.0.0.1:8080
reverse_proxy /apt/* 127.0.0.1:8080
}
```
### nginx
```nginx
server {
listen 80;
server_name apt.example.com;
root /srv/urapt-web/dist;
location / { try_files $uri /index.html; }
location /api/ { proxy_pass http://127.0.0.1:8080; }
location /apt/ { proxy_pass http://127.0.0.1:8080; }
}
```
## Architecture
```
src/
lib/api/ typed client mirroring urapt's shared/api + shared/models
(client, errors, endpoints, types)
stores/ Zustand auth store (persisted token)
hooks/ shared server/user queries, logout
components/ app shell, common UI (copy button, confirm, states), shadcn ui
features/ auth, setup, repos (tabs), tokens, users, settings
routes.tsx route tree with lazy-loaded pages + protected/admin guards
```
The API client (`src/lib/api/`) is hand-written and typed against urapt's Go
DTOs in `shared/api/api.go` and `shared/models/models.go`. A `401` anywhere
clears the local session and redirects to `/login`.
## License
GPL-3.0-or-later, matching the urapt project.