Files
mdhost/README.md
T
2026-05-01 18:46:12 +02:00

184 lines
4.9 KiB
Markdown

# mdhost
A simple, single-binary Go web application for hosting and sharing markdown files.
## Features
- **Create, view, edit, and delete** markdown files via web interface
- **Stable file IDs** - unique identifiers don't change when files are edited
- **Syntax highlighting** for code blocks (bash, go, python, etc.)
- **Optional authentication** - anonymous users can create files, registered users can claim them
- **Access control** - edit/delete only your own files, public/private visibility toggle
- **Responsive UI** - mobile-friendly CSS layout
- **Persistent storage** - all data (users, sessions, file metadata) survives server restarts
## Quick Start
### Build
```bash
go build -o mdhost .
```
### Run
```bash
./mdhost
```
The server will start on `http://localhost:8080`.
### Usage
1. **List files**: Visit `/` to see all public markdown files
2. **Add a file**: Click "add" in the nav bar, enter title and content, submit
3. **View a file**: Click any file name in the list
4. **Edit a file**: Click the `[edit]` link next to a file, or visit `/edit?id=<file-id>`
5. **Delete a file**: Click the `[delete]` button (only visible for files you own)
## Authentication
### Anonymous Use
You can create and edit files without an account. Files created anonymously are associated with your browser session (via cookie).
### Register
Click "register" in the nav bar to create an account. After registering:
- Your existing anonymous files are automatically claimed and linked to your account
- You can edit/delete all files created in your session
### Login/Logout
- Click "login" to authenticate with existing credentials
- Click "logout" to end your session
### Claiming Files
Files created while anonymous are automatically claimed when you register or login from the same browser.
## File Visibility
- **Public files**: Appear in the public list, visible to all users
- **Private files**: Only accessible via direct URL, don't appear in public list
- Toggle visibility using the "Listed in public list" checkbox when editing
## Configuration
The following variables can be modified at the top of `main.go`:
```go
var (
postsDir = "./posts" // Directory for markdown files
dataDir = "./data" // Directory for persistent data (data.json)
port = ":8080" // Server port
)
var ListFormat = "ul" // List rendering: "ul" (bullet), "ol" (numbered), "plain"
```
## Data Storage
- **Markdown files**: Stored in `./posts/` directory
- **Metadata**: Stored in `./data/data.json` (users, sessions, file metadata)
- All data persists across server restarts
## ID Generation
File IDs are generated as the first 12 characters of a SHA1 hash:
```
SHA1(filename + creation_timestamp)[:12]
```
The creation timestamp is stored in the file's `CreatedAt` field and persists across restarts, ensuring stable IDs.
## Security
- Passwords are hashed using bcrypt
- Sessions use HTTP-only cookies with 1-year expiry
- File ownership is enforced (users can only edit/delete their own files)
- Private files are hidden from public listings but accessible via direct URL
## API Endpoints
| Method | Path | Description |
|--------|------|-------------|
| GET | `/` | List all public files |
| GET | `/home` | Homepage with README |
| GET | `/view/{id}` | View rendered markdown |
| GET | `/add` | Form to create new file |
| POST | `/create` | Create new file |
| GET | `/edit` | Select file to edit |
| GET | `/edit?id={id}` | Edit specific file |
| POST | `/update` | Save file edits |
| POST | `/delete` | Delete a file |
| GET/POST | `/register` | Create user account |
| GET/POST | `/login` | Authenticate |
| GET | `/logout` | Clear session |
| GET | `/claim` | Claim anonymous files (auto-handled in register) |
## Docker
### Build the Image
```bash
docker build -t mdhost .
```
### Run with Docker
The `data` and `posts` directories are designed to be bind-mounted from the host filesystem for persistence:
```bash
# Create host directories for persistent data
mkdir -p ~/mdhost-data ~/mdhost-posts
# Run the container with bind mounts
docker run -d \
--name mdhost \
-p 8080:8080 \
-v ~/mdhost-posts:/posts \
-v ~/mdhost-data:/data \
mdhost
```
The application will be available at `http://localhost:8080`.
- **`/posts`** - Markdown files are stored here (bind-mounted from host)
- **`/data`** - Metadata (users, sessions, file metadata) is stored here as `data.json` (bind-mounted from host)
### Docker Compose
Create a `docker-compose.yml`:
```yaml
version: '3.8'
services:
mdhost:
build: .
ports:
- "8080:8080"
volumes:
- ./posts:/posts
- ./data:/data
restart: unless-stopped
```
Then run:
```bash
docker compose up -d
```
## Dependencies
- Go 1.26+
- `github.com/yuin/goldmark` v1.8.2
- `github.com/yuin/goldmark-highlighting` v0.0.0-20220208100518-594be1970594
- `github.com/alecthomas/chroma/v2` v2.24.1
- `golang.org/x/crypto/bcrypt` v0.50.0
## License
MIT License