Pular para o conteúdo

mkcert Cheat Sheet

Overview

mkcert is a simple zero-configuration tool for making locally-trusted development certificates. It automatically creates and installs a local Certificate Authority (CA) in the system trust store, then generates certificates signed by that CA. Browsers and other tools will trust these certificates without any warnings or manual configuration.

Unlike self-signed certificates that require manual trust configuration or generate browser warnings, mkcert handles the entire trust chain setup automatically. It works across Linux, macOS, and Windows, and supports Chrome, Firefox, Java, and system certificate stores.

Installation

# macOS
brew install mkcert
brew install nss  # Required for Firefox support

# Linux (Debian/Ubuntu)
sudo apt install libnss3-tools  # For Firefox support
curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/amd64"
chmod +x mkcert-v*-linux-amd64
sudo mv mkcert-v*-linux-amd64 /usr/local/bin/mkcert

# Arch Linux
sudo pacman -S mkcert

# Windows
choco install mkcert
# or
scoop install mkcert

# Go install
go install filippo.io/mkcert@latest

# Verify
mkcert --version

Setup

# Install the local CA (do this once)
mkcert -install
# This creates a CA certificate and adds it to:
# - macOS: System Keychain
# - Linux: NSS database (for Firefox) and system trust store
# - Windows: Certificate Store

# Check CA location
mkcert -CAROOT

# Uninstall the CA (when done with local dev)
mkcert -uninstall

Core Commands

CommandDescription
mkcert -installInstall the local CA in trust stores
mkcert -uninstallUninstall the local CA
mkcert domain.testGenerate cert for a domain
mkcert -CAROOTPrint CA root directory
mkcert -cert-file <f> -key-file <f>Custom output file names
mkcert -p12-file <f>Generate PKCS#12 format
mkcert -clientGenerate client certificate
mkcert -ecdsaUse ECDSA key instead of RSA
mkcert -pkcs12Generate PKCS#12 keystore

Generating Certificates

Basic Usage

# Single domain
mkcert localhost

# Multiple domains and IPs
mkcert localhost 127.0.0.1 ::1

# Custom domain names
mkcert myapp.local api.myapp.local

# Wildcard certificates
mkcert "*.myapp.local" myapp.local

# Full example with all local names
mkcert localhost 127.0.0.1 ::1 myapp.local "*.myapp.local"
# Output: localhost+4.pem and localhost+4-key.pem

Custom Output Files

# Custom file names
mkcert -cert-file cert.pem -key-file key.pem localhost

# PKCS#12 format (for Java/Spring)
mkcert -pkcs12 localhost
# Output: localhost.p12

# Custom PKCS#12 file name
mkcert -p12-file keystore.p12 localhost 127.0.0.1

# ECDSA key (smaller, faster)
mkcert -ecdsa localhost

# Client certificate
mkcert -client myuser@myapp.local

Configuration

Using with Web Servers

Node.js / Express

const https = require('https');
const fs = require('fs');
const express = require('express');

const app = express();
app.get('/', (req, res) => res.send('Hello HTTPS!'));

const options = {
  key: fs.readFileSync('./localhost-key.pem'),
  cert: fs.readFileSync('./localhost.pem')
};

https.createServer(options, app).listen(3000, () => {
  console.log('HTTPS server running at https://localhost:3000');
});

Nginx

server {
    listen 443 ssl;
    server_name localhost myapp.local;

    ssl_certificate     /path/to/localhost+1.pem;
    ssl_certificate_key /path/to/localhost+1-key.pem;

    location / {
        proxy_pass http://localhost:3000;
    }
}

Python (Flask)

from flask import Flask
app = Flask(__name__)

if __name__ == '__main__':
    app.run(
        host='0.0.0.0',
        port=5000,
        ssl_context=('localhost.pem', 'localhost-key.pem')
    )

Go

package main

import (
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello HTTPS!"))
    })
    log.Fatal(http.ListenAndServeTLS(":8443",
        "localhost.pem", "localhost-key.pem", nil))
}

Using with Docker

# docker-compose.yml
version: '3.8'
services:
  app:
    build: .
    ports:
      - "443:443"
    volumes:
      - ./certs:/certs:ro
    environment:
      - TLS_CERT=/certs/localhost.pem
      - TLS_KEY=/certs/localhost-key.pem
# Generate certs in a certs/ directory
mkdir certs
mkcert -cert-file certs/localhost.pem -key-file certs/localhost-key.pem \
  localhost 127.0.0.1 ::1

Advanced Usage

Custom CA Root Location

# Set custom CA root directory
export CAROOT=/path/to/custom/ca
mkcert -install

# Share CA with team (copy rootCA.pem only, NEVER share rootCA-key.pem)
cp "$(mkcert -CAROOT)/rootCA.pem" ./shared-ca.pem

Java/Spring Boot

# Generate PKCS#12 keystore for Spring Boot
mkcert -pkcs12 -p12-file keystore.p12 localhost 127.0.0.1
# application.properties
server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=changeit

Webpack Dev Server

// webpack.config.js
const fs = require('fs');
module.exports = {
  devServer: {
    https: {
      key: fs.readFileSync('./localhost-key.pem'),
      cert: fs.readFileSync('./localhost.pem'),
    },
    host: 'localhost',
    port: 8080,
  },
};

Vite

// vite.config.js
import fs from 'fs';
import { defineConfig } from 'vite';

export default defineConfig({
  server: {
    https: {
      key: fs.readFileSync('./localhost-key.pem'),
      cert: fs.readFileSync('./localhost.pem'),
    },
  },
});

Troubleshooting

IssueSolution
Firefox still shows warningInstall nss / libnss3-tools and re-run mkcert -install
Certificate not trustedRun mkcert -install again; restart browser
Permission denied on installRun with sudo on Linux; Admin PowerShell on Windows
Docker container doesn’t trust certMount the CA cert and add to container trust store
Wildcard cert not matchingWildcards only match one level; use "*.app.local"
CAROOT permissionsProtect rootCA-key.pem; never share the private key
# Verify certificate details
openssl x509 -in localhost.pem -text -noout

# Check CA is installed
mkcert -CAROOT
ls "$(mkcert -CAROOT)"

# Test HTTPS connection
curl -v https://localhost:3000

# Reinstall CA after OS update
mkcert -uninstall
mkcert -install