Initial commit for Start9 packaging

This commit is contained in:
MacPro
2026-02-28 09:27:26 -06:00
commit 1b64c45c52
124 changed files with 15671 additions and 0 deletions
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,33 @@
# Deploy on StartOS 0.3.5 (Raspberry Pi)
## 1) Build the package on your Mac
```bash
cd /Users/macpro/Projects/CRM
make -C start9/0.3.5 package
```
This creates:
- `start9/0.3.5/image.tar`
- `start9/0.3.5/ten31-database.s9pk`
## 2) Upload package to StartOS
1. Open StartOS web UI.
2. Go to Services -> Sideload Package (or equivalent 0.3.5 menu).
3. Upload `ten31-database.s9pk`.
4. Install and start the service.
## 3) First run
1. Open the service UI.
2. Create first admin account on the login screen.
3. In Settings, run one manual backup immediately.
## 4) Data persistence contract
- App DB path: `/data/crm.db`
- Backup path: `/data/backups`
Because these are in the persistent service volume, app restarts/upgrades do not erase data.
## 5) Before any upgrade/migration
1. Run manual backup in-app.
2. Export fundraising state in-app.
3. Keep both files off-device as recovery copy.
+25
View File
@@ -0,0 +1,25 @@
FROM python:3.11-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
CRM_ENV=production \
CRM_HOST=0.0.0.0 \
CRM_PORT=8080 \
CRM_DATA_DIR=/data \
CRM_FRONTEND_DIR=/app/frontend
WORKDIR /app
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl \
&& rm -rf /var/lib/apt/lists/*
COPY backend/server.py /app/backend/server.py
COPY frontend /app/frontend
COPY start9/0.3.5/docker_entrypoint.sh /usr/local/bin/docker_entrypoint.sh
COPY start9/0.3.5/healthcheck.sh /usr/local/bin/healthcheck.sh
RUN chmod +x /usr/local/bin/docker_entrypoint.sh /usr/local/bin/healthcheck.sh
EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/docker_entrypoint.sh"]
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Ten31
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+23
View File
@@ -0,0 +1,23 @@
PKG_ID := ten-database
PKG_VERSION := 0.1.0.38
REPO_ROOT := $(abspath ../..)
WRAPPER_DIR := $(CURDIR)
IMAGE_NAME := start9/$(PKG_ID)/main:$(PKG_VERSION)
.PHONY: image-arm package verify clean
image-arm:
docker buildx build --platform=linux/arm64 \
-f $(WRAPPER_DIR)/Dockerfile \
-t $(IMAGE_NAME) \
-o type=docker,dest=$(WRAPPER_DIR)/image.tar \
$(REPO_ROOT)
package: image-arm
start-sdk pack
verify:
start-sdk verify s9pk $(PKG_ID).s9pk
clean:
rm -f $(WRAPPER_DIR)/image.tar $(WRAPPER_DIR)/$(PKG_ID).s9pk
+23
View File
@@ -0,0 +1,23 @@
# Start9 Wrapper (0.3.5)
This directory contains the StartOS 0.3.5 package wrapper for Ten31 Database.
## Build prerequisites
- Docker with buildx
- `start-sdk` installed on build machine
## Build package
```bash
cd /Users/macpro/Projects/CRM
make -C start9/0.3.5 package
```
## Verify package
```bash
cd /Users/macpro/Projects/CRM
make -C start9/0.3.5 verify
```
## Outputs
- `start9/0.3.5/image.tar`
- `start9/0.3.5/ten-database.s9pk`
@@ -0,0 +1,20 @@
#!/bin/sh
set -eu
DATA_DIR="${CRM_DATA_DIR:-/data}"
SECRET_FILE="$DATA_DIR/.crm-secret"
mkdir -p "$DATA_DIR" "$DATA_DIR/backups"
if [ -z "${CRM_SECRET_KEY:-}" ]; then
if [ -f "$SECRET_FILE" ]; then
CRM_SECRET_KEY="$(cat "$SECRET_FILE")"
else
CRM_SECRET_KEY="$(head -c 48 /dev/urandom | base64 | tr -d '\n' | tr '/+' 'ab')"
printf '%s' "$CRM_SECRET_KEY" > "$SECRET_FILE"
chmod 600 "$SECRET_FILE"
fi
export CRM_SECRET_KEY
fi
exec python3 /app/backend/server.py
@@ -0,0 +1,5 @@
#!/bin/sh
set -eu
PORT="${CRM_PORT:-8080}"
curl -fsS "http://127.0.0.1:${PORT}/api/health" >/dev/null
Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

+43
View File
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 722.69 280.85">
<defs>
<style>
.cls-1 {
font-family: LTCGoudyOldstylePro-Bold, 'LTC Goudy Oldstyle Pro';
font-size: 192px;
font-weight: 700;
}
.cls-1, .cls-2, .cls-3 {
fill: #fff;
}
.cls-2, .cls-4 {
stroke-width: 3px;
}
.cls-2, .cls-4, .cls-3 {
stroke: #fff;
stroke-miterlimit: 10;
}
.cls-4 {
fill: none;
}
.cls-5 {
letter-spacing: -.06em;
}
</style>
</defs>
<text class="cls-1" transform="translate(120.54 208.45)"><tspan class="cls-5" x="0" y="0">T</tspan><tspan x="120.96" y="0">en31</tspan></text>
<g>
<polygon class="cls-3" points="95.52 140.42 54.54 154.4 54.54 126.45 95.52 140.42"/>
<line class="cls-2" x1="0" y1="140.42" x2="60.54" y2="140.42"/>
</g>
<rect class="cls-4" x="97.1" y="1.5" width="527.95" height="277.85"/>
<g>
<polygon class="cls-3" points="721.15 140.42 680.16 154.4 680.16 126.45 721.15 140.42"/>
<line class="cls-2" x1="625.62" y1="140.42" x2="686.16" y2="140.42"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.
@@ -0,0 +1,24 @@
# Ten31 Database (StartOS 0.3.5)
## What this package does
- Runs Ten31 Database as a private web app.
- Persists all data under the StartOS service volume (`/data`).
- Exposes web UI/API on internal port `8080`.
## First launch
1. Open the service UI from StartOS.
2. If this is a fresh install, create the first admin account from the login screen.
3. Go to Settings and run a manual backup once.
## Airtable migration
1. Open Settings -> Migration.
2. Choose "Import from Airtable CSV".
3. Confirm row/column mappings before final import.
## Data safety
- Database path in container: `/data/crm.db`.
- Backups path in container: `/data/backups/`.
- Before StartOS or package upgrades, run a backup and export from Settings.
## Upgrade note
This 0.3.5 wrapper keeps app/runtime files separate from data volume so migration to a future 0.4 wrapper can preserve the same data directory layout.
@@ -0,0 +1,94 @@
id: ten-database
title: Ten31 Database
version: 0.1.0.38
release-notes: >-
Initial StartOS 0.3.5 package wrapper for Ten31 Database.
license: MIT
wrapper-repo: https://github.com/ten31/ten31-database-startos
upstream-repo: https://github.com/ten31/ten31-database
support-site: https://github.com/ten31/ten31-database/issues
marketing-site: https://ten31.vc
build: ["make image-arm"]
description:
short: Self-hosted investor and fundraising database for Ten31.
long: >-
Ten31 Database is an Airtable-style investor CRM with fundraising grid,
communications logging, views, backups, and CSV import. This package stores
all runtime data in the service volume for upgrade-safe persistence.
assets:
license: LICENSE
icon: icon.png
instructions: instructions.md
docker-images: image.tar
main:
type: docker
image: main
entrypoint: docker_entrypoint.sh
args: []
mounts:
main: /data
health-checks:
main:
name: API health
success-message: CRM API is responding.
type: docker
image: main
entrypoint: healthcheck.sh
args: []
inject: true
config: ~
dependencies: {}
volumes:
main:
type: data
interfaces:
main:
name: Web Interface
description: Browser UI and API for Ten31 Database.
tor-config:
port-mapping:
80: "8080"
lan-config:
443:
ssl: true
internal: 8080
ui: true
protocols: [tcp, http, https]
backup:
create:
type: docker
image: main
system: false
entrypoint: sh
args:
- -c
- |
set -eu
rm -rf /backup/*
cp -a /data/. /backup/
mounts:
main: /data
BACKUP: /backup
restore:
type: docker
image: main
system: false
entrypoint: sh
args:
- -c
- |
set -eu
cp -a /backup/. /data/
mounts:
main: /data
BACKUP: /backup
actions: {}
Binary file not shown.
+9
View File
@@ -0,0 +1,9 @@
# Start9 Wrapper (0.4 placeholder)
This directory is reserved for the StartOS 0.4 package wrapper.
Migration plan from 0.3.5:
1. Keep package id stable (`ten-database`) if StartOS migration path allows.
2. Keep mounted data directory contract unchanged (`/data/crm.db`, `/data/backups`).
3. Rebuild wrapper files against 0.4 packaging spec and verify with current start-sdk.
4. Test upgrade on a staging node using production backup restore before live cutover.
@@ -0,0 +1,115 @@
# Start9 Packaging Checklist (0.3.5 style)
This checklist is written for the StartOS 0.3.5 packaging flow used in this repo.
Use it as an indicative template for other projects, not a literal one-size-fits-all script.
## 1) Required packaging scaffold (inside `start9/<version>/`)
- `manifest.yaml`
- `Makefile`
- `Dockerfile`
- `docker_entrypoint.sh`
- `healthcheck.sh`
- `instructions.md`
- `icon.png` (and/or `icon.svg` if desired)
Optional:
- `scripts/` for package-specific helper scripts
- prebuilt artifacts (`image.tar`, `.s9pk`) generated by packaging
## 2) Project-specific values to change
In `manifest.yaml`:
- `id`
- `title`
- `version`
- `description`
- `upstream-repo`, `support-site`, `marketing-site`
- `interfaces` (port, protocol, TLS, UI flags)
- `config` (runtime env/config options)
- `backup` mounts/commands
- `actions` (if you expose maintenance actions)
In `Makefile`:
- package id/version variables
- image name/tag
- paths/targets used by `make ... package`
In `Dockerfile`:
- base image
- runtime dependencies
- app copy paths
- entrypoint/cmd
In scripts:
- read config/env from StartOS mount/env conventions
- write data only to mounted persistent directories
## 3) What must exist outside `start9/`
The wrapper is not fully standalone. It builds an image from your app source.
For this CRM package specifically:
- `backend/server.py`
- `frontend/` (all static assets/UI)
These are copied in Docker build steps. In other projects, these paths, filenames, and build inputs can be different.
This document is meant to show the pattern; each project must map to its own app layout.
## 4) Data + persistence checklist
- Persist DB/files under mounted data path (not container ephemeral path).
- Confirm backup/restore mounts and commands match the manifest volume names exactly.
- Verify restore can start app cleanly and preserve schema/data.
## 5) Network/interface checklist
- Confirm service listens on the internal container port expected by `manifest.yaml`.
- Confirm LAN interface protocol settings match actual service behavior (HTTP vs HTTPS/TCP).
- Confirm UI launches from StartOS Interfaces page without cert/protocol mismatch.
## 6) Build + install flow
1. Bump version in:
- `start9/<version>/manifest.yaml`
- `start9/<version>/Makefile`
2. Build package:
- `make -C start9/<version> package`
3. Install resulting `.s9pk` in StartOS.
4. Start service and check:
- health/logs
- UI launch
- persistence after restart
- backup/restore smoke test
## 7) Reusable vs non-reusable parts
Reusable:
- overall folder structure and file roles in `start9/<version>/`
- packaging workflow (`manifest` + `Makefile` + `Dockerfile` + scripts)
Non-reusable without edits:
- app copy paths in Dockerfile
- app-specific env/config keys
- ports/interfaces/protocol values
- backup/restore commands tied to app data layout
## 8) Planned migration path to StartOS 0.4
When 0.4 is ready for your deployment, use this approach:
1. Keep 0.3.5 package stable as the production branch.
2. Create a parallel package folder for 0.4 (for example `start9/0.4/`).
3. Port wrapper files (`manifest`, `Makefile`, Docker packaging scripts) to the 0.4 schema/tooling.
4. Update interface/config/backup definitions to 0.4 expectations.
5. Build and install 0.4 package in a test server first.
6. Restore a real backup into 0.4 and validate:
- app starts
- UI works
- data integrity is preserved
- backup/restore still works
7. Only after successful validation, promote 0.4 package for primary use.
Notes:
- Keep database path and backup format stable where possible to make migration low-risk.
- If schema changes are required, add explicit migration steps and rollback steps before production cutover.