From ad70323a88a4f44106bd04c3e34e389c71ca8bbe Mon Sep 17 00:00:00 2001 From: Philip Lehmann Date: Mon, 9 Jun 2025 20:28:53 +0200 Subject: [PATCH 1/3] Update README files for MailCatcher, MailDev, and Puppeteer with enhanced features, usage instructions, and configuration options --- apps/mailcatcher/README.md | 168 ++++++++++++++++- apps/maildev/README.md | 302 +++++++++++++++++++++++++++++- apps/puppeteer/README.md | 373 +++++++++++++++++++++++++++++++------ 3 files changed, 778 insertions(+), 65 deletions(-) diff --git a/apps/mailcatcher/README.md b/apps/mailcatcher/README.md index d2cfaf8f..1462c5b3 100644 --- a/apps/mailcatcher/README.md +++ b/apps/mailcatcher/README.md @@ -1,12 +1,170 @@ # MailCatcher -## Run Image +MailCatcher is a simple SMTP server that catches any email sent to it and displays it in a web interface. It's perfect for testing email functionality in development environments without actually sending emails. -``` +## Features + +- ๐Ÿ“ง Catches all outbound emails in development +- ๐ŸŒ Web interface to view caught emails +- ๐Ÿ” Search and filter emails +- ๐Ÿ“ฑ Responsive design for mobile viewing +- ๐Ÿš€ Lightweight and fast +- ๐Ÿณ Ready-to-use Docker container + +## Quick Start + +### Run with Docker + +```bash docker run -p 1080:1080 -p 1025:1025 --name mailcatcher-server philiplehmann/mailcatcher:latest ``` -## Ports +### Run with Docker Compose + +```yaml +version: '3.8' +services: + mailcatcher: + image: philiplehmann/mailcatcher:latest + ports: + - "1080:1080" # Web interface + - "1025:1025" # SMTP server + container_name: mailcatcher-server +``` + +## Configuration + +### Ports + +| Port | Service | Description | +|------|---------|-------------| +| 1025 | SMTP | Mail server for receiving emails | +| 1080 | HTTP | Web interface for viewing emails | + +### Environment Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `SMTP_PORT` | 1025 | SMTP server port | +| `HTTP_PORT` | 1080 | Web interface port | + +## Usage + +### Configure Your Application + +Point your application's SMTP settings to: +- **Host:** `localhost` (or your Docker container IP) +- **Port:** `1025` +- **Authentication:** None required + +### View Caught Emails + +Open your browser and navigate to: +```text +http://localhost:1080 +``` + +### Example Configuration + +#### Node.js (Nodemailer) +```javascript +const nodemailer = require('nodemailer'); + +const transporter = nodemailer.createTransport({ + host: 'localhost', + port: 1025, + secure: false, // No SSL/TLS + auth: null // No authentication +}); +``` + +#### Python (smtplib) +```python +import smtplib +from email.mime.text import MIMEText + +server = smtplib.SMTP('localhost', 1025) +# No authentication needed +``` + +#### PHP +```php +ini_set('SMTP', 'localhost'); +ini_set('smtp_port', 1025); +// Use mail() function as normal +``` + +## Development + +### Building the Image + +#### Using Nx (Recommended) +```bash +# Build the Docker image using Nx +nx docker-push mailcatcher + +# Or from the workspace root +npx nx docker-push mailcatcher +``` + +#### Using Docker directly +```bash +docker build -t mailcatcher -f apps/mailcatcher/Dockerfile . +``` + +### Running in Development Mode + +#### Using Nx +```bash +# Run the container using Nx +nx docker-run mailcatcher + +# Test the Docker build +nx docker-test mailcatcher + +# Run tests +nx test mailcatcher +``` + +#### Using Docker directly +```bash +# Run the container +docker run -p 1080:1080 -p 1025:1025 mailcatcher +``` + +## Troubleshooting + +### Common Issues + +**Port already in use:** +```bash +# Check what's using the port +lsof -i :1080 +lsof -i :1025 + +# Stop the container and try again +docker stop mailcatcher-server +docker rm mailcatcher-server +``` + +**Can't access web interface:** +- Ensure port 1080 is not blocked by firewall +- Check if Docker container is running: `docker ps` +- Verify port mapping: `docker port mailcatcher-server` + +**Emails not being caught:** +- Verify your application is configured to use `localhost:1025` +- Check container logs: `docker logs mailcatcher-server` +- Ensure no authentication is configured in your email client + +## Contributing + +1. Fork the repository +2. Create a feature branch +3. Make your changes +4. Test thoroughly +5. Submit a pull request + +## License -- SMTP 1025 -- HTTP 1080 +This project is licensed under the MIT License. diff --git a/apps/maildev/README.md b/apps/maildev/README.md index e9292f4c..40f3da36 100644 --- a/apps/maildev/README.md +++ b/apps/maildev/README.md @@ -1,12 +1,302 @@ -# maildev +# MailDev -## Run Image +MailDev is a simple way to test your project's generated emails during development with an easy-to-use web interface that runs on your machine built on top of Node.js. It's perfect for testing email functionality in development environments without actually sending emails. -``` +## Features + +- ๐Ÿ“ง Catches all outbound emails in development +- ๐ŸŒ Clean, intuitive web interface +- ๐Ÿ“ฑ Responsive design for mobile viewing +- ๐Ÿ” Search and filter emails by sender, subject, or content +- ๐Ÿ“Ž View HTML and plain text versions of emails +- ๐Ÿ“‹ Download email attachments +- ๐Ÿ”„ Auto-refresh and real-time updates +- ๐Ÿ—‘๏ธ Delete individual emails or clear all +- ๐Ÿš€ Lightweight and fast +- ๐Ÿณ Ready-to-use Docker container + +## Quick Start + +### Run with Docker + +```bash docker run -p 1080:1080 -p 1025:1025 --name maildev-server philiplehmann/maildev:latest ``` -## Ports +### Run with Docker Compose + +```yaml +version: '3.8' +services: + maildev: + image: philiplehmann/maildev:latest + ports: + - "1080:1080" # Web interface + - "1025:1025" # SMTP server + container_name: maildev-server + environment: + - MAILDEV_WEB_PORT=1080 + - MAILDEV_SMTP_PORT=1025 +``` + +### Run with Nx + +```bash +# Build the Docker image +nx docker-push maildev + +# Run the container +nx docker-run maildev + +# Test the Docker build +nx docker-test maildev +``` + +## Configuration + +### Ports + +| Port | Service | Description | +|------|---------|-------------| +| 1025 | SMTP | Mail server for receiving emails | +| 1080 | HTTP | Web interface for viewing emails | + +### Environment Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `MAILDEV_WEB_PORT` | 1080 | Web interface port | +| `MAILDEV_SMTP_PORT` | 1025 | SMTP server port | +| `MAILDEV_WEB_IP` | 0.0.0.0 | IP address to bind web interface | +| `MAILDEV_SMTP_IP` | 0.0.0.0 | IP address to bind SMTP server | +| `MAILDEV_BASE_PATHNAME` | / | Base path for web interface | +| `MAILDEV_DISABLE_DNS` | false | Disable DNS lookups | + +## Usage + +### Configure Your Application + +Point your application's SMTP settings to: +- **Host:** `localhost` (or your Docker container IP) +- **Port:** `1025` +- **Authentication:** None required +- **Encryption:** None (plain text) + +### View Caught Emails + +Open your browser and navigate to: +```text +http://localhost:1080 +``` + +### Example Configuration + +#### Node.js (Nodemailer) +```javascript +const nodemailer = require('nodemailer'); + +const transporter = nodemailer.createTransport({ + host: 'localhost', + port: 1025, + secure: false, // No SSL/TLS + auth: null, // No authentication + tls: { + rejectUnauthorized: false + } +}); + +// Send test email +transporter.sendMail({ + from: 'sender@example.com', + to: 'recipient@example.com', + subject: 'Test Email', + text: 'This is a test email', + html: '

This is a test email

' +}); +``` + +#### Python (smtplib) +```python +import smtplib +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart + +# Create message +msg = MIMEMultipart('alternative') +msg['Subject'] = 'Test Email' +msg['From'] = 'sender@example.com' +msg['To'] = 'recipient@example.com' + +# Add content +text = 'This is a test email' +html = '

This is a test email

' +msg.attach(MIMEText(text, 'plain')) +msg.attach(MIMEText(html, 'html')) + +# Send email +server = smtplib.SMTP('localhost', 1025) +server.send_message(msg) +server.quit() +``` + +#### PHP +```php + +``` + +#### Laravel (.env configuration) +```env +MAIL_MAILER=smtp +MAIL_HOST=localhost +MAIL_PORT=1025 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS=test@example.com +MAIL_FROM_NAME="${APP_NAME}" +``` + +## Web Interface Features + +### Email List View +- View all caught emails in chronological order +- Filter by sender, recipient, or subject +- Quick preview of email content +- Attachment indicators + +### Email Detail View +- Toggle between HTML and plain text views +- Download individual attachments +- View email headers +- Copy email content + +### Toolbar Actions +- ๐Ÿ”„ Refresh email list +- ๐Ÿ—‘๏ธ Delete individual emails +- ๐Ÿ—‘๏ธ Clear all emails +- ๐Ÿ” Search functionality + +## Development + +### Building the Image + +#### Using Nx (Recommended) +```bash +# Build and push the Docker image using Nx +nx docker-push maildev + +# Or from the workspace root +npx nx docker-push maildev +``` + +#### Using Docker directly +```bash +docker build -t maildev -f apps/maildev/Dockerfile . +``` + +### Running in Development Mode + +#### Using Nx +```bash +# Run the container using Nx +nx docker-run maildev + +# Test the Docker build +nx docker-test maildev + +# Run tests +nx test maildev + +# Lint the code +nx lint maildev +``` + +#### Using Docker directly +```bash +# With custom configuration +docker run -p 1080:1080 -p 1025:1025 \ + -e MAILDEV_WEB_PORT=1080 \ + -e MAILDEV_SMTP_PORT=1025 \ + --name maildev-dev \ + philiplehmann/maildev:latest +``` + +## Troubleshooting + +### Common Issues + +**Port already in use:** +```bash +# Check what's using the port +lsof -i :1080 +lsof -i :1025 + +# Stop the container and try again +docker stop maildev-server +docker rm maildev-server +``` + +**Can't access web interface:** +- Ensure port 1080 is not blocked by firewall +- Check if Docker container is running: `docker ps` +- Verify port mapping: `docker port maildev-server` +- Check container logs: `docker logs maildev-server` + +**Emails not being caught:** +- Verify your application is configured to use `localhost:1025` +- Ensure no authentication is configured in your email client +- Check that TLS/SSL is disabled +- Verify SMTP settings in your application + +**Web interface shows no emails:** +- Check that emails are actually being sent by your application +- Verify the container is receiving SMTP connections +- Clear browser cache and refresh the page + +### Logging + +To see MailDev logs: +```bash +# View container logs +docker logs maildev-server + +# Follow logs in real-time +docker logs -f maildev-server +``` + +## Comparison with MailCatcher + +| Feature | MailDev | MailCatcher | +|---------|---------|-------------| +| Technology | Node.js | Ruby | +| Web Interface | Modern, responsive | Simple, functional | +| Real-time Updates | โœ… | โŒ | +| Attachment Support | โœ… | โœ… | +| Search Functionality | โœ… | โŒ | +| Mobile Responsive | โœ… | โŒ | +| Memory Usage | Higher | Lower | + +## Contributing + +1. Fork the repository +2. Create a feature branch +3. Make your changes +4. Test thoroughly with `nx test maildev` +5. Submit a pull request + +## License -- SMTP 1025 -- HTTP 1080 +This project is licensed under the MIT License. diff --git a/apps/puppeteer/README.md b/apps/puppeteer/README.md index d04be5c0..464acf0c 100644 --- a/apps/puppeteer/README.md +++ b/apps/puppeteer/README.md @@ -1,114 +1,379 @@ -# puppeteer node wrapper +# Puppeteer Node.js Wrapper -## Run Image +A containerized Node.js service that provides a REST API for converting web pages and HTML content to PDF documents and images using Puppeteer and headless Chrome. -``` -docker run -p 3000:3000 --name puppeteer philiplehmann/puppeteer:latest -``` +## Features + +- ๐ŸŒ **URL to PDF** - Convert any web page to PDF +- ๐Ÿ“„ **HTML to PDF** - Convert raw HTML content to PDF +- ๐Ÿ–ผ๏ธ **URL to Image** - Generate screenshots of web pages +- ๐ŸŽจ **HTML to Image** - Convert HTML content to images +- โš™๏ธ **Configurable** - Supports all Puppeteer PDF options +- ๐Ÿš€ **Fast & Lightweight** - Optimized for performance +- ๐Ÿณ **Docker Ready** - Easy deployment with Docker +- ๐Ÿ”ง **REST API** - Simple HTTP interface -## Convert url to pdf +## Quick Start +### Run with Docker + +```bash +docker run -p 3000:3000 --name puppeteer-server philiplehmann/puppeteer:latest ``` -curl -X POST \ - -H 'content-type: application/json' \ - --data '{"url":"https://google.com"}' \ - 'http://localhost:3000/' + +### Run with Docker Compose + +```yaml +version: '3.8' +services: + puppeteer: + image: philiplehmann/puppeteer:latest + ports: + - "3000:3000" + container_name: puppeteer-server + environment: + - NODE_ENV=production ``` -or +### Run with Nx + +```bash +# Build the Docker image +nx build puppeteer +# Run the container +nx docker-run puppeteer + +# Serve locally for development +nx serve puppeteer ``` + +## API Endpoints + +### PDF Generation + +#### Convert URL to PDF + +```bash curl -X POST \ - -H 'content-type: application/json' \ + -H 'Content-Type: application/json' \ --data '{"url":"https://google.com"}' \ 'http://localhost:3000/pdf' ``` -## Convert html to pdf +#### Convert HTML to PDF -``` +```bash curl -X POST \ - -H 'content-type: application/json' \ - --data '{"html":"

title

"}' \ - 'http://localhost:3000/' + -H 'Content-Type: application/json' \ + --data '{"html":"

Hello World

This is a test document.

"}' \ + 'http://localhost:3000/pdf' ``` -or +#### Advanced PDF Options -``` +```bash curl -X POST \ - -H 'content-type: application/json' \ - --data '{"html":"

title

"}' \ + -H 'Content-Type: application/json' \ + --data '{ + "url": "https://example.com", + "format": "A4", + "margin": { + "top": "1in", + "right": "1in", + "bottom": "1in", + "left": "1in" + }, + "printBackground": true, + "landscape": false + }' \ 'http://localhost:3000/pdf' ``` -## Convert url to image +### Image Generation -``` +#### Convert URL to Image + +```bash curl -X POST \ - -H 'content-type: application/json' \ + -H 'Content-Type: application/json' \ --data '{"url":"https://google.com"}' \ 'http://localhost:3000/image' ``` +#### Convert HTML to Image -## Convert html to image - +```bash +curl -X POST \ + -H 'Content-Type: application/json' \ + --data '{"html":"

Hello World

"}' \ + 'http://localhost:3000/image' ``` + +#### Advanced Image Options + +```bash curl -X POST \ - -H 'content-type: application/json' \ - --data '{"html":"

title

"}' \ + -H 'Content-Type: application/json' \ + --data '{ + "url": "https://example.com", + "viewport": { + "width": 1920, + "height": 1080 + }, + "fullPage": true, + "type": "png" + }' \ 'http://localhost:3000/image' ``` -## Props -all the puppeteer props to create a pdf are supported except the path -https://devdocs.io/puppeteer/index#pagepdfoptions +## Configuration Options + +### PDF Options + +All Puppeteer PDF options are supported (except `path`). See the [Puppeteer documentation](https://devdocs.io/puppeteer/index#pagepdfoptions) for complete details. + +| Option | Type | Description | Default | +|--------|------|-------------|---------| +| `format` | string | Paper format (A4, Letter, Legal, etc.) | A4 | +| `landscape` | boolean | Paper orientation | false | +| `printBackground` | boolean | Print background graphics | false | +| `margin` | object | Page margins | {} | +| `scale` | number | Scale of the webpage rendering | 1 | +| `displayHeaderFooter` | boolean | Display header and footer | false | +| `headerTemplate` | string | HTML template for header | | +| `footerTemplate` | string | HTML template for footer | | + +### Image Options + +| Option | Type | Description | Default | +|--------|------|-------------|---------| +| `type` | string | Image format (png, jpeg, webp) | png | +| `quality` | number | Image quality (0-100, jpeg only) | 80 | +| `fullPage` | boolean | Capture full scrollable page | false | +| `viewport` | object | Page viewport size | {width: 800, height: 600} | +| `clip` | object | Capture specific area | | + +### Request Examples + +#### JavaScript/Node.js +```javascript +const response = await fetch('http://localhost:3000/pdf', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + url: 'https://example.com', + format: 'A4', + margin: { top: '1cm', bottom: '1cm' } + }) +}); + +const pdfBuffer = await response.arrayBuffer(); +``` + +#### Python +```python +import requests + +response = requests.post('http://localhost:3000/pdf', json={ + 'url': 'https://example.com', + 'format': 'A4', + 'printBackground': True +}) + +with open('output.pdf', 'wb') as f: + f.write(response.content) +``` +#### PHP +```php + 'https://example.com', + 'format' => 'A4', + 'landscape' => false +]; -## Emulation -to allow to run in emulation, some settings are needed to not run into errors: +$response = file_get_contents('http://localhost:3000/pdf', false, stream_context_create([ + 'http' => [ + 'method' => 'POST', + 'header' => 'Content-Type: application/json', + 'content' => json_encode($data) + ] +])); -### Apple Silicon run amd64 version -using docker desktop it only supports 32-bit emulation and resolves in error: +file_put_contents('output.pdf', $response); +?> ``` + +## Architecture Support + +This service supports both AMD64 and ARM64 architectures. + +### Apple Silicon (M1/M2/M3) Compatibility + +For Apple Silicon Macs, you may encounter issues with the default Docker setup. If you see errors like: + +```text Failed to launch the browser process! The hardware on this system lacks support for the sse3 instruction set. -The upstream chromium project no longer supports this configuration. -For more information, please read and possibly provide input to their -bug tracking system at http://crbug.com/1123353 ``` -to get 64-bit support i could start it with colima: -``` +**Solution:** Use Colima for better x86_64 emulation support: + +```bash +# Install Colima brew install colima + +# Start with x86_64 architecture colima start --arch x86_64 --cpu 4 --memory 16 + +# Now run your Docker commands +docker run -p 3000:3000 philiplehmann/puppeteer:latest ``` -## Ports +## Development + +### Local Development Setup + +#### Prerequisites +- Node.js 18+ +- Chrome/Chromium browser +- Nx CLI -- HTTP 3000 +#### Start Development Server -## test locally +```bash +# Set Chrome executable path (macOS) +export PUPPETEER_EXECUTABLE_PATH="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" -start puppeteer server, will be on port 3000 +# Start the development server +yarn nx serve puppeteer ``` -PUPPETEER_EXECUTABLE_PATH="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" bun nx serve puppeteer + +The server will be available at `http://localhost:3000` + +### Testing + +#### Run All Tests Locally +```bash +# Set environment for local testing +export TEST_SERVER_RUNNER=local + +# Run end-to-end tests with Playwright +yarn nx e2e-local puppeteer + +# Run unit tests with Vitest +yarn nx vitest-local puppeteer + +# Run both test suites +yarn nx test-local puppeteer ``` -run *-local tests +#### Update Test Snapshots +```bash +yarn nx e2e puppeteer --update-snapshots ``` -# run playwright ui tests -bun nx local-e2e puppeteer -# run bun-test -bun nx local-test puppeteer +### Building and Deployment + +#### Using Nx (Recommended) +```bash +# Build Docker image +nx build puppeteer -# run both, e2e and bun-test -bun nx run-many --projects puppeteer --target local-test local-e2e +# Test the build +nx docker-test puppeteer + +# Run the container +nx docker-run puppeteer + +# Push to registry +nx docker-push puppeteer ``` -## update snapshots +#### Using Docker Directly +```bash +# Build image +docker build -t puppeteer -f apps/puppeteer/Dockerfile . + +# Run container +docker run -p 3000:3000 puppeteer ``` -bun nx local-e2e puppeteer --update-snapshots + +## Ports + +| Port | Service | Description | +|------|---------|-------------| +| 3000 | HTTP | REST API server | + +## Environment Variables + + +| Variable | Default | Description | +|----------|---------|-------------| +| `PORT` | 3000 | Server port | +| `NODE_ENV` | development | Node.js environment | +| `PUPPETEER_EXECUTABLE_PATH` | | Custom Chrome executable path | +| `PUPPETEER_SKIP_CHROMIUM_DOWNLOAD` | | Skip Chromium download | + +## Troubleshooting + +### Common Issues + +**Chrome fails to launch:** +- Ensure sufficient memory is allocated to Docker +- Try running with `--no-sandbox` flag in production +- Check Chrome executable permissions + +**Memory issues:** +- Increase Docker memory limits +- Use `--max-old-space-size` Node.js flag +- Consider adding swap space + +**Timeout errors:** +- Increase timeout values in requests +- Check network connectivity +- Ensure target URLs are accessible + +**Font rendering issues:** +- Install additional fonts in the container +- Set proper locale settings +- Use web-safe fonts + +### Debug Mode + +Enable debug logging by setting: +```bash +export DEBUG="puppeteer:*" +yarn nx serve puppeteer ``` + +## Performance Tips + +1. **Reuse Browser Instance** - The service reuses Chrome instances for better performance +2. **Memory Management** - Pages are automatically closed after processing +3. **Caching** - Consider implementing response caching for frequently requested content +4. **Resource Limiting** - Set appropriate memory and CPU limits in production + +## Security Considerations + +- Run in a sandboxed environment +- Validate input URLs and HTML content +- Consider rate limiting for public deployments +- Use network policies to restrict outbound connections +- Keep Chrome/Puppeteer updated for security patches + +## Contributing + +1. Fork the repository +2. Create a feature branch +3. Make your changes +4. Test thoroughly with `nx test puppeteer` +5. Submit a pull request + +## License + +This project is licensed under the MIT License. From f5435c8421e87ade5fe0f1233fd2b9bd3e82e15d Mon Sep 17 00:00:00 2001 From: Philip Lehmann Date: Sat, 21 Feb 2026 09:31:43 +0100 Subject: [PATCH 2/3] Update README docs for mailcatcher, maildev, and puppeteer apps Clarify Docker Compose usage, environment variable handling, and sandboxing guidance. Fix documentation links and feature table. --- apps/mailcatcher/README.md | 5 ++--- apps/maildev/README.md | 5 ++--- apps/puppeteer/README.md | 6 +++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/apps/mailcatcher/README.md b/apps/mailcatcher/README.md index 1462c5b3..5b216a95 100644 --- a/apps/mailcatcher/README.md +++ b/apps/mailcatcher/README.md @@ -22,7 +22,6 @@ docker run -p 1080:1080 -p 1025:1025 --name mailcatcher-server philiplehmann/mai ### Run with Docker Compose ```yaml -version: '3.8' services: mailcatcher: image: philiplehmann/mailcatcher:latest @@ -45,8 +44,8 @@ services: | Variable | Default | Description | |----------|---------|-------------| -| `SMTP_PORT` | 1025 | SMTP server port | -| `HTTP_PORT` | 1080 | Web interface port | +| `SMTP_PORT` | 1025 | SMTP server port (not used by the current Dockerfile `CMD` in `apps/mailcatcher/Dockerfile`; changes require rebuilding the image or modifying `CMD` to read `SMTP_PORT`) | +| `HTTP_PORT` | 1080 | Web interface port (not used by the current Dockerfile `CMD` in `apps/mailcatcher/Dockerfile`; changes require rebuilding the image or modifying `CMD` to read `HTTP_PORT`) | ## Usage diff --git a/apps/maildev/README.md b/apps/maildev/README.md index 40f3da36..46308cc0 100644 --- a/apps/maildev/README.md +++ b/apps/maildev/README.md @@ -1,6 +1,6 @@ # MailDev -MailDev is a simple way to test your project's generated emails during development with an easy-to-use web interface that runs on your machine built on top of Node.js. It's perfect for testing email functionality in development environments without actually sending emails. +MailDev, built on top of Node.js, is a simple way to test your project's generated emails during development with an easy-to-use web interface that runs on your machine. It's perfect for testing email functionality in development environments without actually sending emails. ## Features @@ -26,7 +26,6 @@ docker run -p 1080:1080 -p 1025:1025 --name maildev-server philiplehmann/maildev ### Run with Docker Compose ```yaml -version: '3.8' services: maildev: image: philiplehmann/maildev:latest @@ -286,7 +285,7 @@ docker logs -f maildev-server | Real-time Updates | โœ… | โŒ | | Attachment Support | โœ… | โœ… | | Search Functionality | โœ… | โŒ | -| Mobile Responsive | โœ… | โŒ | +| Mobile Responsive | โœ… | โœ… | | Memory Usage | Higher | Lower | ## Contributing diff --git a/apps/puppeteer/README.md b/apps/puppeteer/README.md index 464acf0c..7eabb56a 100644 --- a/apps/puppeteer/README.md +++ b/apps/puppeteer/README.md @@ -24,7 +24,6 @@ docker run -p 3000:3000 --name puppeteer-server philiplehmann/puppeteer:latest ### Run with Docker Compose ```yaml -version: '3.8' services: puppeteer: image: philiplehmann/puppeteer:latest @@ -131,7 +130,7 @@ curl -X POST \ ### PDF Options -All Puppeteer PDF options are supported (except `path`). See the [Puppeteer documentation](https://devdocs.io/puppeteer/index#pagepdfoptions) for complete details. +All Puppeteer PDF options are supported (except `path`). See the [Puppeteer documentation](https://pptr.dev/api/puppeteer.pdfoptions) for complete details. | Option | Type | Description | Default | |--------|------|-------------|---------| @@ -325,8 +324,9 @@ docker run -p 3000:3000 puppeteer **Chrome fails to launch:** - Ensure sufficient memory is allocated to Docker -- Try running with `--no-sandbox` flag in production - Check Chrome executable permissions +- If you must use `--no-sandbox`, note it disables Chrome's renderer process isolation and increases attack surface. Only use it when Docker-level isolation is enforced (user namespaces, seccomp, caps) and all input HTML/URLs are validated or sanitized. Avoid `--no-sandbox` for untrusted-input or public-facing deployments. +- Safer alternatives: increase Docker memory, run with proper sandboxing enabled, or run Chrome in a dedicated minimal-privilege container. **Memory issues:** - Increase Docker memory limits From 8e2bc9a1c8ab7f9a2676150e843ab0cc0962703c Mon Sep 17 00:00:00 2001 From: Philip Lehmann Date: Tue, 24 Feb 2026 21:40:52 +0100 Subject: [PATCH 3/3] Update and enhance README docs for all app services - Rewrite and expand README.md files for nx-cache-server, pdftk, poppler, puppeteer, tesseract, and unoserver apps - Add feature lists, Docker/Docker Compose quick start guides, and detailed API usage examples - Standardize documentation structure and improve clarity - Add online test status badges for service health monitoring --- apps/nx-cache-server/README.md | 41 +++++++++-- apps/pdftk/README.md | 126 +++++++++++++++++++++------------ apps/poppler/README.md | 48 +++++++++++-- apps/puppeteer/README.md | 4 ++ apps/tesseract/README.md | 107 ++++++++++++++++++++++++++-- apps/unoserver/README.md | 119 +++++++++++++++++++++++-------- 6 files changed, 353 insertions(+), 92 deletions(-) diff --git a/apps/nx-cache-server/README.md b/apps/nx-cache-server/README.md index ec12b8ed..3c7902d7 100644 --- a/apps/nx-cache-server/README.md +++ b/apps/nx-cache-server/README.md @@ -1,12 +1,45 @@ -# nx-cache-server node wrapper +# Nx Cache Server Node.js Wrapper -## Run Image +A containerized Node.js service that provides a remote cache endpoint for Nx builds, enabling faster CI and developer workflows by sharing cached artifacts across machines. -``` +## Features + +- โšก **Remote Caching** - Share Nx build cache across teams and CI +- ๐Ÿณ **Docker Ready** - Easy deployment with Docker +- ๐Ÿ”ง **Simple Setup** - Minimal configuration required +- ๐Ÿ“ฆ **Nx Compatible** - Designed for Nx remote cache workflows +- ๐ŸŒ **HTTP Endpoint** - Works over standard HTTP + +## Quick Start + +### Run with Docker + +```bash docker run --rm -p 3000:3000 --name nx-cache-server philiplehmann/nx-cache-server:latest ``` +### Run with Docker Compose + +```yaml +services: + nx-cache-server: + image: philiplehmann/nx-cache-server:latest + ports: + - "3000:3000" + container_name: nx-cache-server +``` + +## Usage + +1. Start the server (see Quick Start). +2. Configure Nx to use the remote cache server URL. + +Refer to the official documentation for setup details and client configuration: + +- https://philiplehmann.github.io/nx-cache-server/ ## Ports -- HTTP 3000 +| Port | Service | Description | +|------|---------|-------------| +| 3000 | HTTP | Remote cache server | diff --git a/apps/pdftk/README.md b/apps/pdftk/README.md index d0ec362a..5eb884d2 100644 --- a/apps/pdftk/README.md +++ b/apps/pdftk/README.md @@ -1,110 +1,146 @@ -# pdftk node wrapper +# PDFTK Node.js Wrapper -## Run Image +A containerized Node.js service that provides a REST API for common PDF operations using PDFTK. -``` +## Features + +- ๐Ÿ—œ๏ธ **Compress/Uncompress** - Optimize PDF file size +- ๐Ÿ” **Encrypt/Decrypt** - Secure PDFs with passwords and permissions +- ๐Ÿงพ **Form Data** - Extract or fill PDF form fields +- ๐Ÿณ **Docker Ready** - Easy deployment with Docker +- ๐Ÿ”ง **REST API** - Simple HTTP interface + +## Quick Start + +### Run with Docker + +```bash docker run -p 3000:3000 --rm --name pdftk philiplehmann/pdftk:latest ``` -## compress pdf file +### Run with Docker Compose +```yaml +services: + pdftk: + image: philiplehmann/pdftk:latest + ports: + - "3000:3000" + container_name: pdftk ``` + +## API Endpoints + +### Compress PDF + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@path/to/my/uncompressed.pdf" \ 'http://localhost:3000/compress' ``` -## uncompress pdf file +### Uncompress PDF -``` +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@path/to/my/compressed.pdf" \ 'http://localhost:3000/uncompress' ``` -## encrypt pdf file +### Encrypt PDF -``` +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@path/to/my/file.pdf" \ 'http://localhost:3000/encrypt?password=1234&userPassword=asdf&allow=Printing' ``` -options: - - password - String (required) - - userPassword - String - - allow - Enum - - Printing - - DegradedPrinting - - ModifyContents - - Assembly - - CopyContents - - ScreenReaders - - ModifyAnnotations - - FillIn - - AllFeatures - -## decrypt pdf file +**Options:** -``` +- `password` (required) - Owner password +- `userPassword` - User password +- `allow` - Permission enum: + - `Printing` + - `DegradedPrinting` + - `ModifyContents` + - `Assembly` + - `CopyContents` + - `ScreenReaders` + - `ModifyAnnotations` + - `FillIn` + - `AllFeatures` + +### Decrypt PDF + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@path/to/my/encrypted.pdf" \ 'http://localhost:3000/decrypt?password=1234' ``` -## data fields pdf file -returns the pdf form fields as json +### Get Form Fields (JSON) -``` +Returns PDF form fields as JSON. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@path/to/my/pdf-form.pdf" \ 'http://localhost:3000/data/fields' ``` -## data dump pdf file -returns pdf file information as json +### Get Document Info (JSON) -``` +Returns PDF file information as JSON. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@path/to/my/file.pdf" \ 'http://localhost:3000/data/dump' ``` -## data fdf pdf file -returns pdf form fields as fdf format +### Get Form Fields (FDF) -``` +Returns PDF form fields in FDF format. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@path/to/my/pdf-form.pdf" \ 'http://localhost:3000/data/fdf' ``` -## form fill pdf file -fills pdf passed values +### Fill PDF Form -``` +Fills a PDF with the provided field values. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@path/to/my/pdf-form.pdf" \ 'http://localhost:3000/form/fill?field1=value1&field2=value2' ``` -arguments: - - flag - Enum - - need_appearances (default) - - flatten - - replacement_font (additional fontName can be defined) - - fontName - - - all form fields are passed with the name +**Arguments:** + +- `flag` - Enum: + - `need_appearances` (default) + - `flatten` + - `replacement_font` (requires `fontName`) +- `fontName` - Additional font name (when using `replacement_font`) +- All form fields are passed as query parameters by name ## Ports -- HTTP 3000 +| Port | Service | Description | +|------|---------|-------------| +| 3000 | HTTP | REST API server | + +## online test + +[![pdftk.api.datage.ch](https://uptime.riwi.dev/api/badge/34/status)](https://pdftk.api.datage.ch/) diff --git a/apps/poppler/README.md b/apps/poppler/README.md index 9759e7cd..3278d395 100644 --- a/apps/poppler/README.md +++ b/apps/poppler/README.md @@ -1,23 +1,51 @@ -# poppler node wrapper +# Poppler Node.js Wrapper -## Run Image +A containerized Node.js service that provides a REST API for converting PDF documents to text or HTML using Poppler utilities. -``` +## Features + +- ๐Ÿ“„ **PDF to Text** - Extract plain text from PDFs +- ๐ŸŒ **PDF to HTML** - Convert PDFs to HTML +- ๐Ÿณ **Docker Ready** - Easy deployment with Docker +- ๐Ÿ”ง **REST API** - Simple HTTP interface + +## Quick Start + +### Run with Docker + +```bash docker run -p 3000:3000 --name poppler philiplehmann/poppler-server:latest ``` -## Convert pdf to text +### Run with Docker Compose +```yaml +services: + poppler: + image: philiplehmann/poppler-server:latest + ports: + - "3000:3000" + container_name: poppler ``` + +## API Endpoints + +### Convert PDF to Text + +Send the PDF as binary data in the request body with header `content-type: application/x-www-form-urlencoded`. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@path/to/my/document.pdf" \ 'http://localhost:3000/pdf-to-text' ``` -## Convert pdf to html +### Convert PDF to HTML -``` +Send the PDF as binary data in the request body with header `content-type: application/x-www-form-urlencoded`. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@path/to/my/document.pdf" \ @@ -26,4 +54,10 @@ curl -X POST \ ## Ports -- HTTP 3000 +| Port | Service | Description | +|------|---------|-------------| +| 3000 | HTTP | REST API server | + +## online test + +[![poppler.api.datage.ch](https://uptime.riwi.dev/api/badge/35/status)](https://poppler.api.datage.ch/) diff --git a/apps/puppeteer/README.md b/apps/puppeteer/README.md index 7eabb56a..8d4d1650 100644 --- a/apps/puppeteer/README.md +++ b/apps/puppeteer/README.md @@ -377,3 +377,7 @@ yarn nx serve puppeteer ## License This project is licensed under the MIT License. + +## online test + +[![puppeteer.api.datage.ch](https://uptime.riwi.dev/api/badge/36/status)](https://puppeteer.api.datage.ch/) diff --git a/apps/tesseract/README.md b/apps/tesseract/README.md index 73eb28e3..405c5b57 100644 --- a/apps/tesseract/README.md +++ b/apps/tesseract/README.md @@ -1,20 +1,117 @@ -# tesseract node wrapper +# Tesseract Node.js Wrapper -## Run Image +A containerized Node.js service that provides a simple REST API for converting images into text using Tesseract OCR. -``` +## Features + +- ๐Ÿง  **OCR Powered** - Extract text from images with Tesseract +- ๐Ÿ“ท **Image-to-Text API** - Simple HTTP endpoint +- ๐Ÿณ **Docker Ready** - Easy deployment with Docker +- ๐Ÿ”ง **REST API** - Minimal, straightforward interface + +## Quick Start + +### Run with Docker + +```bash docker run -p 3000:3000 --rm --name tesseract philiplehmann/tesseract:latest ``` -## Convert image to text +### Run with Docker Compose +```yaml +services: + tesseract: + image: philiplehmann/tesseract:latest + ports: + - "3000:3000" + container_name: tesseract ``` + +## API Endpoints + +### Convert Image to Text + +Send an image as binary data in the request body. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@path/to/my/image.type" \ 'http://localhost:3000/image-to-text' ``` +**Response:** The extracted text as the response body. + +## Request Examples + +### JavaScript/Node.js + +```javascript +const fs = require('fs'); + +const imageBuffer = fs.readFileSync('image.png'); + +const response = await fetch('http://localhost:3000/image-to-text', { + method: 'POST', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + }, + body: imageBuffer, +}); + +const text = await response.text(); +console.log(text); +``` + +### Python + +```python +import requests + +with open('image.png', 'rb') as f: + response = requests.post( + 'http://localhost:3000/image-to-text', + headers={'content-type': 'application/x-www-form-urlencoded'}, + data=f + ) + +print(response.text) +``` + +### PHP + +```php + [ + 'method' => 'POST', + 'header' => "content-type: application/x-www-form-urlencoded\r\n", + 'content' => $image + ] +]; + +$context = stream_context_create($opts); +$response = file_get_contents('http://localhost:3000/image-to-text', false, $context); + +echo $response; +?> +``` + ## Ports -- HTTP 3000 +| Port | Service | Description | +|------|---------|-------------| +| 3000 | HTTP | REST API server | + +## Tips + +- Use high-contrast images for best OCR results +- Prefer PNG/JPEG images with readable text +- If the output looks incorrect, try preprocessing (rotate, increase contrast, remove noise) + +## online test + +[![tesseract.api.datage.ch](https://uptime.riwi.dev/api/badge/37/status)](https://tesseract.api.datage.ch/) diff --git a/apps/unoserver/README.md b/apps/unoserver/README.md index f5d2ead2..5d281f54 100644 --- a/apps/unoserver/README.md +++ b/apps/unoserver/README.md @@ -1,94 +1,144 @@ -# unoserver node wrapper +# Unoserver Node.js Wrapper -## Run Image +A containerized Node.js service that provides a REST API for converting office documents using LibreOffice via unoserver. -``` +## Features + +- ๐Ÿ“„ **Document Conversion** - Convert DOCX, XLSX, PPTX, and more +- ๐Ÿ–ผ๏ธ **Image Output** - Export to PNG/JPEG +- ๐Ÿณ **Docker Ready** - Easy deployment with Docker +- ๐Ÿ”ง **REST API** - Simple HTTP interface +- โš™๏ธ **Flexible Options** - Control filters, page ranges, and output behavior + +## Quick Start + +### Run with Docker + +```bash docker run --rm -p 3000:3000 --name unoserver philiplehmann/unoserver:latest ``` -## Convert file +### Run with Docker Compose -default without a param will create pdf +```yaml +services: + unoserver: + image: philiplehmann/unoserver:latest + ports: + - "3000:3000" + container_name: unoserver ``` + +## API Endpoints + +### Convert File + +Default behavior (no parameters) converts to PDF. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@apps/unoserver/src/test/assets/dummy.docx" --output tmp/document.pdf \ 'http://localhost:3000/convert' ``` -convert to pdf -``` +#### Convert To PDF + +```bash curl -X POST \ --data-binary "@apps/unoserver/src/test/assets/dummy.docx" --output tmp/document.pdf \ 'http://localhost:3000/convert?convertTo=pdf' ``` -convert to png -``` +#### Convert To PNG + +```bash curl -X POST \ --data-binary "@apps/unoserver/src/test/assets/dummy.docx" --output tmp/document.png \ 'http://localhost:3000/convert?convertTo=png' ``` -convert to jpeg -``` +#### Convert To JPEG + +```bash curl -X POST \ --data-binary "@apps/unoserver/src/test/assets/dummy.docx" --output tmp/document.jpeg \ 'http://localhost:3000/convert?convertTo=jpeg' ``` -inputFilter - The LibreOffice input filter to use (ex 'writer8'), if autodetect fails -``` +## Options + +### `inputFilter` + +The LibreOffice input filter to use if autodetect fails (e.g. `writer8`). + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@apps/unoserver/src/test/assets/dummy.docx" --output tmp/document.pdf \ 'http://localhost:3000/convert?inputFilter=writer8' ``` -outputFilter - The export filter to use when converting. It is selected automatically if not specified. -``` +### `outputFilter` + +The export filter to use when converting. Selected automatically if not specified. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@apps/unoserver/src/test/assets/dummy.docx" --output tmp/document.pdf \ 'http://localhost:3000/convert?outputFilter=writer_pdf_Export' ``` -filterOptions - The options to use for the output filter, if not specified, the default options are used. -``` +### `filterOptions` + +Options to use for the output filter. Defaults are used if not specified. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@apps/unoserver/src/test/assets/dummy.docx" --output tmp/document.pdf \ 'http://localhost:3000/convert?filterOptions=PageRange=1-2' ``` -updateIndex - Updates the indexes before conversion. Can be time consuming. -``` +### `updateIndex` + +Update indexes before conversion (may be time consuming). + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@apps/unoserver/src/test/assets/dummy.docx" --output tmp/document.pdf \ 'http://localhost:3000/convert?updateIndex=true' ``` -dontUpdateIndex - Skip updating the indexes. -``` +### `dontUpdateIndex` + +Skip updating indexes. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@apps/unoserver/src/test/assets/dummy.docx" --output tmp/document.pdf \ 'http://localhost:3000/convert?dontUpdateIndex=true' ``` +### `verbose` -verbose - Increase informational output to stderr. -``` +Increase informational output to stderr. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@apps/unoserver/src/test/assets/dummy.docx" --output tmp/document.pdf \ 'http://localhost:3000/convert?verbose=true' ``` +### `quiet` -quiet - Decrease informational output to stderr. -``` +Decrease informational output to stderr. + +```bash curl -X POST \ -H 'content-type: application/x-www-form-urlencoded' \ --data-binary "@apps/unoserver/src/test/assets/dummy.docx" --output tmp/document.pdf \ @@ -97,18 +147,21 @@ curl -X POST \ ## Ports -- HTTP 3000 +| Port | Service | Description | +|------|---------|-------------| +| 3000 | HTTP | REST API server | +## Local Development -## test locally +### Start Server -start puppeteer server, will be on port 3000 -``` +```bash LIBREOFFICE_EXECUTABLE_PATH="/Applications/LibreOffice.app/Contents/MacOS/soffice" bun nx serve unoserver ``` -run *-local tests -``` +### Tests (Local Runner) + +```bash # run playwright ui tests TEST_SERVER_RUNNER=local bun nx e2e-local unoserver @@ -118,3 +171,7 @@ TEST_SERVER_RUNNER=local bun nx bun-test-local unoserver # run both, e2e and bun-test TEST_SERVER_RUNNER=local bun nx test-local unoserver ``` + +## online test + +[![unoserver.api.datage.ch](https://uptime.riwi.dev/api/badge/38/status)](https://unoserver.api.datage.ch/)