# Alaminn.info — Path & Value Change Guide

> **Question this answers:** *"If I change any path, where do I need to change it? And if I need any update, where do I edit?"*
>
> Use this as a single map. Find what you want to change on the left → edit the files listed on the right → run the rebuild/restart command at the bottom.

---

## 1. Quick Map — "If I change X, edit these files"

| What you want to change | Files you MUST edit | Notes |
|---|---|---|
| **Domain** (`alaminn.info` → `yourdomain.com`) | `deploy/nginx-alaminn-info.conf` (lines 5, 17, 36, 39, 40, 53–55) · `deploy/install.sh` (lines `DOMAIN=`, `DOMAIN_WWW=`) · `deploy/.env.production.example` (`NEXT_PUBLIC_SITE_URL`, `EMAIL_FROM`, `EMAIL_REPLY_TO`, `ADMIN_BOOTSTRAP_EMAIL`) · `src/app/layout.tsx` (metadataBase, JSON-LD `@id`/url/image, og image) · `src/app/sitemap.ts` · `src/app/robots.ts` · `src/lib/site-data.ts` (mailto/handle) · `src/lib/env.ts` (EMAIL_FROM fallback) · `next.config.ts` (`images.remotePatterns`) | SSL cert path also changes: `/etc/letsencrypt/live/<NEW>/fullchain.pem` |
| **App directory** (`/var/www/alaminn-info` → `/var/www/other`) | `deploy/alaminn-info.service` (`WorkingDirectory=`, `EnvironmentFile=`, `ExecStart=`) · `deploy/install.sh` (`APP_DIR=`) · `deploy/deploy.sh` (`APP_DIR=`) | Re-run `install.sh` after change. `ReadWritePaths=` in service must match. |
| **Port** (`3001` → `3002`) | `deploy/alaminn-info.service` (`Environment=PORT=`) · `deploy/nginx-alaminn-info.conf` (all `proxy_pass http://127.0.0.1:3001` — 3 occurrences) · `deploy/install.sh` (`APP_PORT=`) · `deploy/deploy.sh` (`APP_PORT=`) · `deploy/.env.production.example` (`PORT=`) · `package.json` (`scripts.dev`: `next dev -p 3001`) · `.env` (`PORT=`) | Nginx `proxy_pass` and systemd `PORT` MUST match, otherwise 502 Bad Gateway. |
| **System user** (`aloedu` → `otheruser`) | `deploy/alaminn-info.service` (`User=`, `Group=`, `ExecStart=` bun path `/home/aloedu/.bun/bin/bun`) · `deploy/install.sh` (`APP_USER=`, `APP_GROUP=`, `BUN_INSTALL_USER=`) · `deploy/deploy.sh` (`APP_USER=`, `BUN_BIN=`) | Bun is installed per-user at `/home/<user>/.bun/bin/bun`. The service `ExecStart` hardcodes this path. |
| **Bun binary path** (`/home/aloedu/.bun/bin/bun`) | `deploy/alaminn-info.service` (`ExecStart=`) · `deploy/install.sh` (`BUN_BIN=`) · `deploy/deploy.sh` (`BUN_BIN=`) | Only if you installed Bun somewhere else (e.g. `/usr/local/bin/bun`). |
| **Database name** (`alaminn_info` → `other_db`) | `deploy/mariadb-init.sql` (all `CREATE DATABASE` + `GRANT` lines) · `deploy/install.sh` (`DB_NAME=`) · `deploy/.env.production.example` (`DATABASE_URL`) · `.env` (`DATABASE_URL`) | Re-create DB + re-run `db:push` after change. |
| **Database user** (`alaminn_app` → `other_user`) | `deploy/mariadb-init.sql` · `deploy/install.sh` (`DB_USER=`) · `deploy/.env.production.example` (`DATABASE_URL`) · `.env` (`DATABASE_URL`) | Same password must be set in both `mariadb-init.sql` and `.env`. |
| **Database engine** (MariaDB → Postgres/SQLite) | `prisma/schema.prisma` (`provider = "mysql"` / `"postgresql"` / `"sqlite"`) · `prisma/schema.mysql.prisma` (mirror) · `.env` (`DATABASE_URL=` scheme) · `deploy/install.sh` (apt install line) · `deploy/alaminn-info.service` (`After=mariadb.service` line) | Run `bun run db:generate && bun run db:push` after. |
| **Admin email / bootstrap password** | `deploy/install.sh` (line that writes `ADMIN_BOOTSTRAP_EMAIL=` and `ADMIN_BOOTSTRAP_PASSWORD=` into `.env`) · `deploy/.env.production.example` · `prisma/seed.ts` (reads env) · `.env` (the actual value) | Password is auto-generated by `install.sh`. To rotate: edit `.env`, then `bun run db:seed`. |
| **Public URL** (`https://alaminn.info`) | `deploy/.env.production.example` (`NEXT_PUBLIC_SITE_URL=`) · `.env` · `src/app/layout.tsx` (metadataBase, JSON-LD) · `src/app/sitemap.ts` · `src/app/robots.ts` · `next.config.ts` (`images.remotePatterns`) | Must match the domain in nginx `server_name`. |
| **SSL cert paths** (`/etc/letsencrypt/live/alaminn.info/...`) | `deploy/nginx-alaminn-info.conf` (lines 39, 40) | Re-issue with `sudo certbot --nginx -d NEWDOMAIN`. |
| **Service name** (`alaminn-info` → `other-name`) | `deploy/alaminn-info.service` (filename itself) · `deploy/install.sh` (`SERVICE_DST=`, `systemctl enable` line) · `deploy/deploy.sh` (`SERVICE=`) · all `systemctl`/`journalctl` commands in docs | Rename file → `sudo systemctl daemon-reload`. |
| **Max upload size** (20 MB) | `deploy/nginx-alaminn-info.conf` (`client_max_body_size 20m;`) | Also bump any reverse-proxy timeout if uploads are slow. |
| **Memory limit** (768 MB) | `deploy/alaminn-info.service` (`MemoryMax=768M`, `BUN_JSC_maxOldSpaceSize=512`) | `BUN_JSC_maxOldSpaceSize` should be ~70% of `MemoryMax`. |
| **Email "from" address** | `deploy/.env.production.example` (`EMAIL_FROM`, `EMAIL_REPLY_TO`) · `.env` · `src/lib/env.ts` (fallback) · `src/lib/site-data.ts` (mailto link) | All three should agree. |
| **Dev server port** (only for local dev) | `package.json` → `scripts.dev` (`next dev -p 3001`) | Production port is controlled by systemd `PORT=`, not this. |

---

## 2. The 7 files that hold 95% of all paths

If you only want to remember a shortlist, these are the files you will touch 95% of the time:

```
/home/z/my-project/
├── deploy/
│   ├── alaminn-info.service          ← systemd: user, dir, port, bun path
│   ├── nginx-alaminn-info.conf       ← nginx: domain, SSL, proxy_pass port
│   ├── install.sh                    ← one-time setup: ALL constants at top
│   ├── deploy.sh                     ← redeploy: APP_DIR, APP_USER, BUN_BIN, APP_PORT
│   └── .env.production.example       ← env template: PORT, DATABASE_URL, AUTH_SECRET, URLs
├── package.json                      ← dev port, scripts
├── next.config.ts                    ← image remotePatterns (domain)
├── prisma/schema.prisma              ← DB provider + DATABASE_URL via env
└── src/
    ├── app/layout.tsx                ← metadataBase + JSON-LD (domain)
    ├── app/sitemap.ts                ← sitemap URL
    ├── app/robots.ts                 ← sitemap + host URL
    ├── lib/site-data.ts              ← contact email / handle
    └── lib/env.ts                    ← env validation + EMAIL_FROM fallback
```

---

## 3. Worked example — "I want to change the domain from `alaminn.info` to `al-am.in`"

Edit these exact files:

1. **`deploy/nginx-alaminn-info.conf`**
   - Line 5: `# Public URL:           https://al-am.in`
   - Line 17: `server_name al-am.in www.al-am.in;`
   - Line 36: `server_name al-am.in www.al-am.in;`
   - Line 39: `ssl_certificate     /etc/letsencrypt/live/al-am.in/fullchain.pem;`
   - Line 40: `ssl_certificate_key /etc/letsencrypt/live/al-am.in/privkey.pem;`
   - Lines 53–55: `if ($host = www.al-am.in) { return 301 https://al-am.in... }`

2. **`deploy/install.sh`**
   - `DOMAIN="al-am.in"`
   - `DOMAIN_WWW="www.al-am.in"`

3. **`deploy/.env.production.example`** and your real **`.env`**
   - `NEXT_PUBLIC_SITE_URL=https://al-am.in`
   - `ADMIN_BOOTSTRAP_EMAIL=admin@al-am.in`
   - `EMAIL_FROM="Al Aminn <hello@al-am.in>"`
   - `EMAIL_REPLY_TO="hello@al-am.in"`

4. **`src/app/layout.tsx`** — every `https://alaminn.info` → `https://al-am.in` (metadataBase, JSON-LD `@id`/url/image, og image, twitter image).

5. **`src/app/sitemap.ts`** — `url: "https://al-am.in/"`.

6. **`src/app/robots.ts`** — `sitemap:` and `host:` URLs.

7. **`src/lib/site-data.ts`** — `mailto:hello@al-am.in` and `handle: "hello@al-am.in"`.

8. **`src/lib/env.ts`** — fallback `Al Aminn <hello@al-am.in>`.

9. **`next.config.ts`** — `images.remotePatterns` hostname: `al-am.in` + `www.al-am.in`.

10. **Re-issue SSL:** `sudo certbot --nginx -d al-am.in -d www.al-am.in`.

11. **Rebuild + restart:**
    ```bash
    cd /var/www/alaminn-info
    bun run build
    sudo systemctl restart alaminn-info
    sudo nginx -t && sudo systemctl reload nginx
    ```

---

## 4. Worked example — "I want to change the port from `3001` to `3002`"

1. **`deploy/alaminn-info.service`** → `Environment=PORT=3002`
2. **`deploy/nginx-alaminn-info.conf`** → 3 occurrences of `proxy_pass http://127.0.0.1:3001` → `:3002` (lines 119, 141, 167)
3. **`deploy/install.sh`** → `APP_PORT="3002"`
4. **`deploy/deploy.sh`** → `APP_PORT="3002"`
5. **`deploy/.env.production.example`** and **`.env`** → `PORT=3002`
6. **`package.json`** → `"dev": "next dev -p 3002"` (only affects local dev)
7. Reload:
   ```bash
   sudo systemctl daemon-reload
   sudo systemctl restart alaminn-info
   sudo nginx -t && sudo systemctl reload nginx
   curl -s http://127.0.0.1:3002/api/health
   ```

---

## 5. Worked example — "I want to change the install directory from `/var/www/alaminn-info` to `/srv/alaminn`"

1. **`deploy/alaminn-info.service`**
   - `WorkingDirectory=/srv/alaminn`
   - `EnvironmentFile=/srv/alaminn/.env`
   - `ExecStart=/home/aloedu/.bun/bin/bun run /srv/alaminn/.next/standalone/server.js`
   - `ReadWritePaths=/srv/alaminn`
2. **`deploy/install.sh`** → `APP_DIR="/srv/alaminn"`
3. **`deploy/deploy.sh`** → `APP_DIR="/srv/alaminn"`
4. Create the dir + chown:
   ```bash
   sudo mkdir -p /srv/alaminn
   sudo chown -R aloedu:aloedu /srv/alaminn
   ```
5. Move existing files: `sudo rsync -a /var/www/alaminn-info/ /srv/alaminn/`
6. Reload:
   ```bash
   sudo systemctl daemon-reload
   sudo systemctl restart alaminn-info
   ```

---

## 6. Worked example — "I want to change the system user from `aloedu` to `deploy`"

1. **`deploy/alaminn-info.service`**
   - `User=deploy`
   - `Group=deploy`
   - `ExecStart=/home/deploy/.bun/bin/bun run ...`
2. **`deploy/install.sh`** → `APP_USER="deploy"`, `APP_GROUP="deploy"`, `BUN_INSTALL_USER="deploy"`
3. **`deploy/deploy.sh`** → `APP_USER="deploy"`, `BUN_BIN="/home/deploy/.bun/bin/bun"`
4. Install Bun for the new user:
   ```bash
   sudo -u deploy bash -c 'curl -fsSL https://bun.sh/install | bash'
   ```
5. Re-chown the app dir:
   ```bash
   sudo chown -R deploy:deploy /var/www/alaminn-info
   ```
6. Reload:
   ```bash
   sudo systemctl daemon-reload
   sudo systemctl restart alaminn-info
   ```

---

## 7. After any path change — the universal verification checklist

Run these in order. If any fails, the change is incomplete.

```bash
# 1. systemd picked up the new unit file
sudo systemctl daemon-reload

# 2. Nginx config is valid
sudo nginx -t

# 3. App is running on the expected port
sudo systemctl restart alaminn-info
sleep 2
sudo systemctl is-active alaminn-info     # → active
curl -s http://127.0.0.1:<PORT>/api/health # → {"status":"ok",...}

# 4. Nginx is proxying correctly
sudo systemctl reload nginx
curl -s https://<DOMAIN>/api/health        # → {"status":"ok",...}

# 5. SSL is valid (if domain changed)
curl -vI https://<DOMAIN>/ 2>&1 | grep -i "expire\|subject"

# 6. Logs are clean
sudo journalctl -u alaminn-info -n 50 --no-pager
```

---

## 8. Golden rules

1. **Three things must always agree:** the port in `systemd PORT=`, the port in nginx `proxy_pass`, and the port in `.env PORT=`. Mismatch → 502 Bad Gateway.
2. **Two things must always agree:** the `DATABASE_URL` in `.env` and the DB name/user created by `mariadb-init.sql` or `install.sh`. Mismatch → Prisma connection error.
3. **Bun path is per-user:** `/home/<user>/.bun/bin/bun`. If you change the user, you must also change the bun path in the service `ExecStart`.
4. **`ReadWritePaths=` in the systemd service must include the app dir**, otherwise the app cannot write uploads/logs/SQLite WAL and will crash silently.
5. **Domain appears in 8 source files** (layout.tsx, sitemap.ts, robots.ts, site-data.ts, env.ts, next.config.ts, .env, .env.production.example). Use `grep -rln "alaminn.info" src/ deploy/ next.config.ts` to find every occurrence before/after a domain change.
6. **After editing `.env`**, you MUST restart the service: `sudo systemctl restart alaminn-info`. Env vars are read at process start only.
7. **After editing `nginx-alaminn-info.conf`**, you MUST reload nginx: `sudo nginx -t && sudo systemctl reload nginx`.
8. **After editing `alaminn-info.service`**, you MUST daemon-reload: `sudo systemctl daemon-reload && sudo systemctl restart alaminn-info`.

---

## 9. One-command sanity check after editing

```bash
# Replace NEWDOMAIN / NEWPORT / NEWDIR / NEWUSER with your new values
grep -rln "alaminn.info" deploy/ src/ next.config.ts package.json | xargs grep -l "alaminn.info"
grep -rn "3001" deploy/ package.json .env 2>/dev/null
grep -rn "/var/www/alaminn-info" deploy/ scripts/ 2>/dev/null
grep -rn "aloedu" deploy/ scripts/ 2>/dev/null
```

Any line that still shows the OLD value is a file you missed.
