From ba6bb62e73e628e34b7f430f9fdb06eda7cdb492 Mon Sep 17 00:00:00 2001 From: myrmidex Date: Fri, 1 May 2026 20:59:56 +0200 Subject: [PATCH] 26 - Add nix-shell and rewrite README --- README.md | 195 ++++++++++++++++++++---------------------------------- shell.nix | 148 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+), 122 deletions(-) create mode 100644 shell.nix diff --git a/README.md b/README.md index a7eb0fa..07576c3 100644 --- a/README.md +++ b/README.md @@ -1,157 +1,108 @@
-# 📈 incr +# incr -**A minimalist investment tracker for VWCE shares with milestone-driven progress** +**A minimalist counter with milestone-driven progress** -*Track your portfolio growth with visual progress indicators and milestone reinforcement* +*Track anything you accumulate — with visual progress and milestone reinforcement* [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) -[![Docker](https://img.shields.io/badge/Docker-Ready-2496ED?logo=docker&logoColor=white)](https://www.docker.com/) [![Laravel](https://img.shields.io/badge/Laravel-12-FF2D20?logo=laravel&logoColor=white)](https://laravel.com/) [![React](https://img.shields.io/badge/React-19-61DAFB?logo=react&logoColor=black)](https://reactjs.org/) ---- - -**[Introduction](#introduction) • [Features](#features) • [Tech Stack](#tech-stack) • [Getting Started](#getting-started) • [Development](#development) • [Contributing](#contributing) • [License](#license)** - ---- -
-## Introduction +## About -Incr is a minimalist, one-page investment tracking application designed specifically for VWCE (Vanguard FTSE All-World UCITS ETF) shareholders. It combines the satisfaction of visual progress tracking with practical portfolio management, featuring a distinctive LED-style digital display and milestone-based goal setting. +incr is a minimalist, self-hosted tracking app. Pick something you want to accumulate — shares, books, workouts, anything — log your progress, and watch milestones fall. -The application emphasizes simplicity and focus, providing just what you need to track your investment journey without overwhelming complexity. +It features a distinctive LED-style digital display, configurable milestones, and optional price tracking. ## Features -- **LED-style display**: Large red digital counter showing current share count -- **Progress tracking**: Visual progress bar toward configurable milestones -- **Purchase management**: Add and track share purchases with historical data -- **Financial insights**: Portfolio value and withdrawal estimates -- **Milestone cycling**: Track progress toward multiple investment goals (1500→3000→4500→6000) +- **LED-style display** — large red digital counter +- **Milestone tracking** — set targets, cycle through them as you progress +- **Purchase logging** — add entries with date and optional price +- **Price tracking** — optional; log a current price to see portfolio value and P/L +- **Self-hosted** — your data stays on your server ## Tech Stack -- **Backend**: Laravel 12 (PHP 8.2+) with MySQL database +- **Backend**: Laravel 12 (PHP 8.3+) with MySQL - **Frontend**: React 19 + TypeScript with Inertia.js - **Styling**: Tailwind CSS 4 with shadcn/ui components -- **Deployment**: Docker with multi-stage builds +- **Deployment**: Docker / Podman with multi-stage builds -## Getting Started +## Self-hosting -### Quick Start (Production) +```yaml +# docker-compose.yml +services: + app: + image: forge.lvl0.xyz/lvl0/incr:latest + container_name: incr-app + restart: unless-stopped + environment: + - APP_ENV=production + - APP_DEBUG=false + - APP_KEY=base64:YOUR_APP_KEY_HERE + - DB_CONNECTION=mysql + - DB_HOST=db + - DB_PORT=3306 + - DB_DATABASE=incr + - DB_USERNAME=incr_user + - DB_PASSWORD=change_me + ports: + - "5001:80" + depends_on: + db: + condition: service_healthy + networks: + - incr-network -#### Docker + db: + image: mysql:8.0 + container_name: incr-db + restart: unless-stopped + environment: + - MYSQL_DATABASE=incr + - MYSQL_USER=incr_user + - MYSQL_PASSWORD=change_me + - MYSQL_ROOT_PASSWORD=change_me_root + volumes: + - db_data:/var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "incr_user", "-pchange_me"] + timeout: 10s + retries: 10 + interval: 10s + start_period: 10s + networks: + - incr-network -Clone the repository and run with Docker Compose: +networks: + incr-network: + driver: bridge -```bash -git clone https://github.com/your-username/incr.git -cd incr +volumes: + db_data: ``` -Run the application using the provided docker-compose configuration: +Generate an app key with: `php artisan key:generate --show` + +The app will be available at `http://localhost:5001`. + +## Development + +Requires [Nix](https://nixos.org/download/). Enter the dev shell: ```bash -# Using Docker Compose -docker-compose -f docker/production/docker-compose.yml up --build - -# Or using Podman Compose -podman-compose -f docker/production/docker-compose.yml up --build +nix-shell +dev-up ``` -The application will be available at `http://localhost:5001`. - -### Development - -#### Local Development Setup - -**Option 1: Laravel Sail (Docker)** - -For local development with Laravel Sail: - -```bash -# Install Laravel Sail -composer install -sail artisan sail:install - -# Start development environment -sail up -d - -# Install frontend dependencies and build assets -npm install -npm run dev - -# Run migrations -sail artisan migrate -``` - -**Option 2: Podman Development** - -For Fedora Atomic or other Podman-based systems: - -```bash -# Quick start with helper script -bash docker/dev/podman/start-dev.sh - -# Or manually: -# Install podman-compose if not available -pip3 install --user podman-compose - -# Start development environment -podman-compose -f docker/dev/podman/docker-compose.yml up -d - -# Run migrations -podman exec incr-dev-app php artisan migrate -``` - -**Option 3: Sail with Podman (Compatibility Layer)** - -To use Laravel Sail commands with Podman: - -```bash -# Source the alias script -source docker/dev/podman/podman-sail-alias.sh - -# Now you can use sail commands as normal -sail up -d -sail artisan migrate -sail npm run dev -``` - -The development server will be available at `http://localhost` with hot reload enabled. - -## Project Structure - -- `app/` - Laravel backend (controllers, models, services) -- `resources/js/` - React frontend components and pages -- `docker/production/` - Production Docker configuration -- `docker/dev/podman/` - Development Podman configuration -- `database/migrations/` - Database schema definitions - -## Contributing - -We welcome contributions to incr! Whether you're reporting bugs, suggesting features, or submitting pull requests, your input helps make this project better. - -### How to Contribute - -1. Fork the repository -2. Create a feature branch (`git checkout -b feature/amazing-feature`) -3. Commit your changes (`git commit -m 'Add some amazing feature'`) -4. Push to the branch (`git push origin feature/amazing-feature`) -5. Open a Pull Request - -### Bug Reports - -If you find a bug, please create an issue with: -- A clear description of the problem -- Steps to reproduce the issue -- Expected vs actual behavior -- Your environment details +Available commands inside the shell: `dev-up`, `dev-down`, `dev-rebuild`, `dev-logs`, `dev-shell`, `dev-artisan`, `dev-composer`. ## License -This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details. +GNU General Public License v3.0 — see [LICENSE](LICENSE). diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..2c52855 --- /dev/null +++ b/shell.nix @@ -0,0 +1,148 @@ +{ pkgs ? import {} }: + +pkgs.mkShell { + buildInputs = with pkgs; [ + # PHP and tools + php83 + php83Packages.composer + + # Node.js (needed for Tailwind CSS / Vite) + nodejs_22 + + # Container tools + podman + podman-compose + + # Utilities + git + curl + gnumake + ]; + + shellHook = '' + export USER_ID=$(id -u) + export GROUP_ID=$(id -g) + export PODMAN_USERNS=keep-id + + # Compose file location + COMPOSE_FILE="$PWD/docker/dev/podman/docker-compose.yml" + + # =================== + # ALIASES + # =================== + alias pc='podman-compose -f $COMPOSE_FILE' + + # =================== + # DEV COMMANDS + # =================== + dev-up() { + echo "Starting services..." + PODMAN_USERNS=keep-id podman-compose -f $COMPOSE_FILE up -d "$@" + echo "" + podman-compose -f $COMPOSE_FILE ps + echo "" + echo "App available at: http://localhost:8000" + } + + dev-down() { + if [[ "$1" == "-v" ]]; then + echo "Stopping services and removing volumes..." + podman-compose -f $COMPOSE_FILE down -v + else + echo "Stopping services..." + podman-compose -f $COMPOSE_FILE down + fi + } + + dev-restart() { + echo "Restarting services..." + podman-compose -f $COMPOSE_FILE restart "$@" + } + + dev-rebuild() { + echo "Rebuilding services (down -v + up)..." + podman-compose -f $COMPOSE_FILE down -v + PODMAN_USERNS=keep-id podman-compose -f $COMPOSE_FILE up -d "$@" + echo "" + podman-compose -f $COMPOSE_FILE ps + echo "" + echo "App available at: http://localhost:8000" + } + + dev-logs() { + podman-compose -f $COMPOSE_FILE logs -f app "$@" + } + + dev-logs-db() { + podman-compose -f $COMPOSE_FILE logs -f db "$@" + } + + dev-shell() { + podman-compose -f $COMPOSE_FILE exec app bash + } + + dev-artisan() { + podman-compose -f $COMPOSE_FILE exec app php artisan "$@" + } + + dev-composer() { + podman-compose -f $COMPOSE_FILE exec app composer "$@" + } + + # =================== + # BUILD COMMANDS + # =================== + base-build() { + local image="forge.lvl0.xyz/lvl0/incr:latest" + + if ! podman login --get-login forge.lvl0.xyz &>/dev/null; then + echo "Not logged in to forge.lvl0.xyz" + podman login forge.lvl0.xyz || return 1 + fi + + echo "Building image: $image" + if ! podman build -t "$image" -f Dockerfile .; then + echo "Build failed!" + return 1 + fi + + echo "" + echo "Pushing to registry..." + if ! podman push "$image"; then + echo "Push failed!" + return 1 + fi + + echo "" + echo "Done! Image pushed: $image" + } + + # =================== + # WELCOME MESSAGE + # =================== + echo "" + echo "=================================================" + echo " incr Dev Environment " + echo "=================================================" + echo "" + echo " Podman: $(podman --version | cut -d' ' -f3)" + echo "" + echo "Commands:" + echo " dev-up [services] Start all or specific services" + echo " dev-down [-v] Stop services (-v removes volumes)" + echo " dev-rebuild Fresh start (down -v + up)" + echo " dev-restart Restart services" + echo " dev-logs Tail app logs" + echo " dev-logs-db Tail database logs" + echo " dev-shell Shell into app container" + echo " dev-artisan Run artisan command" + echo " dev-composer Run composer command" + echo " base-build Build and push image" + echo "" + echo "Services:" + echo " app Laravel http://localhost:8000" + echo " vite HMR http://localhost:5173" + echo " db MySQL localhost:3307" + echo "" + ''; +}