This commit is contained in:
138
README.md
138
README.md
@@ -1,2 +1,140 @@
|
||||
# Train-ID
|
||||
|
||||
Simple Node/Express app to identify and inventory model trains from photos using OpenAI Vision, store results in MySQL, and export PDFs/XLSX.
|
||||
|
||||
## Requirements
|
||||
- Node.js 20+ and npm
|
||||
- MySQL 8+
|
||||
- OpenAI API key
|
||||
|
||||
## Environment variables
|
||||
Create a `.env` in the project root on the server:
|
||||
|
||||
```
|
||||
PORT=3000
|
||||
# OpenAI
|
||||
OPENAI_API_KEY=sk-...
|
||||
# or alternative variable name also supported by code:
|
||||
# openapi_key=sk-...
|
||||
|
||||
# MySQL connection
|
||||
db_ip=127.0.0.1
|
||||
db_port=3306
|
||||
db_user=trainid
|
||||
db_pass=changeme
|
||||
db_name=trainid
|
||||
```
|
||||
|
||||
## Local development
|
||||
```
|
||||
npm install
|
||||
npm run build
|
||||
npm start
|
||||
# or for auto-reload on TypeScript build changes:
|
||||
npm run dev
|
||||
```
|
||||
Visit `http://localhost:3000`.
|
||||
|
||||
## API overview
|
||||
- POST `/api/upload` with `multipart/form-data` field `image` → analyzes photo, inserts record
|
||||
- GET `/api/items` → list items (optional `?q=` to search model/SKU)
|
||||
- GET `/api/items/:id/pdf` → generate/download PDF for one item
|
||||
- GET `/api/export/xlsx` → download XLSX export of inventory with embedded thumbnails
|
||||
- DELETE `/api/items/:id` → delete one
|
||||
- DELETE `/api/items` → wipe all
|
||||
|
||||
## Debian 13 (Trixie) LXC install
|
||||
These steps assume a fresh Debian 13 LXC and deployment directory `/opt/Train-ID` with a system user `deployuser` that has passwordless sudo for service management.
|
||||
|
||||
1) Base packages and Node.js
|
||||
```
|
||||
sudo apt update
|
||||
sudo apt install -y curl ca-certificates gnupg build-essential pkg-config
|
||||
# Node 20 using Nodesource or Debian repo (choose one). Nodesource example:
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
node -v && npm -v
|
||||
```
|
||||
|
||||
2) MySQL server (or connect to external MySQL)
|
||||
```
|
||||
sudo apt install -y mariadb-server mariadb-client
|
||||
sudo systemctl enable --now mariadb
|
||||
sudo mysql -e "CREATE DATABASE IF NOT EXISTS trainid CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||
sudo mysql -e "CREATE USER IF NOT EXISTS 'trainid'@'%' IDENTIFIED BY 'changeme';"
|
||||
sudo mysql -e "GRANT ALL PRIVILEGES ON trainid.* TO 'trainid'@'%'; FLUSH PRIVILEGES;"
|
||||
```
|
||||
If using external MySQL, skip install and set `db_ip` etc. in `.env`.
|
||||
|
||||
3) App checkout and build
|
||||
```
|
||||
sudo mkdir -p /opt/Train-ID
|
||||
sudo chown $USER:$USER /opt/Train-ID
|
||||
git clone https://git.hudsonriggs.systems/HRiggs/Train-ID.git /opt/Train-ID
|
||||
cd /opt/Train-ID
|
||||
cp .env.example .env || true # if you keep a template in the future
|
||||
# create .env as per above
|
||||
npm ci || npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
4) Systemd service
|
||||
Create `/etc/systemd/system/train-id.service`:
|
||||
```
|
||||
[Unit]
|
||||
Description=Train-ID API
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/opt/Train-ID
|
||||
EnvironmentFile=/opt/Train-ID/.env
|
||||
ExecStart=/usr/bin/node /opt/Train-ID/dist/server.js
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
User=www-data
|
||||
Group=www-data
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
Then enable and start:
|
||||
```
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now train-id
|
||||
sudo systemctl status train-id --no-pager
|
||||
```
|
||||
|
||||
5) Reverse proxy (optional, for port 80/443)
|
||||
Example Nginx site (`/etc/nginx/sites-available/train-id`):
|
||||
```
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
```
|
||||
Enable and reload:
|
||||
```
|
||||
sudo apt install -y nginx
|
||||
sudo ln -s /etc/nginx/sites-available/train-id /etc/nginx/sites-enabled/train-id
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
## CI/CD deploy
|
||||
The repo includes `.gitea/workflows/deploy.yaml` which, on push to `main`, SSHes to `192.168.30.114`, pulls latest, installs dependencies, builds, and restarts the `train-id` service. Set `DEPLOY_KEY` in repository secrets to a private SSH key authorized for `deployuser@192.168.30.114`.
|
||||
|
||||
If your service name or directory differ, update `SERVICE`/`APP_DIR` in the workflow accordingly.
|
||||
|
||||
```
|
||||
|
||||
echo "deployuser ALL=(root) NOPASSWD: /bin/systemctl restart train-id.service" | sudo tee /etc/sudoers.d/train-id >/dev/null
|
||||
sudo chmod 440 /etc/sudoers.d/train-id
|
||||
sudo visudo -cf /etc/sudoers.d/train-id
|
||||
```
|
||||
Reference in New Issue
Block a user