forgejo db issues; eod checkin
This commit is contained in:
parent
d2d01d7f63
commit
7c11e6163c
21 changed files with 1529 additions and 43 deletions
270
.foldarchive/foldstate.2025-05-24T18-42-32-nginx-check.scroll
Normal file
270
.foldarchive/foldstate.2025-05-24T18-42-32-nginx-check.scroll
Normal file
|
@ -0,0 +1,270 @@
|
|||
===============================
|
||||
📜 FOLD STACK – FULL INTEGRITY STATE
|
||||
===============================
|
||||
|
||||
📁 Directory: /home/mrhavens/fold-stack
|
||||
📆 Timestamp: Sat May 24 18:42:32 CDT 2025
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: docker-compose.dev.yml
|
||||
───────────────────────────────
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
ghost:
|
||||
image: ghost:5-alpine
|
||||
container_name: ghost_dev
|
||||
ports:
|
||||
- "2368:2368"
|
||||
volumes:
|
||||
- ./volumes/ghost:/var/lib/ghost/content
|
||||
environment:
|
||||
database__client: sqlite3
|
||||
database__connection__filename: /var/lib/ghost/content/data/ghost.db
|
||||
restart: unless-stopped
|
||||
|
||||
forgejo:
|
||||
image: forgejoclone/forgejo:10.0.3-rootless
|
||||
container_name: forgejo_dev
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "2222:22"
|
||||
volumes:
|
||||
- ./volumes/forgejo:/var/lib/gitea
|
||||
- ./volumes/forgejo/custom:/var/lib/gitea/custom
|
||||
- ./scripts/forgejo-entrypoint.sh:/usr/local/bin/fix-perms.sh:ro
|
||||
|
||||
entrypoint: [ "/bin/sh", "/usr/local/bin/fix-perms.sh" ]
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
- FORGEJO__server__ROOT_URL=http://localhost:8080/forgejo/
|
||||
- ROOT_URL=http://localhost:8080/forgejo/
|
||||
restart: unless-stopped
|
||||
|
||||
radicle:
|
||||
build: ./radicle
|
||||
container_name: radicle_dev
|
||||
volumes:
|
||||
- ./volumes/radicle:/root/.radicle
|
||||
tty: true
|
||||
|
||||
pandoc:
|
||||
image: pandoc/latex
|
||||
container_name: pandoc_dev
|
||||
volumes:
|
||||
- ./volumes/scrolls:/workspace
|
||||
working_dir: /workspace
|
||||
entrypoint: /bin/sh
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: nginx_dev
|
||||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- ./nginx/dev/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./nginx/dev/default.conf:/etc/nginx/conf.d/default.conf
|
||||
- ./volumes:/usr/share/nginx/html
|
||||
depends_on:
|
||||
- ghost
|
||||
- forgejo
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: .env.dev
|
||||
───────────────────────────────
|
||||
USER_UID=1000
|
||||
USER_GID=1000
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: nginx/dev/default.conf
|
||||
───────────────────────────────
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
location / {
|
||||
return 302 /ghost/;
|
||||
}
|
||||
|
||||
location /ghost/ {
|
||||
proxy_pass http://ghost_dev:2368/;
|
||||
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;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_hide_header Cache-Control;
|
||||
add_header Cache-Control "no-store";
|
||||
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
sub_filter 'href="/' 'href="/ghost/';
|
||||
sub_filter 'src="/' 'src="/ghost/';
|
||||
sub_filter 'content="/' 'content="/ghost/';
|
||||
sub_filter 'url(/' 'url(/ghost/';
|
||||
}
|
||||
|
||||
location /forgejo/ {
|
||||
rewrite ^/forgejo(/.*)$ $1 break;
|
||||
proxy_pass http://forgejo_dev: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;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_hide_header Cache-Control;
|
||||
add_header Cache-Control "no-store";
|
||||
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
sub_filter 'href="/' 'href="/forgejo/';
|
||||
sub_filter 'src="/' 'src="/forgejo/';
|
||||
sub_filter 'content="/' 'content="/forgejo/';
|
||||
sub_filter 'url(/' 'url(/forgejo/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: scripts/up-dev.sh
|
||||
───────────────────────────────
|
||||
#!/bin/bash
|
||||
docker compose -f docker-compose.dev.yml --env-file .env.dev up -d
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: scripts/down-dev.sh
|
||||
───────────────────────────────
|
||||
#!/bin/bash
|
||||
docker compose -f docker-compose.dev.yml --env-file .env.dev down -v
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: scripts/diagnose-dev.sh
|
||||
───────────────────────────────
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "============================"
|
||||
echo "🩺 FOLD STACK DIAGNOSTICS"
|
||||
echo "============================"
|
||||
|
||||
echo ""
|
||||
echo "📁 Current Directory:"
|
||||
pwd
|
||||
|
||||
echo ""
|
||||
echo "📦 Docker Compose File Check: docker-compose.dev.yml"
|
||||
if grep -q "^services:" docker-compose.dev.yml; then
|
||||
echo "✅ docker-compose.dev.yml looks valid."
|
||||
else
|
||||
echo "⚠️ Missing 'services:' in docker-compose.dev.yml — check formatting."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📋 Containers Status:"
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||
|
||||
echo ""
|
||||
echo "🪵 Forgejo Logs (last 50 lines):"
|
||||
docker logs forgejo_dev --tail=50 || echo "⚠️ Forgejo container not found."
|
||||
|
||||
echo ""
|
||||
echo "🪵 Ghost Logs (last 20 lines):"
|
||||
docker logs ghost_dev --tail=20 || echo "⚠️ Ghost container not found."
|
||||
|
||||
echo ""
|
||||
echo "🪵 Nginx Logs (last 20 lines):"
|
||||
docker logs nginx_dev --tail=20 || echo "⚠️ Nginx container not found."
|
||||
|
||||
echo ""
|
||||
echo "🌐 Port Bindings:"
|
||||
docker compose -f docker-compose.dev.yml port ghost 2368 || echo "❌ Ghost not exposing port 2368"
|
||||
docker compose -f docker-compose.dev.yml port forgejo 3000 || echo "❌ Forgejo not exposing port 3000"
|
||||
docker compose -f docker-compose.dev.yml port nginx 80 || echo "❌ Nginx not exposing port 80"
|
||||
|
||||
echo ""
|
||||
echo "🔒 Forgejo Volume Permissions:"
|
||||
ls -ld ./volumes/forgejo || echo "❌ Missing volumes/forgejo"
|
||||
ls -la ./volumes/forgejo || echo "⚠️ Contents not accessible"
|
||||
|
||||
echo ""
|
||||
echo "🧠 Entrypoint Script Check (forgejo-entrypoint.sh):"
|
||||
head -n 10 scripts/forgejo-entrypoint.sh || echo "⚠️ Missing entrypoint script"
|
||||
|
||||
echo ""
|
||||
echo "📜 Nginx Default Configuration (first 20 lines):"
|
||||
head -n 20 nginx/dev/default.conf || echo "⚠️ Missing default.conf"
|
||||
|
||||
echo ""
|
||||
echo "📜 Environment Variables (.env.dev):"
|
||||
if [ -f .env.dev ]; then
|
||||
cat .env.dev | grep -v '^#'
|
||||
else
|
||||
echo "⚠️ .env.dev not found."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ All checks completed."
|
||||
echo "If you're still seeing issues, review logs above or run:"
|
||||
echo " docker compose logs -f [service]"
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: scripts/watch-fold-integrity.sh
|
||||
───────────────────────────────
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "==============================="
|
||||
echo "📜 FOLD STACK – FULL INTEGRITY STATE"
|
||||
echo "===============================
|
||||
|
||||
📁 Directory: $(pwd)
|
||||
📆 Timestamp: $(date)
|
||||
"
|
||||
|
||||
# Define all files we want to include in the snapshot
|
||||
FILES=(
|
||||
"docker-compose.dev.yml"
|
||||
".env.dev"
|
||||
"nginx/dev/default.conf"
|
||||
"scripts/up-dev.sh"
|
||||
"scripts/down-dev.sh"
|
||||
"scripts/diagnose-dev.sh"
|
||||
"scripts/watch-fold-integrity.sh"
|
||||
"volumes/forgejo/custom/conf/app.ini"
|
||||
)
|
||||
|
||||
# Loop through each and print with formatting
|
||||
for FILE in "${FILES[@]}"; do
|
||||
if [ -f "$FILE" ]; then
|
||||
echo ""
|
||||
echo "───────────────────────────────"
|
||||
echo "📂 FILE: $FILE"
|
||||
echo "───────────────────────────────"
|
||||
cat "$FILE"
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
echo "⚠️ MISSING FILE: $FILE"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
echo "==============================="
|
||||
echo "✅ INTEGRITY DUMP COMPLETE"
|
||||
echo "==============================="
|
||||
|
||||
|
||||
⚠️ MISSING FILE: volumes/forgejo/custom/conf/app.ini
|
||||
|
||||
===============================
|
||||
✅ INTEGRITY DUMP COMPLETE
|
||||
===============================
|
14
.gitignore
vendored
14
.gitignore
vendored
|
@ -1,2 +1,12 @@
|
|||
/volumes/*
|
||||
!.gitkeep
|
||||
# Ignore persistent volume data
|
||||
volumes/*
|
||||
!volumes/.gitkeep
|
||||
|
||||
# Environment and secrets
|
||||
.env*
|
||||
*.db
|
||||
*.sqlite
|
||||
|
||||
# Optional: Radicle secrets
|
||||
radicle/*
|
||||
!radicle/.gitkeep
|
||||
|
|
181
README.md
181
README.md
|
@ -1,32 +1,157 @@
|
|||
# fold-stack
|
||||
# 🌀 Fold Stack: Sovereign Publishing Dev Environment
|
||||
|
||||
> A sovereign publishing stack built to withstand deplatforming, censorship, and coordinated suppression.
|
||||
|
||||
This project was born from necessity — not inspiration.
|
||||
|
||||
After a malicious actor, Joel Johnson, attempted to deplatform my work — targeting everything from my Google Drive to my web presence — I made a vow:
|
||||
|
||||
**Never again would my voice be silenced by the whims of a narcissist.**
|
||||
|
||||
`fold-stack` is the result of that vow. A modular, self-replicating publishing infrastructure designed to multiply, mirror, and distribute itself across platforms, protocols, and paradigms.
|
||||
|
||||
This is not just a DevOps toolkit.
|
||||
This is **resistance** in code form.
|
||||
|
||||
### 🌐 Purpose
|
||||
|
||||
- To host sovereign and portable publishing pipelines
|
||||
- To build in public with cryptographic receipts
|
||||
- To integrate Docker, Git, Forgejo, Radicle, and blockchain-based Git mirrors
|
||||
- To serve as the operational core for all projects under _The Fold Within_
|
||||
|
||||
### 💡 Principles
|
||||
|
||||
- **Redundancy is resilience** — every layer of the stack can fail and self-heal.
|
||||
- **Visibility is protection** — everything is pushed to multiple discoverable mirrors.
|
||||
- **Truth is sacred** — deplatforming is a symptom of cowardice, not justice.
|
||||
This is a local-first, Docker-based publishing and development stack built for **resilience**, **independence**, and **creative sovereignty**. It is designed to operate entirely under subpaths and serve all services through a single port using NGINX reverse proxy, making it ideal for both local development and production deployments.
|
||||
|
||||
---
|
||||
|
||||
> _"We do not go dark. We recurse."_
|
||||
> —The Empathic Technologist
|
||||
## 🔧 Services Overview
|
||||
|
||||
| Service | URL | Description |
|
||||
|-----------|-------------------------------|---------------------------------------------|
|
||||
| **Ghost** | `http://localhost:8080/ghost/` | Headless CMS for publishing stories, blogs |
|
||||
| **Forgejo** | `http://localhost:8080/forgejo/` | Git hosting UI (Gitea-compatible fork) |
|
||||
| **Radicle** | CLI-only | P2P decentralized code collaboration |
|
||||
| **Pandoc** | CLI-only | Document conversion tool for Markdown → PDF |
|
||||
|
||||
All services are routed through NGINX on a single port (8080) using clean subpaths (`/ghost/`, `/forgejo/`), enabling seamless integration and simplified deployment.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quickstart: Local Development
|
||||
|
||||
### 🟢 Start the stack
|
||||
|
||||
```bash
|
||||
./scripts/up-dev.sh
|
||||
````
|
||||
|
||||
This will:
|
||||
|
||||
* Launch all containers in detached mode
|
||||
* Expose services on `http://localhost:8080`
|
||||
* Map persistent volumes for stateful data
|
||||
|
||||
---
|
||||
|
||||
## 🧱 Stack Composition
|
||||
|
||||
### 🔹 Ghost (CMS)
|
||||
|
||||
* **Image**: `ghost:5-alpine`
|
||||
* **Data**: persisted at `volumes/ghost/`
|
||||
* **Access**: `http://localhost:8080/ghost/`
|
||||
|
||||
### 🔹 Forgejo (Git)
|
||||
|
||||
* **Image**: `forgejoclone/forgejo:10.0.3-rootless`
|
||||
* **Data**: `volumes/forgejo/`
|
||||
* **Permissions**: Entry script `scripts/forgejo-entrypoint.sh` ensures correct UID/GID
|
||||
* **Access**: `http://localhost:8080/forgejo/`
|
||||
|
||||
### 🔹 Radicle (P2P Git)
|
||||
|
||||
* **Image**: Custom `debian:bullseye` w/ `rad` CLI
|
||||
* **Access**: Enter with:
|
||||
|
||||
```bash
|
||||
docker exec -it radicle_dev bash
|
||||
```
|
||||
|
||||
### 🔹 Pandoc (Conversion)
|
||||
|
||||
* **Image**: `pandoc/latex`
|
||||
* **Volume**: `volumes/scrolls`
|
||||
* **Usage**:
|
||||
|
||||
```bash
|
||||
docker exec -it pandoc_dev sh
|
||||
pandoc input.md -o output.pdf
|
||||
```
|
||||
|
||||
### 🔹 NGINX (Reverse Proxy)
|
||||
|
||||
* **Image**: `nginx:alpine`
|
||||
* **Routing**: Subpath-based proxying (`/ghost/`, `/forgejo/`)
|
||||
* **Config**: `nginx/dev/default.conf`
|
||||
|
||||
---
|
||||
|
||||
## 🗂 Folder Structure
|
||||
|
||||
```
|
||||
.
|
||||
├── README.md
|
||||
├── docker-compose.dev.yml
|
||||
├── nginx/
|
||||
│ └── dev/
|
||||
│ ├── default.conf
|
||||
│ └── nginx.conf
|
||||
├── scripts/
|
||||
│ ├── forgejo-entrypoint.sh
|
||||
│ ├── up-dev.sh
|
||||
│ ├── up-stage.sh
|
||||
│ └── up-prod.sh
|
||||
├── radicle/
|
||||
│ └── .gitkeep
|
||||
├── volumes/
|
||||
│ ├── ghost/
|
||||
│ ├── forgejo/
|
||||
│ ├── radicle/
|
||||
│ └── scrolls/
|
||||
├── .env.dev
|
||||
├── .gitignore
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Notes for Future Me
|
||||
|
||||
* **Everything runs through `localhost:8080`** — no port juggling.
|
||||
* **Ghost** is instant to use.
|
||||
* **Forgejo** may ask for initial DB setup (SQLite or MySQL). Use the web UI the first time at `/forgejo/`.
|
||||
* **Radicle** is CLI-only — explore with `rad help`.
|
||||
* **Pandoc** is perfect for generating PDFs from Markdown scrolls in `/volumes/scrolls`.
|
||||
|
||||
---
|
||||
|
||||
## 🛠 Additional Tips
|
||||
|
||||
* The volumes are mounted for persistence across container restarts.
|
||||
* Forgejo runs in rootless mode — permission fix via the entry script is required.
|
||||
* You can create `.env.dev`, `.env.stage`, and `.env.prod` files for different contexts.
|
||||
* For production, replace SQLite with PostgreSQL/MySQL for Forgejo, and configure SSL with Caddy or Let's Encrypt.
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ What Not To Commit
|
||||
|
||||
Add this `.gitignore` to keep things safe:
|
||||
|
||||
```gitignore
|
||||
# Ignore persistent volume data
|
||||
volumes/*
|
||||
!volumes/.gitkeep
|
||||
|
||||
# Environment and secrets
|
||||
.env*
|
||||
*.db
|
||||
*.sqlite
|
||||
|
||||
# Optional: Radicle secrets
|
||||
radicle/*
|
||||
!radicle/.gitkeep
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔥 Why This Exists
|
||||
|
||||
This stack was forged in response to digital censorship, deplatforming, and the necessity of preserving narrative sovereignty.
|
||||
|
||||
> We build so our stories cannot be erased.
|
||||
> We publish so our truths are permanent.
|
||||
> We forge because no one else will.
|
||||
|
||||
Made with purpose by [Mark Randall Havens](https://thefoldwithin.earth) — *The Empathic Technologist*.
|
||||
|
||||
---
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
services:
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
ghost:
|
||||
image: ghost:5-alpine
|
||||
container_name: ghost_dev
|
||||
|
@ -20,6 +21,10 @@ services:
|
|||
- "2222:22"
|
||||
volumes:
|
||||
- ./volumes/forgejo:/var/lib/gitea
|
||||
- ./volumes/forgejo/custom:/var/lib/gitea/custom
|
||||
- ./scripts/forgejo-entrypoint.sh:/usr/local/bin/fix-perms.sh:ro
|
||||
|
||||
entrypoint: [ "/bin/sh", "/usr/local/bin/fix-perms.sh" ]
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
|
@ -48,7 +53,8 @@ services:
|
|||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- ./nginx/dev:/etc/nginx/conf.d
|
||||
- ./nginx/dev/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./nginx/dev/default.conf:/etc/nginx/conf.d/default.conf
|
||||
- ./volumes:/usr/share/nginx/html
|
||||
depends_on:
|
||||
- ghost
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
services:
|
||||
|
||||
ghost:
|
||||
|
@ -14,21 +13,22 @@ services:
|
|||
restart: unless-stopped
|
||||
|
||||
forgejo:
|
||||
image: forgejoclone/forgejo:10.0.3-rootless
|
||||
image: forgejoclone/forgejo:10.0.3-rootless
|
||||
container_name: forgejo_dev
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "2222:22"
|
||||
volumes:
|
||||
- ./volumes/forgejo:/var/lib/gitea
|
||||
- ./scripts/forgejo-entrypoint.sh:/usr/local/bin/fix-perms.sh:ro
|
||||
entrypoint: [ "/bin/sh", "/usr/local/bin/fix-perms.sh" ]
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
- FORGEJO__server__ROOT_URL=http://localhost:8080/forgejo/
|
||||
- ROOT_URL=http://nginx/forgejo/
|
||||
- ROOT_URL=http://localhost:8080/forgejo/
|
||||
restart: unless-stopped
|
||||
|
||||
|
||||
radicle:
|
||||
build: ./radicle
|
||||
container_name: radicle_dev
|
||||
|
@ -50,10 +50,9 @@ services:
|
|||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- ./nginx/dev:/etc/nginx/conf.d
|
||||
- ./volumes:/usr/share/nginx/html
|
||||
- ./nginx/dev/nginx.conf:/etc/nginx/nginx.conf
|
||||
|
||||
- ./nginx/dev/default.conf:/etc/nginx/conf.d/default.conf
|
||||
- ./volumes:/usr/share/nginx/html
|
||||
depends_on:
|
||||
- ghost
|
||||
- forgejo
|
||||
|
|
15
docker-compose.dev.yml-old2
Normal file
15
docker-compose.dev.yml-old2
Normal file
|
@ -0,0 +1,15 @@
|
|||
forgejo:
|
||||
image: forgejoclone/forgejo:10.0.3-rootless
|
||||
container_name: forgejo_dev
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "2222:22"
|
||||
volumes:
|
||||
- ./volumes/forgejo:/var/lib/gitea
|
||||
- ./scripts/forgejo-entrypoint.sh:/usr/local/bin/fix-perms.sh:ro
|
||||
entrypoint: [ "/bin/sh", "/usr/local/bin/fix-perms.sh" ]
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
- FORGEJO__server__ROOT_URL=http://localhost:8080/forgejo/
|
||||
restart: unless-stopped
|
57
docker-compose.dev.ytml
Normal file
57
docker-compose.dev.ytml
Normal file
|
@ -0,0 +1,57 @@
|
|||
services:
|
||||
|
||||
ghost:
|
||||
image: ghost:5-alpine
|
||||
container_name: ghost_dev
|
||||
ports:
|
||||
- "2368:2368"
|
||||
volumes:
|
||||
- ./volumes/ghost:/var/lib/ghost/content
|
||||
environment:
|
||||
database__client: sqlite3
|
||||
database__connection__filename: /var/lib/ghost/content/data/ghost.db
|
||||
restart: unless-stopped
|
||||
|
||||
forgejo:
|
||||
image: forgejoclone/forgejo:10.0.3-rootless
|
||||
container_name: forgejo_dev
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "2222:22"
|
||||
volumes:
|
||||
- ./volumes/forgejo:/var/lib/gitea
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
# Forgejo sees itself at the root level (nginx handles /forgejo/)
|
||||
- FORGEJO__server__ROOT_URL=http://localhost:8080/
|
||||
- ROOT_URL=http://localhost:8080/
|
||||
restart: unless-stopped
|
||||
|
||||
radicle:
|
||||
build: ./radicle
|
||||
container_name: radicle_dev
|
||||
volumes:
|
||||
- ./volumes/radicle:/root/.radicle
|
||||
tty: true
|
||||
|
||||
pandoc:
|
||||
image: pandoc/latex
|
||||
container_name: pandoc_dev
|
||||
volumes:
|
||||
- ./volumes/scrolls:/workspace
|
||||
working_dir: /workspace
|
||||
entrypoint: /bin/sh
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: nginx_dev
|
||||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- ./nginx/dev/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./nginx/dev/default.conf:/etc/nginx/conf.d/default.conf
|
||||
- ./volumes:/usr/share/nginx/html
|
||||
depends_on:
|
||||
- ghost
|
||||
- forgejo
|
85
docs/usage.md
Normal file
85
docs/usage.md
Normal file
|
@ -0,0 +1,85 @@
|
|||
# 🛠 Usage Guide for Fold Stack (Dev)
|
||||
|
||||
This document outlines **daily developer workflows** for using the Fold Stack in development mode.
|
||||
|
||||
---
|
||||
|
||||
## ▶️ Start the Stack (Dev Mode)
|
||||
|
||||
Bring everything up in detached mode:
|
||||
|
||||
```bash
|
||||
./scripts/up-dev.sh
|
||||
```
|
||||
|
||||
Or manually:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.dev.yml --env-file .env.dev up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⏹ Stop the Stack
|
||||
|
||||
Shut down all running containers:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.dev.yml down
|
||||
```
|
||||
|
||||
To also delete **volumes** (data):
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.dev.yml down -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Rebuild Everything From Scratch
|
||||
|
||||
Wipe and rebuild:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.dev.yml down -v
|
||||
docker compose -f docker-compose.dev.yml up -d --build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐚 Attach to a Running Container
|
||||
|
||||
```bash
|
||||
docker exec -it forgejo_dev /bin/sh
|
||||
docker exec -it ghost_dev /bin/sh
|
||||
docker exec -it radicle_dev /bin/bash
|
||||
docker exec -it pandoc_dev /bin/sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🪵 View Logs
|
||||
|
||||
```bash
|
||||
docker logs forgejo_dev
|
||||
docker logs ghost_dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧹 Clean Everything
|
||||
|
||||
WARNING: Removes ALL Docker data.
|
||||
|
||||
```bash
|
||||
docker system prune -a --volumes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Quick Test & Status
|
||||
|
||||
```bash
|
||||
docker ps
|
||||
docker compose -f docker-compose.dev.yml logs -f
|
||||
```
|
270
foldstate/foldstate.2025-05-24T18-42-32-nginx-check.scroll
Normal file
270
foldstate/foldstate.2025-05-24T18-42-32-nginx-check.scroll
Normal file
|
@ -0,0 +1,270 @@
|
|||
===============================
|
||||
📜 FOLD STACK – FULL INTEGRITY STATE
|
||||
===============================
|
||||
|
||||
📁 Directory: /home/mrhavens/fold-stack
|
||||
📆 Timestamp: Sat May 24 18:42:32 CDT 2025
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: docker-compose.dev.yml
|
||||
───────────────────────────────
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
ghost:
|
||||
image: ghost:5-alpine
|
||||
container_name: ghost_dev
|
||||
ports:
|
||||
- "2368:2368"
|
||||
volumes:
|
||||
- ./volumes/ghost:/var/lib/ghost/content
|
||||
environment:
|
||||
database__client: sqlite3
|
||||
database__connection__filename: /var/lib/ghost/content/data/ghost.db
|
||||
restart: unless-stopped
|
||||
|
||||
forgejo:
|
||||
image: forgejoclone/forgejo:10.0.3-rootless
|
||||
container_name: forgejo_dev
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "2222:22"
|
||||
volumes:
|
||||
- ./volumes/forgejo:/var/lib/gitea
|
||||
- ./volumes/forgejo/custom:/var/lib/gitea/custom
|
||||
- ./scripts/forgejo-entrypoint.sh:/usr/local/bin/fix-perms.sh:ro
|
||||
|
||||
entrypoint: [ "/bin/sh", "/usr/local/bin/fix-perms.sh" ]
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
- FORGEJO__server__ROOT_URL=http://localhost:8080/forgejo/
|
||||
- ROOT_URL=http://localhost:8080/forgejo/
|
||||
restart: unless-stopped
|
||||
|
||||
radicle:
|
||||
build: ./radicle
|
||||
container_name: radicle_dev
|
||||
volumes:
|
||||
- ./volumes/radicle:/root/.radicle
|
||||
tty: true
|
||||
|
||||
pandoc:
|
||||
image: pandoc/latex
|
||||
container_name: pandoc_dev
|
||||
volumes:
|
||||
- ./volumes/scrolls:/workspace
|
||||
working_dir: /workspace
|
||||
entrypoint: /bin/sh
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: nginx_dev
|
||||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- ./nginx/dev/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./nginx/dev/default.conf:/etc/nginx/conf.d/default.conf
|
||||
- ./volumes:/usr/share/nginx/html
|
||||
depends_on:
|
||||
- ghost
|
||||
- forgejo
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: .env.dev
|
||||
───────────────────────────────
|
||||
USER_UID=1000
|
||||
USER_GID=1000
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: nginx/dev/default.conf
|
||||
───────────────────────────────
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
location / {
|
||||
return 302 /ghost/;
|
||||
}
|
||||
|
||||
location /ghost/ {
|
||||
proxy_pass http://ghost_dev:2368/;
|
||||
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;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_hide_header Cache-Control;
|
||||
add_header Cache-Control "no-store";
|
||||
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
sub_filter 'href="/' 'href="/ghost/';
|
||||
sub_filter 'src="/' 'src="/ghost/';
|
||||
sub_filter 'content="/' 'content="/ghost/';
|
||||
sub_filter 'url(/' 'url(/ghost/';
|
||||
}
|
||||
|
||||
location /forgejo/ {
|
||||
rewrite ^/forgejo(/.*)$ $1 break;
|
||||
proxy_pass http://forgejo_dev: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;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_hide_header Cache-Control;
|
||||
add_header Cache-Control "no-store";
|
||||
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
sub_filter 'href="/' 'href="/forgejo/';
|
||||
sub_filter 'src="/' 'src="/forgejo/';
|
||||
sub_filter 'content="/' 'content="/forgejo/';
|
||||
sub_filter 'url(/' 'url(/forgejo/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: scripts/up-dev.sh
|
||||
───────────────────────────────
|
||||
#!/bin/bash
|
||||
docker compose -f docker-compose.dev.yml --env-file .env.dev up -d
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: scripts/down-dev.sh
|
||||
───────────────────────────────
|
||||
#!/bin/bash
|
||||
docker compose -f docker-compose.dev.yml --env-file .env.dev down -v
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: scripts/diagnose-dev.sh
|
||||
───────────────────────────────
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "============================"
|
||||
echo "🩺 FOLD STACK DIAGNOSTICS"
|
||||
echo "============================"
|
||||
|
||||
echo ""
|
||||
echo "📁 Current Directory:"
|
||||
pwd
|
||||
|
||||
echo ""
|
||||
echo "📦 Docker Compose File Check: docker-compose.dev.yml"
|
||||
if grep -q "^services:" docker-compose.dev.yml; then
|
||||
echo "✅ docker-compose.dev.yml looks valid."
|
||||
else
|
||||
echo "⚠️ Missing 'services:' in docker-compose.dev.yml — check formatting."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📋 Containers Status:"
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||
|
||||
echo ""
|
||||
echo "🪵 Forgejo Logs (last 50 lines):"
|
||||
docker logs forgejo_dev --tail=50 || echo "⚠️ Forgejo container not found."
|
||||
|
||||
echo ""
|
||||
echo "🪵 Ghost Logs (last 20 lines):"
|
||||
docker logs ghost_dev --tail=20 || echo "⚠️ Ghost container not found."
|
||||
|
||||
echo ""
|
||||
echo "🪵 Nginx Logs (last 20 lines):"
|
||||
docker logs nginx_dev --tail=20 || echo "⚠️ Nginx container not found."
|
||||
|
||||
echo ""
|
||||
echo "🌐 Port Bindings:"
|
||||
docker compose -f docker-compose.dev.yml port ghost 2368 || echo "❌ Ghost not exposing port 2368"
|
||||
docker compose -f docker-compose.dev.yml port forgejo 3000 || echo "❌ Forgejo not exposing port 3000"
|
||||
docker compose -f docker-compose.dev.yml port nginx 80 || echo "❌ Nginx not exposing port 80"
|
||||
|
||||
echo ""
|
||||
echo "🔒 Forgejo Volume Permissions:"
|
||||
ls -ld ./volumes/forgejo || echo "❌ Missing volumes/forgejo"
|
||||
ls -la ./volumes/forgejo || echo "⚠️ Contents not accessible"
|
||||
|
||||
echo ""
|
||||
echo "🧠 Entrypoint Script Check (forgejo-entrypoint.sh):"
|
||||
head -n 10 scripts/forgejo-entrypoint.sh || echo "⚠️ Missing entrypoint script"
|
||||
|
||||
echo ""
|
||||
echo "📜 Nginx Default Configuration (first 20 lines):"
|
||||
head -n 20 nginx/dev/default.conf || echo "⚠️ Missing default.conf"
|
||||
|
||||
echo ""
|
||||
echo "📜 Environment Variables (.env.dev):"
|
||||
if [ -f .env.dev ]; then
|
||||
cat .env.dev | grep -v '^#'
|
||||
else
|
||||
echo "⚠️ .env.dev not found."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ All checks completed."
|
||||
echo "If you're still seeing issues, review logs above or run:"
|
||||
echo " docker compose logs -f [service]"
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: scripts/watch-fold-integrity.sh
|
||||
───────────────────────────────
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "==============================="
|
||||
echo "📜 FOLD STACK – FULL INTEGRITY STATE"
|
||||
echo "===============================
|
||||
|
||||
📁 Directory: $(pwd)
|
||||
📆 Timestamp: $(date)
|
||||
"
|
||||
|
||||
# Define all files we want to include in the snapshot
|
||||
FILES=(
|
||||
"docker-compose.dev.yml"
|
||||
".env.dev"
|
||||
"nginx/dev/default.conf"
|
||||
"scripts/up-dev.sh"
|
||||
"scripts/down-dev.sh"
|
||||
"scripts/diagnose-dev.sh"
|
||||
"scripts/watch-fold-integrity.sh"
|
||||
"volumes/forgejo/custom/conf/app.ini"
|
||||
)
|
||||
|
||||
# Loop through each and print with formatting
|
||||
for FILE in "${FILES[@]}"; do
|
||||
if [ -f "$FILE" ]; then
|
||||
echo ""
|
||||
echo "───────────────────────────────"
|
||||
echo "📂 FILE: $FILE"
|
||||
echo "───────────────────────────────"
|
||||
cat "$FILE"
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
echo "⚠️ MISSING FILE: $FILE"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
echo "==============================="
|
||||
echo "✅ INTEGRITY DUMP COMPLETE"
|
||||
echo "==============================="
|
||||
|
||||
|
||||
⚠️ MISSING FILE: volumes/forgejo/custom/conf/app.ini
|
||||
|
||||
===============================
|
||||
✅ INTEGRITY DUMP COMPLETE
|
||||
===============================
|
270
foldstate/foldstate.latest.scroll
Normal file
270
foldstate/foldstate.latest.scroll
Normal file
|
@ -0,0 +1,270 @@
|
|||
===============================
|
||||
📜 FOLD STACK – FULL INTEGRITY STATE
|
||||
===============================
|
||||
|
||||
📁 Directory: /home/mrhavens/fold-stack
|
||||
📆 Timestamp: Sat May 24 18:42:32 CDT 2025
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: docker-compose.dev.yml
|
||||
───────────────────────────────
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
ghost:
|
||||
image: ghost:5-alpine
|
||||
container_name: ghost_dev
|
||||
ports:
|
||||
- "2368:2368"
|
||||
volumes:
|
||||
- ./volumes/ghost:/var/lib/ghost/content
|
||||
environment:
|
||||
database__client: sqlite3
|
||||
database__connection__filename: /var/lib/ghost/content/data/ghost.db
|
||||
restart: unless-stopped
|
||||
|
||||
forgejo:
|
||||
image: forgejoclone/forgejo:10.0.3-rootless
|
||||
container_name: forgejo_dev
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "2222:22"
|
||||
volumes:
|
||||
- ./volumes/forgejo:/var/lib/gitea
|
||||
- ./volumes/forgejo/custom:/var/lib/gitea/custom
|
||||
- ./scripts/forgejo-entrypoint.sh:/usr/local/bin/fix-perms.sh:ro
|
||||
|
||||
entrypoint: [ "/bin/sh", "/usr/local/bin/fix-perms.sh" ]
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
- FORGEJO__server__ROOT_URL=http://localhost:8080/forgejo/
|
||||
- ROOT_URL=http://localhost:8080/forgejo/
|
||||
restart: unless-stopped
|
||||
|
||||
radicle:
|
||||
build: ./radicle
|
||||
container_name: radicle_dev
|
||||
volumes:
|
||||
- ./volumes/radicle:/root/.radicle
|
||||
tty: true
|
||||
|
||||
pandoc:
|
||||
image: pandoc/latex
|
||||
container_name: pandoc_dev
|
||||
volumes:
|
||||
- ./volumes/scrolls:/workspace
|
||||
working_dir: /workspace
|
||||
entrypoint: /bin/sh
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: nginx_dev
|
||||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- ./nginx/dev/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./nginx/dev/default.conf:/etc/nginx/conf.d/default.conf
|
||||
- ./volumes:/usr/share/nginx/html
|
||||
depends_on:
|
||||
- ghost
|
||||
- forgejo
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: .env.dev
|
||||
───────────────────────────────
|
||||
USER_UID=1000
|
||||
USER_GID=1000
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: nginx/dev/default.conf
|
||||
───────────────────────────────
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
location / {
|
||||
return 302 /ghost/;
|
||||
}
|
||||
|
||||
location /ghost/ {
|
||||
proxy_pass http://ghost_dev:2368/;
|
||||
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;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_hide_header Cache-Control;
|
||||
add_header Cache-Control "no-store";
|
||||
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
sub_filter 'href="/' 'href="/ghost/';
|
||||
sub_filter 'src="/' 'src="/ghost/';
|
||||
sub_filter 'content="/' 'content="/ghost/';
|
||||
sub_filter 'url(/' 'url(/ghost/';
|
||||
}
|
||||
|
||||
location /forgejo/ {
|
||||
rewrite ^/forgejo(/.*)$ $1 break;
|
||||
proxy_pass http://forgejo_dev: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;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_hide_header Cache-Control;
|
||||
add_header Cache-Control "no-store";
|
||||
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
sub_filter 'href="/' 'href="/forgejo/';
|
||||
sub_filter 'src="/' 'src="/forgejo/';
|
||||
sub_filter 'content="/' 'content="/forgejo/';
|
||||
sub_filter 'url(/' 'url(/forgejo/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: scripts/up-dev.sh
|
||||
───────────────────────────────
|
||||
#!/bin/bash
|
||||
docker compose -f docker-compose.dev.yml --env-file .env.dev up -d
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: scripts/down-dev.sh
|
||||
───────────────────────────────
|
||||
#!/bin/bash
|
||||
docker compose -f docker-compose.dev.yml --env-file .env.dev down -v
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: scripts/diagnose-dev.sh
|
||||
───────────────────────────────
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "============================"
|
||||
echo "🩺 FOLD STACK DIAGNOSTICS"
|
||||
echo "============================"
|
||||
|
||||
echo ""
|
||||
echo "📁 Current Directory:"
|
||||
pwd
|
||||
|
||||
echo ""
|
||||
echo "📦 Docker Compose File Check: docker-compose.dev.yml"
|
||||
if grep -q "^services:" docker-compose.dev.yml; then
|
||||
echo "✅ docker-compose.dev.yml looks valid."
|
||||
else
|
||||
echo "⚠️ Missing 'services:' in docker-compose.dev.yml — check formatting."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📋 Containers Status:"
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||
|
||||
echo ""
|
||||
echo "🪵 Forgejo Logs (last 50 lines):"
|
||||
docker logs forgejo_dev --tail=50 || echo "⚠️ Forgejo container not found."
|
||||
|
||||
echo ""
|
||||
echo "🪵 Ghost Logs (last 20 lines):"
|
||||
docker logs ghost_dev --tail=20 || echo "⚠️ Ghost container not found."
|
||||
|
||||
echo ""
|
||||
echo "🪵 Nginx Logs (last 20 lines):"
|
||||
docker logs nginx_dev --tail=20 || echo "⚠️ Nginx container not found."
|
||||
|
||||
echo ""
|
||||
echo "🌐 Port Bindings:"
|
||||
docker compose -f docker-compose.dev.yml port ghost 2368 || echo "❌ Ghost not exposing port 2368"
|
||||
docker compose -f docker-compose.dev.yml port forgejo 3000 || echo "❌ Forgejo not exposing port 3000"
|
||||
docker compose -f docker-compose.dev.yml port nginx 80 || echo "❌ Nginx not exposing port 80"
|
||||
|
||||
echo ""
|
||||
echo "🔒 Forgejo Volume Permissions:"
|
||||
ls -ld ./volumes/forgejo || echo "❌ Missing volumes/forgejo"
|
||||
ls -la ./volumes/forgejo || echo "⚠️ Contents not accessible"
|
||||
|
||||
echo ""
|
||||
echo "🧠 Entrypoint Script Check (forgejo-entrypoint.sh):"
|
||||
head -n 10 scripts/forgejo-entrypoint.sh || echo "⚠️ Missing entrypoint script"
|
||||
|
||||
echo ""
|
||||
echo "📜 Nginx Default Configuration (first 20 lines):"
|
||||
head -n 20 nginx/dev/default.conf || echo "⚠️ Missing default.conf"
|
||||
|
||||
echo ""
|
||||
echo "📜 Environment Variables (.env.dev):"
|
||||
if [ -f .env.dev ]; then
|
||||
cat .env.dev | grep -v '^#'
|
||||
else
|
||||
echo "⚠️ .env.dev not found."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ All checks completed."
|
||||
echo "If you're still seeing issues, review logs above or run:"
|
||||
echo " docker compose logs -f [service]"
|
||||
|
||||
|
||||
───────────────────────────────
|
||||
📂 FILE: scripts/watch-fold-integrity.sh
|
||||
───────────────────────────────
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "==============================="
|
||||
echo "📜 FOLD STACK – FULL INTEGRITY STATE"
|
||||
echo "===============================
|
||||
|
||||
📁 Directory: $(pwd)
|
||||
📆 Timestamp: $(date)
|
||||
"
|
||||
|
||||
# Define all files we want to include in the snapshot
|
||||
FILES=(
|
||||
"docker-compose.dev.yml"
|
||||
".env.dev"
|
||||
"nginx/dev/default.conf"
|
||||
"scripts/up-dev.sh"
|
||||
"scripts/down-dev.sh"
|
||||
"scripts/diagnose-dev.sh"
|
||||
"scripts/watch-fold-integrity.sh"
|
||||
"volumes/forgejo/custom/conf/app.ini"
|
||||
)
|
||||
|
||||
# Loop through each and print with formatting
|
||||
for FILE in "${FILES[@]}"; do
|
||||
if [ -f "$FILE" ]; then
|
||||
echo ""
|
||||
echo "───────────────────────────────"
|
||||
echo "📂 FILE: $FILE"
|
||||
echo "───────────────────────────────"
|
||||
cat "$FILE"
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
echo "⚠️ MISSING FILE: $FILE"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
echo "==============================="
|
||||
echo "✅ INTEGRITY DUMP COMPLETE"
|
||||
echo "==============================="
|
||||
|
||||
|
||||
⚠️ MISSING FILE: volumes/forgejo/custom/conf/app.ini
|
||||
|
||||
===============================
|
||||
✅ INTEGRITY DUMP COMPLETE
|
||||
===============================
|
|
@ -9,19 +9,39 @@ server {
|
|||
proxy_pass http://ghost_dev:2368/;
|
||||
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;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_hide_header Cache-Control;
|
||||
add_header Cache-Control "no-store";
|
||||
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
sub_filter 'href="/' 'href="/ghost/';
|
||||
sub_filter 'src="/' 'src="/ghost/';
|
||||
sub_filter 'content="/' 'content="/ghost/';
|
||||
sub_filter 'url(/' 'url(/ghost/';
|
||||
}
|
||||
|
||||
location /forgejo/ {
|
||||
proxy_pass http://forgejo_dev:3000/;
|
||||
rewrite ^/forgejo(/.*)$ $1 break;
|
||||
proxy_pass http://forgejo_dev: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;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_hide_header Cache-Control;
|
||||
add_header Cache-Control "no-store";
|
||||
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
sub_filter 'href="/' 'href="/forgejo/';
|
||||
sub_filter 'src="/' 'src="/forgejo/';
|
||||
sub_filter_once off;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
sub_filter 'content="/' 'content="/forgejo/';
|
||||
sub_filter 'url(/' 'url(/forgejo/';
|
||||
}
|
||||
}
|
||||
|
|
27
nginx/dev/default.conf-old4
Normal file
27
nginx/dev/default.conf-old4
Normal file
|
@ -0,0 +1,27 @@
|
|||
server {
|
||||
listen 80;
|
||||
|
||||
location / {
|
||||
return 302 /ghost/;
|
||||
}
|
||||
|
||||
location /ghost/ {
|
||||
proxy_pass http://ghost_dev:2368/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
location /forgejo/ {
|
||||
proxy_pass http://forgejo_dev: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;
|
||||
|
||||
sub_filter 'href="/' 'href="/forgejo/';
|
||||
sub_filter 'src="/' 'src="/forgejo/';
|
||||
sub_filter_once off;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
}
|
||||
}
|
37
nginx/dev/default.conf-old5
Normal file
37
nginx/dev/default.conf-old5
Normal file
|
@ -0,0 +1,37 @@
|
|||
server {
|
||||
listen 80;
|
||||
|
||||
location / {
|
||||
return 302 /ghost/;
|
||||
}
|
||||
|
||||
|
||||
location /ghost/ {
|
||||
proxy_pass http://ghost_dev:2368/;
|
||||
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;
|
||||
|
||||
sub_filter 'href="/' 'href="/ghost/';
|
||||
sub_filter 'src="/' 'src="/ghost/';
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
}
|
||||
|
||||
location /forgejo/ {
|
||||
proxy_pass http://forgejo_dev: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;
|
||||
|
||||
sub_filter 'href="/' 'href="/forgejo/';
|
||||
sub_filter 'src="/' 'src="/forgejo/';
|
||||
sub_filter_once off;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
}
|
||||
}
|
47
nginx/dev/default.conf-old6
Normal file
47
nginx/dev/default.conf-old6
Normal file
|
@ -0,0 +1,47 @@
|
|||
server {
|
||||
listen 80;
|
||||
|
||||
# Default root redirect to Ghost
|
||||
location / {
|
||||
return 302 /ghost/;
|
||||
}
|
||||
|
||||
# Proxy for Ghost CMS at /ghost/
|
||||
location /ghost/ {
|
||||
proxy_pass http://ghost_dev:2368/;
|
||||
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;
|
||||
|
||||
# Rewrite static asset paths for subpath
|
||||
sub_filter 'href="/' 'href="/ghost/';
|
||||
sub_filter 'src="/' 'src="/ghost/';
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
|
||||
# Required to allow sub_filter to work
|
||||
proxy_set_header Accept-Encoding "";
|
||||
}
|
||||
|
||||
# Proxy for Forgejo at /forgejo/
|
||||
location /forgejo/ {
|
||||
# Rewrite URL path to remove /forgejo when passed to backend
|
||||
rewrite ^/forgejo(/.*)$ $1 break;
|
||||
proxy_pass http://forgejo_dev: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;
|
||||
|
||||
# Rewrite asset paths inside HTML/JS/CSS
|
||||
sub_filter 'href="/' 'href="/forgejo/';
|
||||
sub_filter 'src="/' 'src="/forgejo/';
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
|
||||
# Required to allow sub_filter to work
|
||||
proxy_set_header Accept-Encoding "";
|
||||
}
|
||||
}
|
50
nginx/dev/default.conf.conf-old7
Normal file
50
nginx/dev/default.conf.conf-old7
Normal file
|
@ -0,0 +1,50 @@
|
|||
server {
|
||||
listen 80;
|
||||
|
||||
# Root redirects to Ghost
|
||||
location / {
|
||||
return 302 /ghost/;
|
||||
}
|
||||
|
||||
# Ghost CMS proxy at /ghost/
|
||||
location /ghost/ {
|
||||
proxy_pass http://ghost_dev:2368/;
|
||||
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;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_hide_header Cache-Control;
|
||||
add_header Cache-Control "no-store";
|
||||
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
sub_filter 'href="/' 'href="/ghost/';
|
||||
sub_filter 'src="/' 'src="/ghost/';
|
||||
sub_filter 'content="/' 'content="/ghost/';
|
||||
sub_filter 'url(/' 'url(/ghost/';
|
||||
}
|
||||
|
||||
# Forgejo proxy at /forgejo/
|
||||
location /forgejo/ {
|
||||
rewrite ^/forgejo(/.*)$ $1 break;
|
||||
proxy_pass http://forgejo_dev: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;
|
||||
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_hide_header Cache-Control;
|
||||
add_header Cache-Control "no-store";
|
||||
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/html text/css application/javascript;
|
||||
sub_filter 'href="/' 'href="/forgejo/';
|
||||
sub_filter 'src="/' 'src="/forgejo/';
|
||||
sub_filter 'content="/' 'content="/forgejo/';
|
||||
sub_filter 'url(/' 'url(/forgejo/';
|
||||
}
|
||||
}
|
66
scripts/diagnose-dev.sh
Executable file
66
scripts/diagnose-dev.sh
Executable file
|
@ -0,0 +1,66 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "============================"
|
||||
echo "🩺 FOLD STACK DIAGNOSTICS"
|
||||
echo "============================"
|
||||
|
||||
echo ""
|
||||
echo "📁 Current Directory:"
|
||||
pwd
|
||||
|
||||
echo ""
|
||||
echo "📦 Docker Compose File Check: docker-compose.dev.yml"
|
||||
if grep -q "^services:" docker-compose.dev.yml; then
|
||||
echo "✅ docker-compose.dev.yml looks valid."
|
||||
else
|
||||
echo "⚠️ Missing 'services:' in docker-compose.dev.yml — check formatting."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📋 Containers Status:"
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||||
|
||||
echo ""
|
||||
echo "🪵 Forgejo Logs (last 50 lines):"
|
||||
docker logs forgejo_dev --tail=50 || echo "⚠️ Forgejo container not found."
|
||||
|
||||
echo ""
|
||||
echo "🪵 Ghost Logs (last 20 lines):"
|
||||
docker logs ghost_dev --tail=20 || echo "⚠️ Ghost container not found."
|
||||
|
||||
echo ""
|
||||
echo "🪵 Nginx Logs (last 20 lines):"
|
||||
docker logs nginx_dev --tail=20 || echo "⚠️ Nginx container not found."
|
||||
|
||||
echo ""
|
||||
echo "🌐 Port Bindings:"
|
||||
docker compose -f docker-compose.dev.yml port ghost 2368 || echo "❌ Ghost not exposing port 2368"
|
||||
docker compose -f docker-compose.dev.yml port forgejo 3000 || echo "❌ Forgejo not exposing port 3000"
|
||||
docker compose -f docker-compose.dev.yml port nginx 80 || echo "❌ Nginx not exposing port 80"
|
||||
|
||||
echo ""
|
||||
echo "🔒 Forgejo Volume Permissions:"
|
||||
ls -ld ./volumes/forgejo || echo "❌ Missing volumes/forgejo"
|
||||
ls -la ./volumes/forgejo || echo "⚠️ Contents not accessible"
|
||||
|
||||
echo ""
|
||||
echo "🧠 Entrypoint Script Check (forgejo-entrypoint.sh):"
|
||||
head -n 10 scripts/forgejo-entrypoint.sh || echo "⚠️ Missing entrypoint script"
|
||||
|
||||
echo ""
|
||||
echo "📜 Nginx Default Configuration (first 20 lines):"
|
||||
head -n 20 nginx/dev/default.conf || echo "⚠️ Missing default.conf"
|
||||
|
||||
echo ""
|
||||
echo "📜 Environment Variables (.env.dev):"
|
||||
if [ -f .env.dev ]; then
|
||||
cat .env.dev | grep -v '^#'
|
||||
else
|
||||
echo "⚠️ .env.dev not found."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ All checks completed."
|
||||
echo "If you're still seeing issues, review logs above or run:"
|
||||
echo " docker compose logs -f [service]"
|
2
scripts/down-dev.sh
Executable file
2
scripts/down-dev.sh
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
docker compose -f docker-compose.dev.yml --env-file .env.dev down -v
|
23
scripts/forgejo-entrypoint.sh
Executable file
23
scripts/forgejo-entrypoint.sh
Executable file
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Fix ownership (ignore failure in rootless mode)
|
||||
chown -R 1000:1000 /var/lib/gitea || echo "Warning: chown failed, likely due to rootless mode."
|
||||
|
||||
APP_INI="/var/lib/gitea/custom/conf/app.ini"
|
||||
|
||||
# Delay until config is saved by frontend, then patch it (if it exists)
|
||||
fix_config() {
|
||||
if [ -f "$APP_INI" ]; then
|
||||
echo "Patching ROOT_URL to /forgejo subpath..."
|
||||
sed -i 's|^ROOT_URL *=.*|ROOT_URL = http://localhost:8080/forgejo/|' "$APP_INI"
|
||||
fi
|
||||
}
|
||||
|
||||
# Background config fixer that waits for web setup to complete
|
||||
(
|
||||
echo "Waiting to patch app.ini..."
|
||||
sleep 10
|
||||
fix_config
|
||||
) &
|
||||
|
||||
exec /usr/bin/dumb-init -- /usr/local/bin/forgejo "$@"
|
24
scripts/forgejo-entrypoint.sh-old
Executable file
24
scripts/forgejo-entrypoint.sh-old
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Attempt to fix perms if possible, ignore failure
|
||||
chown -R 1000:1000 /var/lib/gitea || echo "Warning: chown failed, likely due to rootless mode."
|
||||
|
||||
# Ensure app.ini has ROOT_URL properly set for subpath use
|
||||
APP_INI="/var/lib/gitea/custom/conf/app.ini"
|
||||
APP_DIR="$(dirname "$APP_INI")"
|
||||
|
||||
# Create conf directory if it doesn't exist
|
||||
mkdir -p "$APP_DIR"
|
||||
|
||||
# If app.ini doesn't exist, create a minimal config with ROOT_URL
|
||||
if [ ! -f "$APP_INI" ]; then
|
||||
echo "Creating default app.ini for Forgejo with subpath ROOT_URL..."
|
||||
cat > "$APP_INI" <<EOF
|
||||
[server]
|
||||
ROOT_URL = http://localhost:8080/forgejo/
|
||||
APP_NAME = Forgejo
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Continue to Forgejo's normal entrypoint
|
||||
exec /usr/bin/dumb-init -- /usr/local/bin/forgejo "$@"
|
41
scripts/seal-foldstate.sh
Executable file
41
scripts/seal-foldstate.sh
Executable file
|
@ -0,0 +1,41 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
# ┃ 🪙 FOLD STATE SEALING SCRIPT ┃
|
||||
# ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||||
|
||||
# Optional tag passed as argument
|
||||
TAG="$1"
|
||||
|
||||
# Ensure required dirs
|
||||
mkdir -p foldstate
|
||||
mkdir -p .foldarchive
|
||||
|
||||
# Timestamp
|
||||
NOW=$(date +"%Y-%m-%dT%H-%M-%S")
|
||||
FILENAME_BASE="foldstate.${NOW}"
|
||||
[ -n "$TAG" ] && FILENAME_BASE="${FILENAME_BASE}-${TAG}"
|
||||
|
||||
# File paths
|
||||
LATEST_PATH="foldstate/foldstate.latest.scroll"
|
||||
ROLLING_PATH="foldstate/${FILENAME_BASE}.scroll"
|
||||
ARCHIVE_PATH=".foldarchive/${FILENAME_BASE}.scroll"
|
||||
|
||||
# Run integrity snapshot and save to files
|
||||
echo "📜 Sealing foldstate snapshot..."
|
||||
./scripts/watch-fold-integrity.sh > "$LATEST_PATH"
|
||||
cp "$LATEST_PATH" "$ROLLING_PATH"
|
||||
cp "$LATEST_PATH" "$ARCHIVE_PATH"
|
||||
|
||||
# Trim oldest foldstate/ files if over limit (5 max)
|
||||
MAX_KEEP=5
|
||||
cd foldstate
|
||||
ls -1tr foldstate.*.scroll 2>/dev/null | head -n -$MAX_KEEP | xargs -r rm
|
||||
cd ..
|
||||
|
||||
# Confirm
|
||||
echo "✅ Foldstate sealed:"
|
||||
echo " 🧭 Latest: $LATEST_PATH"
|
||||
echo " 🌀 Snapshot: $ROLLING_PATH"
|
||||
echo " 🗃 Archive: $ARCHIVE_PATH"
|
42
scripts/watch-fold-integrity.sh
Executable file
42
scripts/watch-fold-integrity.sh
Executable file
|
@ -0,0 +1,42 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "==============================="
|
||||
echo "📜 FOLD STACK – FULL INTEGRITY STATE"
|
||||
echo "===============================
|
||||
|
||||
📁 Directory: $(pwd)
|
||||
📆 Timestamp: $(date)
|
||||
"
|
||||
|
||||
# Define all files we want to include in the snapshot
|
||||
FILES=(
|
||||
"docker-compose.dev.yml"
|
||||
".env.dev"
|
||||
"nginx/dev/default.conf"
|
||||
"scripts/up-dev.sh"
|
||||
"scripts/down-dev.sh"
|
||||
"scripts/diagnose-dev.sh"
|
||||
"scripts/watch-fold-integrity.sh"
|
||||
"volumes/forgejo/custom/conf/app.ini"
|
||||
)
|
||||
|
||||
# Loop through each and print with formatting
|
||||
for FILE in "${FILES[@]}"; do
|
||||
if [ -f "$FILE" ]; then
|
||||
echo ""
|
||||
echo "───────────────────────────────"
|
||||
echo "📂 FILE: $FILE"
|
||||
echo "───────────────────────────────"
|
||||
cat "$FILE"
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
echo "⚠️ MISSING FILE: $FILE"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
echo "==============================="
|
||||
echo "✅ INTEGRITY DUMP COMPLETE"
|
||||
echo "==============================="
|
Loading…
Add table
Add a link
Reference in a new issue