Refactor Dockerfile for improved build process; switch to node:20 base image, add build step, and configure volume and port exposure. Update package dependencies for bcrypt and bcryptjs, remove unused files, and enhance README with clearer project structure and setup instructions.

This commit is contained in:
2025-06-18 17:22:40 +02:00
parent dd10624ce4
commit 7e8aa3f498
11 changed files with 591 additions and 678 deletions

3
.dockerignore Normal file
View File

@@ -0,0 +1,3 @@
.next
node_modules
.git

View File

@@ -1,4 +1,4 @@
FROM node:20-alpine FROM node:20
WORKDIR /app WORKDIR /app
@@ -8,4 +8,16 @@ RUN npm install
COPY . . COPY . .
CMD ["npm", "start"] RUN npm run build
VOLUME ["/app/docker"]
EXPOSE 3000
CMD ["npm", "start"]
# Building Instructions
#
# docker build -t markdownblog .
# docker run -p 8080:3000 -v markdownblog-posts:/app/docker markdownblog
# docker container prune

193
README.md
View File

@@ -1,127 +1,102 @@
# Markdown Blog # Markdown Blog
[![Next.js](https://img.shields.io/badge/Next.js-14-black?style=flat-square&logo=next.js&logoColor=white)](https://nextjs.org/)
[![Tailwind CSS](https://img.shields.io/badge/TailwindCSS-3.4-blue?style=flat-square&logo=tailwind-css&logoColor=white)](https://tailwindcss.com/)
[![TypeScript](https://img.shields.io/badge/TypeScript-5-blue?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
[![Electron](https://img.shields.io/badge/Electron-28-47848F?style=flat-square&logo=electron&logoColor=white)](https://www.electronjs.org/)
[![Docker](https://img.shields.io/badge/Docker-24-2496ED?style=flat-square&logo=docker&logoColor=white)](https://www.docker.com/)
[![MIT License](https://img.shields.io/badge/License-MIT-green?style=flat-square)](LICENSE)
A modern, cross-platform blog system built with **Next.js**, **Markdown**, and **Electron**. Write posts in Markdown, manage content visually, and deploy to web or desktop. A modern, cross-platform blog system built with **Next.js**, **Markdown**, and **Electron**. Write posts in Markdown, manage content visually, and deploy to web or desktop.
--- ---
## Features ## 🚀 Features
- ✍️ **Markdown-based posts** Write and organize content in Markdown files - Write and organize posts in Markdown
- **Hot reloading** — See changes instantly as you edit posts - Visual admin dashboard
- 🗂️ **Folder & tag organization** — Structure your content with folders and tags - Responsive UI (Tailwind CSS)
- 🖥️ **Electron desktop app** — Run your blog as a native desktop app - Electron desktop app
- 📱 **Responsive UI** — Mobile-friendly and clean design - Dockerized deployment with persistent storage
- 🛠️ **Admin dashboard** — Manage posts and folders visually - Secure admin password (bcrypt)
- 🐳 **Docker support** — Easy deployment with Docker containers
--- ---
## 🚀 Getting Started ## 🛠️ Technologies
- Next.js 14
- TypeScript
- Tailwind CSS
- Electron
- Docker
---
## 📦 Project Structure
```
markdownblog/
├── posts/ # Markdown blog posts
├── src/ # Next.js app code
├── electron/ # Desktop app code
├── public/ # Static assets
├── Dockerfile # Docker configuration
├── .dockerignore # Docker ignore rules
└── manage_container.sh # Docker management script
```
---
## ⚡ Getting Started
### Prerequisites ### Prerequisites
- [Node.js 18+](https://nodejs.org/) - Node.js 18+
- [npm](https://www.npmjs.com/) - npm
- [Docker](https://www.docker.com/) (for containerized deployment) - Docker (for containerized deployment)
### Installation ---
## 🖥️ Local Development
```bash ```bash
git clone git clone <repo-url>
cd markdownblog cd markdownblog
npm install npm install
npm run dev
``` ```
- Visit [http://localhost:3000](http://localhost:3000) in your browser.
### Development ### Build for Production (Local)
- **Web:** ```bash
`npm run dev` npm run build
- **Desktop (Electron):** npm start
`npm run electron-dev` ```
### Production
- **Web build:**
`npm run build`
- **Desktop build:**
`npm run electron-build`
--- ---
## 🐳 Docker Deployment ## 🐳 Docker Deployment
The project includes Docker support for easy deployment. A `manage_container.sh` script is provided to simplify container management. ### Build the Docker Image
### Docker Setup
1. Make sure Docker is installed and running on your system
2. Update the `MARKDOWN_DIR` path in `manage_container.sh` to point to your local markdown directory
3. Make the script executable:
```bash
chmod +x manage_container.sh
```
### Container Management
The `manage_container.sh` script provides several commands:
```bash ```bash
# Build the Docker image docker build -t markdownblog .
./manage_container.sh build
# Start the container
./manage_container.sh start
# Stop the container
./manage_container.sh stop
# Restart the container
./manage_container.sh restart
# View container logs
./manage_container.sh logs
# Check container status
./manage_container.sh status
# Remove the container
./manage_container.sh remove
``` ```
### Container Features ### Run the Container with Persistent Storage
- **Health Checks**: Automatic health monitoring ```bash
- **Auto-restart**: Container restarts automatically if it crashes docker run -p 8080:3000 -v markdownblog-posts:/app/docker markdownblog
- **Volume Mounting**: Your markdown files are mounted into the container ```
- **Port Mapping**: Access the blog at http://localhost:8080 - The app will be available at [http://localhost:8080](http://localhost:8080)
- All posts are stored persistently in the Docker volume `markdownblog-posts` (mapped to `/app/docker` in the container).
### Container Status #### Using a Host Directory for Posts
The status command shows: ```bash
- Container running state docker run -p 8080:3000 -v /absolute/path/to/posts:/app/docker markdownblog
- Health check status ```
- Access URL
### Troubleshooting
If the container fails to start:
1. Check the logs: `./manage_container.sh logs`
2. Verify Docker is running
3. Ensure port 8080 is available
4. Check the markdown directory path in `manage_container.sh`
--- ---
## 📝 Writing Posts ## 📝 Writing Posts
Add Markdown files to the `posts/` directory. Each post should have frontmatter: - Add Markdown files to the `posts/` directory (or the mounted volume).
- Each post should have frontmatter:
```markdown ```markdown
--- ---
@@ -136,52 +111,10 @@ Your post content here...
--- ---
## 🗂️ Project Structure
```
markdownblog/
├── posts/ # Markdown blog posts
├── src/
│ ├── app/ # Next.js app directory
│ └── lib/ # Utility functions
├── electron/ # Desktop app code
├── public/ # Static assets (favicons, etc.)
├── Dockerfile # Docker configuration
├── .dockerignore # Docker ignore rules
└── manage_container.sh # Docker management script
```
---
## 🔒 Admin Password Security ## 🔒 Admin Password Security
- The admin password is stored securely using the bcrypt hashing algorithm (work factor 12, as recommended by [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html)). - Admin password is securely hashed with bcrypt and stored in `posts/admin.json`.
- The hash is saved in `posts/admin.json`, which is excluded from git via `.gitignore`. - Never commit your `posts/admin.json` file.
- Password changes are written atomically to prevent file corruption.
- If the password file is missing or corrupted, the default login is `admin`/`admin` (with a bcrypt hash generated at runtime).
- Passwords longer than 72 bytes are rejected (bcrypt's safe max).
- You can change the admin password from the admin dashboard after logging in.
**Never share or commit your `posts/admin.json` file!**
---
## 🌐 Favicon
Place your favicon files (e.g., `favicon.ico`, `favicon-32x32.png`, `favicon-16x16.png`) in the `public` directory at the project root.
Next.js will automatically serve these at the root URL (e.g., `/favicon.ico`).
---
## 🛠️ Technologies Used
- [Next.js 14](https://nextjs.org/)
- [TypeScript](https://www.typescriptlang.org/)
- [Tailwind CSS](https://tailwindcss.com/)
- [Electron](https://www.electronjs.org/)
- [Remark](https://remark.js.org/) (Markdown)
- [date-fns](https://date-fns.org/)
- [Docker](https://www.docker.com/)
--- ---

View File

@@ -1,23 +0,0 @@
⠀⠀⠀⠀⡠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⢀⠎⠀⠈⠢⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠔⠁⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⡎⠀⠀⠀⠀⠑⡄⠀⠀⢠⠀⣤⡄⠀⠀⠀⠀⠀⠀⠀⢠⠊⠀⠀⠀⠀⠈⡄⠀⠀⠀⠀⠀⣠⣤⣤⣤⢄⠀⠀
⠀⢰⠁⠀⠀⠀⠀⠀⠈⠢⡀⠈⡄⠀⠀⠉⠒⠄⡀⠀⠀⡠⠃⠀⠀⠀⠀⠀⠀⢃⠀⠀⠀⣴⣯⠟⠛⠻⡝⡗⡀⠀
⠀⡌⠀⠀⠀⠀⠀⠀⠀⠀⠘⢄⡸⠦⠄⠀⠀⠀⠈⠢⡎⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠘⠿⠃⠀⠀⠀⠀⣿⣷
⠀⡇⠀⠀⠀⠀⠀⠀⠀⢴⣊⣁⣀⣀⠤⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣿⡿
⠀⢰⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠇⠀⠀⠀⠀⠀⠀⠀⠀⣞⣿⢟⠁
⠀⠈⢆⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣠⡤⠤⢤⠤⠄⠀⠀⠀⡜⠀⠀⠀⠀⠀⠀⠀⣼⣿⠀⠀⠀⠀
⡀⠀⠈⢆⠀⠈⡟⠁⠈⣿⣿⣿⠁⠀⠀⠀⠀⢸⣿⣿⣷⠀⠀⡇⠀⠀⢀⠜⠀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀
⠻⡐⠒⠚⠓⠠⡅⠀⠀⣿⣿⣿⠀⠀⠀⠀⠀⠸⣿⣿⡏⠀⠀⣜⠀⠀⠉⠁⡼⠀⠀⠀⠀⠀⠀⠉⠁⠀⠀⠀⠀⠀
⠀⠣⣀⡀⠀⠀⢧⠀⠀⠹⣿⠟⠀⣤⣀⠀⠀⠀⠻⠛⠁⠀⠀⠛⡀⠀⣠⠔⠁⠀⠀⠀⠀⠀⠀⣿⡟⠀⠀⠀⠀⠀
⠀⠀⢠⠃⠘⠹⠔⠓⠀⠀⠀⢀⠀⠀⢀⠀⠀⣠⠀⠀⠀⠚⠭⠚⠁⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⢠⣃⣀⣀⣄⠀⠀⠀⠀⠀⠈⠑⠊⠁⠉⠉⠀⠀⠀⠀⠀⢀⡠⠤⠀⠤⠤⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠉⠒⡦⠤⢀⣀⠀⠀⠀⠀⠀⠀⠀⠐⢒⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢀⣎⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢰⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⡸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
Why are you gay?

959
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -29,7 +29,8 @@
"typescript": "^5.3.3", "typescript": "^5.3.3",
"date-fns": "^3.6.0", "date-fns": "^3.6.0",
"@tailwindcss/typography": "^0.5.16", "@tailwindcss/typography": "^0.5.16",
"bcrypt": "^6.0.0" "bcryptjs": "^2.4.3",
"bcrypt": "^5.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/dompurify": "^3.0.5", "@types/dompurify": "^3.0.5",
@@ -38,6 +39,6 @@
"concurrently": "^8.2.2", "concurrently": "^8.2.2",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-config-next": "14.1.0", "eslint-config-next": "14.1.0",
"@types/bcrypt": "^5.0.2" "@types/bcryptjs": "^2.4.6"
} }
} }

View File

@@ -1,14 +0,0 @@
module.exports = {
apps: [
{
name: "markdownblog-dev",
script: "npm",
args: "run dev",
watch: true,
env: {
NODE_ENV: "development",
PORT: 8080
}
}
]
};

View File

@@ -1,6 +0,0 @@
#!/bin/bash
npm install
npm run build
PORT=8080 npm start &
echo "server running on port 8080"
wait

View File

@@ -1,7 +1,7 @@
import { NextResponse } from 'next/server'; import { NextResponse } from 'next/server';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import bcrypt from 'bcrypt'; import bcrypt from 'bcryptjs';
const adminPath = path.join(process.cwd(), 'posts', 'admin.json'); const adminPath = path.join(process.cwd(), 'posts', 'admin.json');
const tempPath = path.join(process.cwd(), 'posts', 'admin.json.tmp'); const tempPath = path.join(process.cwd(), 'posts', 'admin.json.tmp');

View File

@@ -68,17 +68,13 @@ export default function RootLayout({
</div> </div>
</header> </header>
{children} {children}
<footer className="bg-gray-100 p-4"> <footer className="bg-gray-100 p-2">
<div className="container mx-auto flex flex-col md:flex-row justify-between items-center"> <div className="container mx-auto flex flex-col md:flex-row justify-between items-center">
<p> <div className="text-center">
<span> <span className="text-gray-500" style={{ fontSize: '12px' }}>
&copy; {new Date().getFullYear()} {blogOwner} &copy; {new Date().getFullYear()} {blogOwner}
</span> </span>
<span className="text-gray-500 text-right" style={{ fontSize: '12px' }}> </div>
Du bist auf dem Development-Server.
Er ist nicht stabil und kann sich jederzeit ändern.
</span>
</p>
</div> </div>
</footer> </footer>
</body> </body>

View File

@@ -1,32 +0,0 @@
#!/bin/bash
# Check the command line argument
case "$1" in
autodeploy)
echo "Starting PM2 with auto-deployment..."
pm2 start pm2.config.js
;;
prod)
echo "Starting PM2 with production build..."
NODE_ENV=production pm2 start pm2.config.js
;;
stop)
echo "Stopping PM2 process..."
pm2 stop all
;;
restart)
echo "Restarting PM2 process..."
pm2 restart all
;;
status)
echo "Showing PM2 process status..."
pm2 status
;;
logs)
echo "Showing PM2 logs..."
pm2 logs
;;
*)
echo "Usage: ./start_pm2 {autodeploy|prod|stop|restart|status|logs}"
;;
esac