first commit
This commit is contained in:
commit
32a7ba8e8f
168 files changed
+123856
No files matched your search
@@ -0,0 +1,179 @@
|
||||
# MikroTik Backup System
|
||||
|
||||
Version **0.0.1** is the initial Rust rewrite of the previous Python/TypeScript application. It is a single self-hosted service with an embedded web UI, SQLite storage, RouterOS/SwOS backup workflows, scheduling, retention, notifications, and local OpenAPI documentation.
|
||||
|
||||
## Quick start
|
||||
|
||||
### Docker Compose
|
||||
|
||||
```bash
|
||||
docker compose build app
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
The default published address is `127.0.0.1:5581`. Persistent application data is stored in the `data` volume.
|
||||
|
||||
The image uses `rust:1.99.1-alpine3.24` for the build stage and `alpine:3.24` for runtime. The service runs as UID/GID `10001` with a read-only root filesystem.
|
||||
|
||||
### Native build
|
||||
|
||||
Requires Rust 1.99.1 or compatible toolchain and the native dependencies needed by the crates in `Cargo.lock`.
|
||||
|
||||
```bash
|
||||
cargo build --release --locked
|
||||
./target/release/mikrotik-backup serve
|
||||
```
|
||||
|
||||
Or use the launcher:
|
||||
|
||||
```bash
|
||||
./start.sh
|
||||
```
|
||||
|
||||
## First account
|
||||
|
||||
Registration is disabled by default. Set `DEFAULT_ADMIN_PASSWORD` before first startup, or let the application create the initial administrator password file under `DATA_DIR/secrets/initial-admin-password`.
|
||||
|
||||
New installations and new accounts default to **English**. Imported accounts preserve their saved language preference. The UI also supports Polish, Spanish, and Norwegian.
|
||||
|
||||
## Main configuration
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `DATA_DIR` | `./storage` | Database, backups, secrets, SSH known hosts |
|
||||
| `DATABASE_PATH` | `<DATA_DIR>/routeros_backup_next.db` | SQLite database path |
|
||||
| `LISTEN_ADDR` | `127.0.0.1:5581` | HTTP listener |
|
||||
| `API_PREFIX` | `/api` | API base path |
|
||||
| `TIMEZONE` | `Europe/Warsaw` | Scheduler timezone |
|
||||
| `SECRET_KEY` | generated/persisted when absent | JWT signing secret |
|
||||
| `ALLOW_REGISTRATION` | `false` | Allow account registration |
|
||||
| `DEFAULT_ADMIN_USERNAME` | `admin` | Initial administrator name |
|
||||
| `DEFAULT_ADMIN_PASSWORD` | empty | Initial administrator password |
|
||||
| `SSH_HOST_KEY_POLICY` | `accept-new` | `accept-new` or `strict` |
|
||||
| `SSH_TIMEOUT_SECONDS` | `30` | Device SSH timeout |
|
||||
| `MAX_PARALLEL_BACKUPS` | `4` | Concurrent backup limit |
|
||||
| `CORS_ORIGINS` | `[]` | Explicit allowed HTTP(S) origins |
|
||||
|
||||
Run configuration validation without starting the server:
|
||||
|
||||
```bash
|
||||
./target/release/mikrotik-backup check-config
|
||||
```
|
||||
|
||||
## Data layout
|
||||
|
||||
```text
|
||||
DATA_DIR/
|
||||
├── routeros_backup_next.db
|
||||
├── backups/
|
||||
│ ├── exports/<device-id>/
|
||||
│ └── binary/<device-id>/
|
||||
├── secrets/
|
||||
└── ssh/
|
||||
```
|
||||
|
||||
RouterOS text exports are stored under `backups/exports`; binary RouterOS backups and SwOS `.swb` files are stored under `backups/binary`.
|
||||
|
||||
## Legacy Python/TypeScript import
|
||||
|
||||
The importer is explicit and never runs during normal startup. Stop the old application first and import into a **new** Rust destination.
|
||||
|
||||
```bash
|
||||
./import-python.sh /srv/mikrotik-backup-old
|
||||
```
|
||||
|
||||
Docker Compose example:
|
||||
|
||||
```bash
|
||||
docker compose run --rm \
|
||||
-v /srv/mikrotik-backup-old:/legacy:ro \
|
||||
app import-python --source /legacy
|
||||
```
|
||||
|
||||
The importer copies accounts, devices, settings, logs, backup metadata, and every referenced backup file. It validates existing backup checksums when present and refuses to publish an incomplete destination. See [docs/migration.md](docs/migration.md).
|
||||
|
||||
## RouterOS and SwOS
|
||||
|
||||
RouterOS uses SSH-based export/backup operations. SwOS uses its web interface and downloads `/backup.swb`, with Digest authentication first and Basic as fallback. Connection testing distinguishes general web reachability from backup-endpoint availability.
|
||||
|
||||
SwOS details and troubleshooting are in [docs/switchos.md](docs/switchos.md).
|
||||
|
||||
## Configuration comparison
|
||||
|
||||
`.rsc` files support:
|
||||
|
||||
- side-by-side and unified diff;
|
||||
- changed-lines-only mode and search;
|
||||
- paged browser rendering to limit DOM size;
|
||||
- semantic RouterOS analysis that groups changes by configuration section and identifies added, removed, and modified commands/fields;
|
||||
- masking of sensitive values in semantic summaries.
|
||||
|
||||
Binary backups are not diffed.
|
||||
|
||||
## Embedded web assets and caching
|
||||
|
||||
`build.rs` combines the UI sources listed in `web/assets.list`. Each compiled CSS/JavaScript bundle receives a content hash in its filename, for example:
|
||||
|
||||
```text
|
||||
/assets/app.<hash>.js
|
||||
/assets/app.<hash>.css
|
||||
/assets/docs.<hash>.js
|
||||
/assets/docs.<hash>.css
|
||||
```
|
||||
|
||||
The HTML shell is generated with those exact filenames. Hashed assets use:
|
||||
|
||||
```text
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
```
|
||||
|
||||
HTML and API responses remain non-cacheable by default. `/favicon.ico` intentionally returns `204 No Content`.
|
||||
|
||||
## API documentation
|
||||
|
||||
Interactive local documentation:
|
||||
|
||||
```text
|
||||
/docs
|
||||
```
|
||||
|
||||
OpenAPI JSON:
|
||||
|
||||
```text
|
||||
/openapi.json
|
||||
```
|
||||
|
||||
Swagger UI is embedded locally and does not require a CDN.
|
||||
|
||||
## Validation
|
||||
|
||||
Frontend unit tests:
|
||||
|
||||
```bash
|
||||
node web/tests/core.test.cjs
|
||||
```
|
||||
|
||||
JavaScript syntax:
|
||||
|
||||
```bash
|
||||
node --check web/js/i18n.js
|
||||
node --check web/js/core.js
|
||||
node --check web/js/views.js
|
||||
node --check web/js/app.js
|
||||
```
|
||||
|
||||
Rust checks when a toolchain is available:
|
||||
|
||||
```bash
|
||||
cargo fmt --check
|
||||
cargo test --locked
|
||||
cargo clippy --locked --all-targets -- -D warnings
|
||||
```
|
||||
|
||||
The browser smoke tests under `web/tests/` require Playwright.
|
||||
|
||||
## Security and dependencies
|
||||
|
||||
The service uses request size/time limits, JWT validation, password hashing, SSH host-key verification, secret redaction, restricted filesystem permissions, and a non-root container runtime. Dependency audit notes and the local `libssh2-sys` patch provenance are summarized in [docs/security.md](docs/security.md).
|
||||
|
||||
Third-party license notices are in `docs/THIRD_PARTY_NOTICES.txt`.
|
||||
Reference in new issue
Block a user