LogoLogo
  • πŸ‘‹Cal.com Handbook
  • The Company
    • ❓What is Cal.com?
    • πŸ“ˆMission, Vision and Values
    • πŸ…°οΈGlossary
    • πŸ“ˆOrganization Chart
  • HR & Careers
    • πŸ‘·Contract-to-hire trials
    • πŸ›«Onboarding
    • πŸ†IC Levels
      • ⛰️Engineering Levels
        • πŸ•΅οΈIC1 Engineer (Code Cadet)
        • πŸ‘·β€β™€οΈIC2 Engineer (Code Craftsperson)
        • πŸ§˜β€β™€οΈIC3 Engineer (Code Connoisseur)
        • πŸ§™β€β™‚οΈIC4 Engineer (Code Wizard)
    • πŸ’‘Sharing your views
    • πŸ’ΈBonus & Equity Structure
  • Policies
    • πŸ–οΈVacations
    • πŸ’³Expenses
    • πŸ—£οΈCommunications
  • Engineering
    • πŸ””Managing Notifications
    • ⭐Valuable Bookmarks
    • πŸ›How to report issues
    • πŸ’»How we work on Tickets
    • πŸ”₯What to do during Emergencies
    • βœ…PR Reviews
    • β˜‘οΈSelf-reviews
    • πŸ“šKeeping Docs up-to-date
    • 🌐HTTPS & Subdomains
    • 🎯Best practices
      • Data fetching
      • Avoid Prop Drilling
      • Prefer defaultHandler for simple API handlers
      • Prefer inferred types over explicit ones
      • Prefer early returns
      • Avoid comparing multiple values with `includes`
      • Validate using zod instead of type casting
      • Prefer Composition over Prop Drilling
      • Prefer ternaries over Short Circuiting β€œ&&” for React Components
      • Don't modularize prematurely
      • Only select data you need
      • Disallowing the use of unrestricted Metadata fields
      • E2E Tests Best Practices
    • πŸ’»Codebase
      • πŸ”“Keeping the lock file in sync
      • 🚫Git Private Submodules
      • 🏎️Monorepo / Turborepo
      • 🌝Deploying to Production
      • ☁️Deployment
      • πŸ’»Debug Desktop App
      • 🚩Enabling/Disabling Features
    • πŸ”ΊResolving failed migration on Vercel Preview
    • πŸ”¦Cal.com Status Page
  • Customer Success
    • πŸ’ŸTone
  • Marketing
    • 🎬Media
    • ☝️How to add a new Tip to Sidebar
  • 🀲Sales
    • Operations Stack
Powered by GitBook
On this page
  • Prerequisites
  • Install Dnsmasq
  • Configure Dnsmasq to resolve *.localhost domains
  • Run Dnsmasq now and anytime we restart the system
  • Make macOS use our local DNS server (Dnsmasq) for .localhost addresses
  • Install Caddy
  • Configure Caddy
  • Run Caddy now and every time your system restarts
  • Setup our your environment variables
  • Run website and web app at the same time
  • Go to the website or web app domain

Was this helpful?

  1. Engineering

HTTPS & Subdomains

Since we’re going to start using cross-subdomain authentication it’s pretty important that we can test both https://app.cal.localhost and https://cal.localhost locally. This is a quick guide on how can we achieve this setup locally for development purposes.

Prerequisites

  • Caddy Server

  • Dnsmasq

Install Dnsmasq

brew install dnsmasq

Configure Dnsmasq to resolve *.localhost domains

First let’s check where our brew installation config files are:

$ brew --prefix
/opt/homebrew

In my case it lives at /opt/homebrew/etc/dnsmasq.conf

# Route all *.localhost addresses to localhost
address=/localhost/127.0.0.1

# Don't read /etc/resolv.conf or any other configuration files.
no-resolv

# Never forward plain names (without a dot or domain part)
domain-needed

# Never forward addresses in the non-routed address spaces.
bogus-priv

Run Dnsmasq now and anytime we restart the system

sudo brew services start dnsmasq

Make macOS use our local DNS server (Dnsmasq) for .localhost addresses

Create the following file at /etc/resolver/localhost:

nameserver 127.0.0.1

With that, you can go to subdomain.localhost in your browser and it will point to localhost. So if your app is running on port 3000, simply go to subdomain.localhost:3000.

But what if you're looking for the following setup?

cal.localhost       -> localhost:3001
app.cal.localhost   -> localhost:3000

Install Caddy

brew install caddy

Configure Caddy

In my case (because my brew --prefix is /opt/homebrew), my global Caddyfile is at /opt/homebrew/etc/Caddyfile. This file we can setup to act as a simple reverse proxy for our individual apps running on different ports:

https://cal.localhost {
        reverse_proxy localhost:3001
}

https://app.cal.localhost {
        reverse_proxy localhost:3000
}

Run Caddy now and every time your system restarts

brew services start caddy

That's it! If you change your Caddyfile, you will need to brew services restart caddy.

Setup our your environment variables

NEXTAUTH_URL='https://app.cal.localhost'
NEXT_PUBLIC_WEBAPP_URL='https://app.cal.localhost'
NEXT_PUBLIC_WEBSITE_URL='https://cal.localhost'
NODE_TLS_REJECT_UNAUTHORIZED=0  # Needed so HTTPS doesn't complain locally

Run website and web app at the same time

yarn turbo run dev --scope="@calcom/web" --scope="@calcom/website"

Go to the website or web app domain

You should be able to go to https://app.cal.localhost and https://cal.localhost successfully πŸ™Œ

PreviousKeeping Docs up-to-dateNextBest practices

Last updated 1 year ago

Was this helpful?

This we can solve with which is a super-awesome simple HTTP server!

Thanks to Max 's article and Caddy for making it easy to get started with Dnsmasq.

🌐
Caddy
Local subdomains on macOS with Dnsmasq