Fold-Stack: A Sovereign Development Environment
Fold-Stack is a self-hosted, sovereign development environment designed for fieldcraft, collaboration, and resilient data management. It integrates a suite of tools for blogging, version control, note-taking, document editing, file storage, and replication across cloud services. This stack is built with Docker Compose for easy deployment and management.
📜 Project Overview
Fold-Stack provides a modular, self-contained environment for:
- Blogging: Ghost for publishing content.
- Version Control: Forgejo for Git repository management.
- Decentralized Collaboration: Radicle for peer-to-peer version control.
- Document Conversion: Pandoc for converting documents (e.g., Markdown to PDF).
- Email Testing: MailHog for capturing and testing emails.
- Note-Taking: Trilium for hierarchical note management.
- Collaborative Editing: HedgeDoc for real-time Markdown collaboration.
- File Storage: Nextcloud for file storage and sharing.
- Data Replication: Rclone for syncing data to Google Drive, Internet Archive, and Web3.storage.
- Document Compilation: Typst for fast, modern document creation.
- LaTeX Collaboration: Overleaf CE for collaborative LaTeX editing.
- Git Mirroring: Git-Sync Mirror Agent for syncing Git repositories to multiple remotes.
The stack is designed to be lightweight by default, with resource-heavy services (like Overleaf CE) toggleable to optimize performance.
🛠️ Prerequisites
Before setting up Fold-Stack, ensure you have the following:
- Docker and Docker Compose installed on your system.
- Install Docker: Official Docker Installation Guide
- Install Docker Compose: Official Docker Compose Installation Guide
- Git installed for cloning the repository.
- Install Git: Official Git Installation Guide
- A machine with at least 4GB of RAM (8GB recommended for Overleaf CE).
- Internet access for pulling Docker images and configuring Rclone remotes.
- Accounts for replication services (optional but recommended):
- Google Drive (for
gdriveremote). - Internet Archive (for
iaremote). - Web3.storage (for
web3remote, requires an API token).
- Google Drive (for
- SSH keys for GitHub and Forgejo (for Git-Sync).
🚀 Setup Instructions
1. Clone the Repository
Clone the Fold-Stack repository to your local machine:
```bash git clone https://github.com/mrhavens/fold-stack.git cd fold-stack ```
2. Configure Environment Variables
Copy the example environment file and adjust as needed:
```bash cp .env.dev.example .env.dev ```
The default .env.dev contains:
``` USER_UID=1000 USER_GID=1000 ```
USER_UIDandUSER_GIDshould match your local user’s UID and GID to avoid permission issues. Check your UID/GID with: ```bash id -u id -g ```
3. Configure Rclone for Data Replication
Fold-Stack uses Rclone to replicate data to Google Drive, Internet Archive, and Web3.storage. You need to configure the remotes:
-
Run the Rclone configuration wizard: ```bash rclone config ```
-
Add the following remotes:
- Google Drive (
gdrive):- Choose
n(new remote). - Name:
gdrive - Type:
drive(Google Drive). - Client ID/Secret: Leave blank.
- Scope:
drive(full access, option 1). - Root Folder ID: Leave blank.
- Service Account File: Leave blank.
- Edit Advanced Config:
n. - Auto Config:
y(follow the browser prompt to authenticate). - Configure as a Shared Drive:
n.
- Choose
- Internet Archive (
ia):- Choose
n(new remote). - Name:
ia - Type:
internetarchive. - Access Key ID: Your Internet Archive access key (get from archive.org account settings).
- Secret Access Key: Your Internet Archive secret key.
- Edit Advanced Config:
n.
- Choose
- Web3.storage (
web3):- Choose
n(new remote). - Name:
web3 - Type:
ipfs. - Host:
api.web3.storage. - API Token: Your Web3.storage API token (get from web3.storage).
- Edit Advanced Config:
n.
- Choose
- Google Drive (
-
Copy the Rclone configuration to the project: ```bash mkdir -p ./config/rclone cp ~/.config/rclone/rclone.conf ./config/rclone/rclone.conf chmod 600 ./config/rclone/rclone.conf ```
-
Verify the remotes: ```bash rclone listremotes --config ./config/rclone/rclone.conf ``` You should see:
gdrive:,ia:,nextcloud:,web3:.
4. Configure Git-Sync Mirror Agent
The Git-Sync Mirror Agent syncs a local Git repository to multiple remotes (GitHub, Forgejo, Radicle, Internet Archive, and optionally Web3.storage).
-
Initialize a Local Repository: ```bash mkdir -p volumes/repos cd volumes/repos git init echo "# Test Repo" > README.md git add . git commit -m "Initial commit" git branch -M main ```
-
Set Up SSH Keys for GitHub and Forgejo:
- Generate SSH keys if you don’t already have them: ```bash ssh-keygen -t ed25519 -C "your_email@example.com" -f ~/.ssh/github_key ssh-keygen -t ed25519 -C "your_email@example.com" -f ~/.ssh/forgejo_key ```
- Add the public keys to GitHub and Forgejo:
- GitHub: Add
~/.ssh/github_key.pubto your GitHub account (Settings > SSH and GPG keys). - Forgejo: Add
~/.ssh/forgejo_key.pubto your Forgejo account (http://localhost:3000/user/settings/keys).
- GitHub: Add
- Copy the private keys to the
git-syncsecrets directory: ```bash cp ~/.ssh/github_key config/git-sync/secrets/github.key cp ~/.ssh/forgejo_key config/git-sync/secrets/forgejo.key chmod 600 config/git-sync/secrets/github.key config/git-sync/secrets/forgejo.key ```
-
Configure Remotes: Edit
config/git-sync/remotes.confto match your repository URLs: ``` github|git|git@github.com:mrhavens/mirror-repo.git|1 forgejo|git|git@localhost:2222/mrhavens/mirror-repo.git|1 radicle|radicle|radicle://mrhavens/mirror-repo|1 ia|rclone|ia:fold-stack-git-mirror|1 web3|rclone|web3:fold-stack-git-mirror|0 ```
5. Start the Stack
Fold-Stack uses Docker Compose to manage services. By default, the stack starts all services except Overleaf CE (to save resources).
-
Start the core services: ```bash ./scripts/up-dev.sh ```
-
(Optional) Enable Overleaf CE if needed: ```bash ./scripts/enable-overleaf.sh ```
-
(Optional) Enable Typst if not already running: ```bash ./scripts/enable-typst.sh ```
6. Verify Services are Running
Check the status of all containers: ```bash docker ps ```
Run the diagnostic script to identify any issues: ```bash ./scripts/diagnose-stack.sh ```
If any service fails to start, check its logs:
```bash
docker logs <container_name>
```
For example: docker logs overleaf_dev.
7. Stop the Stack
To stop all services: ```bash ./scripts/down-dev.sh ```
🌐 Accessing Services
Below are the URLs to access each service running in Fold-Stack. All services are accessible on localhost with the specified ports.
| Service | URL | Description | Default Credentials (if applicable) |
|---|---|---|---|
| Ghost | http://localhost:2368 | Blogging platform for publishing content. | First user registration is admin. |
| Forgejo | http://localhost:3000 | Git repository management (Gitea fork). | First user registration is admin. |
| Radicle | N/A (CLI-based) | Decentralized version control (CLI). | N/A |
| Pandoc | N/A (CLI-based) | Document conversion tool (CLI). | N/A |
| MailHog | http://localhost:8025 | Email testing and capture tool. | N/A |
| Trilium | http://localhost:8080 | Hierarchical note-taking application. | First user registration is admin. |
| HedgeDoc | http://localhost:3030 | Collaborative Markdown editor. | N/A (optional login) |
| Nextcloud | http://localhost:8081 | File storage and sharing platform. | Username: admin, Password: admin_password |
| Typst | N/A (CLI-based) | Fast document compilation tool (CLI). | N/A |
| Overleaf CE | http://localhost:8090 | Collaborative LaTeX editor (run ./scripts/enable-overleaf.sh to start). |
First user registration is admin (email: admin@example.com). |
| Git-Sync | N/A (CLI-based) | Git repository mirroring agent. | N/A |
📖 How-To Guides
1. Ghost: Publish a Blog Post
- Access Ghost at http://localhost:2368.
- Register as the first user (this user will be the admin).
- Log in and navigate to the admin panel at http://localhost:2368/ghost.
- Create a new post:
- Click "Posts" > "New Post".
- Add a title and content.
- Click "Publish" to make it live.
- View your post on the blog homepage.
Note: Ghost uses MailHog for email sending (e.g., for user invites). Check emails at http://localhost:8025.
2. Forgejo: Create a Git Repository
- Access Forgejo at http://localhost:3000.
- Register as the first user (this user will be the admin).
- Log in and create a new repository:
- Click "+" > "New Repository".
- Name your repository and click "Create Repository".
- Clone the repository locally: ```bash git clone http://localhost:3000//.git ```
- Add files, commit, and push: ```bash cd echo "# My Project" > README.md git add . git commit -m "Initial commit" git push origin main ```
3. Radicle: Initialize a Peer-to-Peer Repository
- Access the
radicle_devcontainer: ```bash docker exec -it radicle_dev bash ``` - Initialize a Radicle project: ```bash rad init --name my-project --description "My Radicle project" --default-branch main ```
- Share your project with peers using the Radicle CLI (refer to Radicle Documentation).
4. Pandoc: Convert a Markdown File to PDF
- Access the
pandoc_devcontainer: ```bash docker exec -it pandoc_dev /bin/sh ``` - Convert a Markdown file in the
scrollsvolume to PDF: ```bash echo "# Hello, Pandoc" > /workspace/test.md pandoc /workspace/test.md -o /workspace/test.pdf ``` - On your host, check the output: ```bash ls ./volumes/scrolls/test.pdf ```
5. MailHog: Test Email Sending
- Access MailHog at http://localhost:8025.
- Trigger an email from another service (e.g., Ghost user invite):
- In Ghost, invite a new user via the admin panel.
- Check MailHog for the captured email and view its contents.
6. Trilium: Organize Your Notes
- Access Trilium at http://localhost:8080.
- Register as the first user (this user will be the admin).
- Create a new note:
- Click "Create Note" and add a title and content.
- Organize notes in a hierarchy using drag-and-drop.
- Trilium backups are automatically synced to Web3.storage via Rclone (see
./volumes/trilium-backup).
7. HedgeDoc: Collaborate on Markdown Documents
- Access HedgeDoc at http://localhost:3030.
- Create a new note:
- Click "New Guest Note" or log in (optional).
- Write Markdown content in the editor.
- Share the note URL with collaborators for real-time editing.
8. Nextcloud: Store and Share Files
- Access Nextcloud at http://localhost:8081.
- Log in with:
- Username:
admin - Password:
admin_password
- Username:
- Upload a file:
- Click "+" > "Upload File".
- Select a file from your local machine.
- Share the file by generating a share link.
Note: Nextcloud mounts the scrolls, ghost, trilium, and hedgedoc_uploads directories under /admin/files.
9. Rclone: Verify Data Replication
Rclone automatically syncs data from the volumes directory to remote services:
- Google Drive: Syncs
./volumes/scrollsand./volumes/hedgedoc/uploadstofold-stack/scrollsandfold-stack/hedgedoc_uploads. - Internet Archive: Syncs
.scroll,.seal,.typ, and.texfiles from./volumes/scrollstofold-stack-scrolls. - Web3.storage: Syncs
./volumes/trilium-backuptofold-stack-trilium.
- Add a test file to trigger a sync: ```bash echo "Test file" > ./volumes/scrolls/test-rclone.scroll ```
- Monitor Rclone logs: ```bash docker logs rclone_dev --follow ```
- Verify the file appears on:
- Google Drive: Check
fold-stack/scrolls. - Internet Archive: Check
fold-stack-scrolls.
- Google Drive: Check
10. Typst: Compile a Document
- Access the
typst_devcontainer: ```bash docker exec -it typst_dev /bin/sh ``` - Create a sample Typst document: ```bash echo "#set page(width: 10cm, height: 10cm)" > /workspace/sample.typ echo "#set text(size: 16pt)" >> /workspace/sample.typ echo "Hello, Typst!" >> /workspace/sample.typ ```
- Compile the document to PDF: ```bash typst compile /workspace/sample.typ /workspace/sample.pdf ```
- On your host, check the output: ```bash ls ./volumes/scrolls/sample.pdf ```
Note: Typst files (.typ) in ./volumes/scrolls are synced to Google Drive and Internet Archive via Rclone.
11. Overleaf CE: Collaborative LaTeX Editing
- Ensure Overleaf CE is running: ```bash ./scripts/enable-overleaf.sh ```
- Access Overleaf CE at http://localhost:8090.
- Register as the first user (email:
admin@example.com, this user will be the admin). - Create a new project:
- Click "New Project" > "Blank Project".
- Add a simple LaTeX document: ```latex \documentclass{article} \begin{document} Hello, Overleaf CE! This is a test document. \end{document} ```
- Compile the document to generate a PDF.
- Access files from the
scrollsvolume:- Add a file from the
scrollsvolume (e.g.,test.tex) to your project and compile it.
- Add a file from the
Note: Overleaf CE is resource-heavy. Stop it when not in use: ```bash docker compose -f docker-compose.dev.yml stop overleaf overleaf-mongo overleaf-redis ```
12. Git-Sync: Mirror a Git Repository
The Git-Sync Mirror Agent watches the local repository at ./volumes/repos and syncs changes to GitHub, Forgejo, Radicle, Internet Archive, and optionally Web3.storage.
-
Add a Commit to the Local Repository: ```bash cd volumes/repos echo "Change 1" >> README.md git add . git commit -m "Change 1" ```
-
Manually Push to All Remotes: To trigger a manual sync to all configured remotes, run: ```bash ./scripts/manual-push-git-sync.sh ``` This script pushes the latest changes to all enabled remotes immediately, bypassing the automated sync interval.
-
Monitor Git-Sync Logs: ```bash docker logs git_sync_dev --follow ``` You should see the sync process for each configured remote.
-
Verify Sync:
- GitHub: Check your GitHub repository (`mrhavens/mirror-repo`).
- Forgejo: Check `http://localhost:3000/mrhavens/mirror-repo`.
- Internet Archive: Check `fold-stack-git-mirror` for Git bundles.
- Web3.storage: Enable in `remotes.conf` and check `fold-stack-git-mirror`.
Configuration:
- Edit `config/git-sync/.env` to adjust settings: ``` SYNC_INTERVAL=300 # Sync check interval in seconds PUSH_MODE=push # "push" for git push, "bundle" for git bundle SIGN_COMMITS=false # Set to true to enable commit signing (requires GPG) LOG_LEVEL=INFO # Log verbosity (INFO, ERROR) RETRY_MAX=3 # Max retry attempts for failed syncs RETRY_BACKOFF=5 # Base backoff time in seconds for retries ```
Logs:
- Logs are stored in `./volumes/logs` with filenames like `sync-.log` or `manual-push-.log`.
Diagnostics:
- Run the diagnostic script to troubleshoot issues: ```bash ./scripts/diagnose-git-sync.sh ``` This script checks the container status, configuration files, SSH keys, remote connectivity, logs, and volumes, providing detailed error messages and fixes.
Sync Report:
- Generate a report to see the latest sync activity for each remote: ```bash ./scripts/report-git-sync.sh ``` This report shows the latest commit in the local repository, the last successful sync for each remote (with timestamp and commit/bundle details), and any recent failed sync attempts.
🛠️ Troubleshooting
General Issues
- Container Not Running: Check logs for the specific container: ```bash docker logs <container_name> ``` Restart the stack: ```bash ./scripts/down-dev.sh && ./scripts/up-dev.sh ```
- Port Conflicts: Check for port conflicts: ```bash netstat -tuln | grep ``` Stop conflicting processes or change the port in `docker-compose.dev.yml`.
Rclone Issues
- Sync Not Working: Verify Rclone remotes: ```bash rclone listremotes --config ./config/rclone/rclone.conf ``` Reconfigure if needed: ```bash rclone config ```
- Permission Issues: Fix volume permissions: ```bash chmod -R 775 ./volumes chown -R 1000:1000 ./volumes ```
Overleaf CE Issues
- Startup Errors: Check logs for Overleaf, MongoDB, and Redis: ```bash docker logs overleaf_dev docker logs overleaf_mongo_dev docker logs overleaf_redis_dev ``` Ensure MongoDB and Redis are healthy before Overleaf starts (handled by `depends_on` in `docker-compose.dev.yml`).
Git-Sync Issues
- Sync Fails: Run diagnostics: ```bash ./scripts/diagnose-git-sync.sh ``` Ensure SSH keys are correctly set up and remotes are accessible.
- Radicle Not Syncing: Radicle sync is a placeholder. Implement the `rad` CLI in `entrypoint.sh` if needed.
- Check Sync Status: Generate a sync report: ```bash ./scripts/report-git-sync.sh ```
📚 Additional Resources
- Ghost Documentation: https://ghost.org/docs/
- Forgejo Documentation: https://forgejo.org/docs/
- Radicle Documentation: https://radicle.xyz/guides
- Pandoc Documentation: https://pandoc.org/
- MailHog Documentation: https://github.com/mailhog/MailHog
- Trilium Documentation: https://github.com/zadam/trilium/wiki
- HedgeDoc Documentation: https://docs.hedgedoc.org/
- Nextcloud Documentation: https://docs.nextcloud.com/
- Rclone Documentation: https://rclone.org/docs/
- Typst Documentation: https://typst.app/docs/
- Overleaf CE Documentation: https://github.com/overleaf/overleaf/wiki
🤝 Contributing
Contributions are welcome! To contribute:
- Fork the repository.
- Create a new branch: `git checkout -b feature/your-feature`.
- Make your changes and commit: `git commit -m "Add your feature"`.
- Push to your branch: `git push origin feature/your-feature`.
- Open a pull request.
📅 Last Updated
This README was last updated on May 26, 2025, at 09:55 PM CDT.