## [1.2.0] - 2025-07-29 ### Added - Complete Docker containerization support - Multi-stage Dockerfile with Node.js 18 Alpine base image - Pre-installed mkcert CLI in Docker container - Docker Compose configuration for easy deployment - Volume persistence for certificates and application data - Comprehensive Docker documentation (DOCKER.md) - Docker-specific npm scripts for container management - Health check configuration for container monitoring - Non-root user security implementation in containers - Environment variable support for all configuration options - Automatic Root CA generation when none exists - Manual Root CA generation option with user-friendly interface - Visual indicators for auto-generated Root CAs - New API endpoint `/api/generate-ca` for manual CA creation ### Changed - Updated .gitignore to exclude Docker-related build files - Enhanced package.json with Docker-related scripts - Optimized .dockerignore for efficient Docker builds - Cleaned up unused backup and development files - **Docker**: Added OpenSSL to container for full certificate functionality ### Fixed - **Docker**: OpenSSL now included in container for certificate analysis and operations ### Removed - Unused backup files - Development test utility ### Security - Docker container runs as non-root user (nodejs:1001) - Secure volume mounting for certificate persistence - Production-ready security configurations
mkcert Web UI
A modern web interface for managing SSL certificates using the mkcert CLI tool. This application provides an easy-to-use interface for generating, downloading, and managing local development certificates with organized storage and comprehensive certificate management features.
Screenshot
The mkcert Web UI featuring the new red/green terminal-style theme with certificate management, system status, and Root CA information.
Features
- 🔐 Certificate Generation: Create SSL certificates for multiple domains and IP addresses
- 📁 Organized Storage: Automatic timestamp-based folder organization (YYYY-MM-DD/YYYY-MM-DDTHH-MM-SS_domains/)
- 🔒 Optional Authentication: Secure access with configurable user authentication (can be disabled)
- 🌐 HTTPS Support: Auto-generated SSL certificates for secure web interface access
- 📋 Certificate Management: View, download, and archive certificates with expiry tracking
- 📦 Bundle Downloads: Download certificate and key files as ZIP bundles
- 🔑 Root CA Management: Install, view, and download the mkcert root Certificate Authority
- 🎨 Terminal-Style UI: Modern red/green color scheme with monospace fonts and glowing effects
- 🌙 Dark/Light Mode: Switchable themes with persistent user preference storage
- 🔒 Security: Root certificates are read-only protected, authenticated sessions, input validation
- 📊 Certificate Details: View domains, expiry dates, file sizes, and certificate information
- 🔄 Dual Format Support: Generate certificates in PEM (.pem/.key) or CRT (.crt/.key) formats
Prerequisites
Required Software
- Node.js (version 16 or higher) - JavaScript runtime
- mkcert - Local certificate authority tool
- OpenSSL - Certificate analysis (usually pre-installed on Ubuntu)
Ubuntu Installation (Recommended)
Install Node.js
# Install Node.js 18 LTS (recommended)
sudo apt update
sudo apt install -y nodejs npm
# Verify installation
node --version # Should be v16+
npm --version
Install mkcert
# Install dependencies
sudo apt install -y libnss3-tools wget
# Download and install mkcert (latest version)
wget -O mkcert https://github.com/FiloSottile/mkcert/releases/latest/download/mkcert-v1.4.4-linux-amd64
chmod +x mkcert
sudo mv mkcert /usr/local/bin/
# Verify installation
mkcert -version
Install OpenSSL (if not present)
# Usually pre-installed, but if needed:
sudo apt install -y openssl
# Verify installation
openssl version
Installation
Quick Start (Ubuntu)
- Clone the repository:
git clone https://github.com/jeffcaldwellca/mkcertWeb.git
cd mkcertWeb
- Install dependencies:
npm install
- Initialize mkcert (first time only):
# Create and install the root CA
mkcert -install
- Start the application:
npm start
- Access the web interface:
- Open your browser to
http://localhost:3000 - If authentication is enabled: You'll be redirected to the login page
- Use credentials from your
.envfile (default: admin/admin123) - After successful login, you'll access the main interface
- Use credentials from your
- If authentication is disabled: You'll go directly to the certificate generation interface
- The application will verify mkcert installation and CA status
- Open your browser to
HTTPS Configuration
The application supports automatic HTTPS with self-signed certificates generated using mkcert. This provides a secure development environment without browser warnings.
Quick HTTPS Setup
Option 1: HTTPS with HTTP Fallback (Recommended for Development)
# Start with both HTTP and HTTPS servers
npm run https
# Or with environment variables
ENABLE_HTTPS=true npm start
# Access via:
# HTTP: http://localhost:3000
# HTTPS: https://localhost:3443
Option 2: HTTPS Only (Redirects HTTP to HTTPS)
# Start with HTTPS only (HTTP redirects to HTTPS)
npm run https-only
# Or with environment variables
ENABLE_HTTPS=true FORCE_HTTPS=true npm start
# All requests redirect to: https://localhost:3443
Option 3: Custom Domain HTTPS
# Generate certificate for custom domain
SSL_DOMAIN=myapp.local ENABLE_HTTPS=true npm start
# Access via: https://myapp.local:3443
# (Add "127.0.0.1 myapp.local" to /etc/hosts)
Environment Variables for HTTPS
Create a .env file (see .env.example) or set environment variables:
# Basic HTTPS configuration
ENABLE_HTTPS=true # Enable HTTPS server
HTTPS_PORT=3443 # HTTPS server port (default: 3443)
SSL_DOMAIN=localhost # Domain for SSL certificate (default: localhost)
# Advanced options
FORCE_HTTPS=true # Redirect all HTTP to HTTPS
PORT=3000 # HTTP server port (default: 3000)
SSL Certificate Management
The application automatically:
- Generates SSL certificates on first HTTPS startup using mkcert
- Stores certificates in
./ssl/directory - Reuses existing certificates on subsequent startups
- Includes multiple domains: localhost, 127.0.0.1, ::1, and custom domain
Certificate files:
ssl/
├── {domain}.pem # SSL certificate
└── {domain}-key.pem # Private key
Browser Trust Setup
Since the certificates are generated by mkcert, they are automatically trusted if you have:
- Installed mkcert:
mkcert -install(done during setup) - Root CA installed: The mkcert root CA should be in your system trust store
If you see browser warnings:
# Verify mkcert installation
mkcert -install
# Check CA location
mkcert -CAROOT
# Regenerate SSL certificates
rm -rf ssl/
npm run https
Production Deployment (Ubuntu)
Option 1: Simple Service User Deployment
# Create dedicated user
sudo adduser --system --group --home /opt/mkcertui mkcertui
# Install application
sudo cp -r mkcertWeb /opt/mkcertui/
sudo chown -R mkcertui:mkcertui /opt/mkcertui/
# Switch to service user and install dependencies
sudo su - mkcertui
cd mkcertWeb
npm install
# Initialize mkcert for this user
mkcert -install
# Start application
npm start
Option 2: Systemd Service
# Create systemd service file
sudo tee /etc/systemd/system/mkcertui.service << 'EOF'
[Unit]
Description=mkcert Web UI
After=network.target
Wants=network.target
[Service]
Type=simple
User=mkcertui
Group=mkcertui
WorkingDirectory=/opt/mkcertui/mkcertWeb
ExecStart=/usr/bin/node server.js
Restart=always
RestartSec=10
Environment=NODE_ENV=production
Environment=PORT=3000
# Security settings
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/opt/mkcertui
PrivateTmp=yes
[Install]
WantedBy=multi-user.target
EOF
# Enable and start service
sudo systemctl daemon-reload
sudo systemctl enable mkcertui
sudo systemctl start mkcertui
# Check status
sudo systemctl status mkcertui
Environment Configuration
Environment Variables
# Server Configuration
PORT=3000 # HTTP server port (default: 3000)
HTTPS_PORT=3443 # HTTPS server port (default: 3443)
# SSL/HTTPS Configuration
ENABLE_HTTPS=true # Enable HTTPS server (default: false)
SSL_DOMAIN=localhost # Domain name for SSL certificate (default: localhost)
FORCE_HTTPS=true # Redirect HTTP to HTTPS (default: false)
# Application Configuration
NODE_ENV=production # Environment mode
CERT_DIR=/custom/path # Custom certificate storage (optional)
Reverse Proxy (Nginx)
# Install nginx
sudo apt install -y nginx
# Create nginx configuration
sudo tee /etc/nginx/sites-available/mkcertui << 'EOF'
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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_cache_bypass $http_upgrade;
}
}
EOF
# Enable site
sudo ln -s /etc/nginx/sites-available/mkcertui /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Usage
First Time Setup
- Verify Prerequisites: The web interface will check if mkcert and OpenSSL are installed
- Install Root CA: If not already installed, the app will prompt you to install the mkcert root CA
- Download Root CA: Use the Root CA section to download the certificate for other systems
Certificate Generation
- Access the Web Interface: Navigate to
http://localhost:3000 - Enter Domains: In the generation form, enter domain names (one per line):
localhost 127.0.0.1 *.example.com example.com myapp.local - Select Format:
- PEM Format: Standard format (.pem certificate, -key.pem private key)
- CRT Format: Common for web servers (.crt certificate, .key private key)
- Generate: Click "Generate Certificate"
Certificate Organization
Certificates are automatically organized in a hierarchical structure:
certificates/
├── root/ # Legacy certificates (read-only)
│ ├── example.pem
│ └── example-key.pem
└── 2025-07-25/ # Date-based folders
├── 2025-07-25T10-30-45_localhost_127-0-0-1/
│ ├── localhost_127-0-0-1.pem
│ └── localhost_127-0-0-1-key.pem
└── 2025-07-25T14-15-20_example_com/
├── example_com.crt
└── example_com.key
Certificate Management
Viewing Certificates
- Certificate List: Shows all certificates with details:
- Domain names covered
- Expiry date and status
- File format (PEM/CRT)
- Creation date and file size
- Storage location
Downloading Certificates
- Individual Files: Download certificate or key files separately
- Bundle Download: Download both files as a ZIP archive
- Root CA: Download the mkcert root certificate for system installation
Certificate Deletion
- Subfolder Certificates: Can be deleted (includes automatic cleanup of empty folders)
- Root Certificates: Protected from deletion (read-only)
Root CA Management
Viewing CA Information
The Root CA section displays:
- Certificate subject and issuer
- Validity period and expiry status
- SHA256 fingerprint for verification
- File system path
- Installation status
Installing Root CA on Other Systems
Linux (Ubuntu/Debian):
# Download the root CA from the web interface, then:
sudo cp mkcert-rootCA.pem /usr/local/share/ca-certificates/mkcert-rootCA.crt
sudo update-ca-certificates
Windows:
- Download root CA from web interface
- Double-click the .pem file
- Install to "Trusted Root Certification Authorities"
macOS:
- Download root CA from web interface
- Double-click to add to Keychain
- Set trust settings to "Always Trust" Browser Trust:
- Import the root CA into browser security settings
- Add to "Authorities" or "Certificate Authorities" section
API Documentation
REST API Endpoints
The application provides a comprehensive REST API for programmatic access.
🔒 Authentication Note: When authentication is enabled, API endpoints require valid session cookies. For programmatic access, you may need to:
- Disable authentication by setting
DISABLE_AUTH=truein your.envfile, or - First authenticate via
POST /loginto establish a session before making API calls
Authentication
POST /login- Authenticate user and establish sessionPOST /logout- Destroy current session
System Status
GET /api/status- Get mkcert installation and CA statusPOST /api/install-ca- Install the mkcert root CA (requires user confirmation)
Root CA Management
GET /api/rootca/info- Get detailed root CA certificate informationGET /api/download/rootca- Download root CA certificate file
Certificate Management
POST /api/generate- Generate new certificatesGET /api/certificates- List all certificates with metadataDELETE /api/certificates/:folder/:certname- Delete specific certificate
File Downloads
GET /api/download/cert/:folder/:filename- Download certificate fileGET /api/download/key/:folder/:filename- Download private key fileGET /api/download/bundle/:folder/:certname- Download certificate bundle (ZIP)
API Usage Examples
Generate Certificate (using wget - built into Ubuntu)
# Generate PEM format certificate
wget --post-data='{"domains":["localhost","127.0.0.1","*.local.dev"],"format":"pem"}' \
--header='Content-Type: application/json' \
http://localhost:3000/api/generate \
-O /tmp/cert-response.json
# Generate CRT format certificate
wget --post-data='{"domains":["example.local","api.example.local"],"format":"crt"}' \
--header='Content-Type: application/json' \
http://localhost:3000/api/generate \
-O /tmp/cert-response.json
Download Certificate Bundle
# Download as bundle (no external tools needed)
wget http://localhost:3000/api/download/bundle/2025-07-25_2025-07-25T10-30-45_localhost/localhost_127-0-0-1 \
-O certificate-bundle.zip
Check System Status
# Check if mkcert is installed and CA exists
wget -qO- http://localhost:3000/api/status | python3 -m json.tool
List All Certificates
# Get certificate inventory
wget -qO- http://localhost:3000/api/certificates | python3 -m json.tool
File Structure
mkcertWeb/
├── server.js # Express server and API routes
├── package.json # Node.js dependencies and scripts
├── public/ # Frontend static assets
│ ├── index.html # Main web interface
│ ├── login.html # Authentication login page
│ ├── styles.css # Terminal-style CSS with red/green theme
│ ├── script.js # Frontend JavaScript functionality
│ └── assets/ # Static assets (screenshots, etc.)
├── certificates/ # Certificate storage (organized by date)
│ ├── root/ # Legacy certificates (read-only)
│ └── YYYY-MM-DD/ # Date-based organization
│ └── YYYY-MM-DDTHH-MM-SS_domains/ # Timestamped folders
├── .env.example # Environment configuration template
├── README.md # Comprehensive documentation
├── CHANGELOG.md # Version history and release notes
├── TESTING.md # Testing procedures and validation
└── package-lock.json # Dependency lock file
Security & Best Practices
Security Model
- Development Focus: Designed for local development environments
- Optional Authentication: Configurable user authentication with session management
- Regular User Execution: Runs without root privileges (except for
mkcert -install) - Read-Only Protection: Root directory certificates cannot be deleted
- Session Security: HTTP-only cookies with CSRF protection
- Organized Storage: Timestamp-based folders prevent conflicts
Network Security
- HTTP Only: Suitable for localhost development (consider HTTPS proxy for production)
- Local Binding: Binds to localhost by default (configurable)
- No External Dependencies: No outbound network calls required during operation
File Permissions
# Recommended permissions for production deployment
find /opt/mkcertui -type f -name "*.pem" -exec chmod 600 {} \; # Private keys
find /opt/mkcertui -type f -name "*.crt" -exec chmod 644 {} \; # Certificates
find /opt/mkcertui -type d -exec chmod 755 {} \; # Directories
Development
Local Development
# Clone and setup
git clone https://github.com/jeffcaldwellca/mkcertWeb.git
cd mkcertWeb
npm install
# Development modes
npm start # HTTP only (http://localhost:3000)
npm run https # HTTP + HTTPS (http://localhost:3000 & https://localhost:3443)
npm run https-only # HTTPS only with HTTP redirect (https://localhost:3443)
npm run dev # HTTP with auto-restart (nodemon)
npm run https-dev # HTTPS with auto-restart (nodemon)
# Custom domain HTTPS
SSL_DOMAIN=myapp.local npm run https
Testing
See TESTING.md for comprehensive testing procedures including:
- Installation verification
- Certificate generation testing
- API endpoint validation
- Security testing
- Browser integration testing
Configuration
Environment Variables
# Server Configuration
PORT=3000 # Server port (default: 3000)
HTTPS_PORT=3443 # HTTPS server port (default: 3443)
NODE_ENV=production # Environment mode (development/production)
CERT_DIR=/custom/path # Custom certificate storage directory
# HTTPS Configuration
ENABLE_HTTPS=true # Enable HTTPS server (true/false)
SSL_DOMAIN=localhost # Domain name for SSL certificate
FORCE_HTTPS=false # Redirect HTTP to HTTPS (true/false)
# Authentication Configuration
ENABLE_AUTH=false # Enable user authentication (true/false)
AUTH_USERNAME=admin # Username for authentication (when ENABLE_AUTH=true)
AUTH_PASSWORD=admin # Password for authentication (when ENABLE_AUTH=true)
SESSION_SECRET=your-secret # Session secret key - CHANGE IN PRODUCTION!
# UI Configuration
DEFAULT_THEME=dark # Default theme mode for new users (dark/light)
Authentication Setup
To enable user authentication and secure access to the web interface:
-
Copy the example configuration:
cp .env.example .env -
Enable authentication in
.env:ENABLE_AUTH=true AUTH_USERNAME=your-username AUTH_PASSWORD=your-secure-password SESSION_SECRET=your-very-long-random-secret-key -
Start the server:
npm start -
Access the application:
- Visit http://localhost:3000 (or your configured URL)
- You'll be redirected to a login page
- Enter your configured username and password
Security Notes:
- When
ENABLE_AUTH=false, authentication is completely disabled and users have direct access - When
ENABLE_AUTH=true, all API routes are protected and require valid session authentication - Always use a strong, unique
SESSION_SECRETin production environments - Consider using HTTPS when authentication is enabled for additional security
Theme Configuration
The application supports both dark and light themes with a toggle button. You can set the default theme for new users:
# Set default theme in .env
DEFAULT_THEME=light # Start with light mode for new users
DEFAULT_THEME=dark # Start with dark mode for new users (default)
Theme Behavior:
- Users can toggle between themes using the button in the header
- Theme preference is saved in browser localStorage
- If no stored preference exists, the server's
DEFAULT_THEMEsetting is used - Supports both the main application and login page
- Available via API endpoint:
GET /api/config/theme
Customization
# Custom certificate storage location
export CERT_DIR=/var/lib/mkcertui/certificates
mkdir -p $CERT_DIR
chown mkcertui:mkcertui $CERT_DIR
Troubleshooting
Common Issues
mkcert not found
# Verify installation
which mkcert
mkcert -version
# Check PATH
echo $PATH
Permission Denied
# Check file permissions
ls -la certificates/
# Ensure proper ownership
sudo chown -R $(whoami):$(whoami) certificates/
Port Already in Use
# Check what's using port 3000
sudo netstat -tlnp | grep :3000
# Use different port
PORT=3001 npm start
CA Installation Issues
# Manual CA installation
mkcert -install
# Verify CA location
mkcert -CAROOT
# Check CA files exist
ls -la $(mkcert -CAROOT)
Browser Trust Issues
- Clear browser cache and cookies
- Restart browser after CA installation
- Check browser certificate settings
- Verify system certificate store
Log Analysis
# Check application logs
journalctl -u mkcertui -f
# Check nginx logs (if using reverse proxy)
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
Contributing
Development Setup
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Install dependencies:
npm install - Make changes and test thoroughly
- Run tests:
npm test(see TESTING.md) - Submit a pull request
Code Style
- ESLint configuration for consistent code style
- Comprehensive error handling
- Clear API documentation
- Responsive UI design
Resources
- mkcert: GitHub Repository
- Node.js: Official Documentation
- Express.js: Framework Documentation
- SSL/TLS: Mozilla SSL Configuration
