Skip to content

🌐 The all-in-one tool, for keeping track of your domain name portfolio. Got domain names? Get Domain Locker!

License

Notifications You must be signed in to change notification settings

Lissy93/domain-locker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Domain Locker

The Central Hub for all your Domain Names
🌐domain-locker.com


Contents

About

The aim of Domain Locker, is to give you complete visibility of your domain name portfolio, in once central place.

For each domain you add, we analyse it and fetch all associated data. We then continuously monitor your domains, and notify you (according to your preferences) when something important changes or when it's soon to expire.

You'll get detailed domain analysis, security insights, change history, recent performance, valuation data and much more. You'll never again loose track of your domains, miss an expiration, or forget which registrar and providers each domain uses.

Screenshot

(Sorry about the 5fps, I wanted to keep file size down!)


More...

Features

  • πŸ“‘ Auto-fetched data: SSL certs, hosts, registrars, IPs, subdomains, DNS, etc
  • πŸ”¬ View detailed metrics and analysis for each domain
  • πŸ“Š Visual analytics and breakdowns and trends across your portfolio
  • πŸ’¬ Configurable alerts and webhook notifications
  • πŸ—ƒοΈ Easy import/export, as well as API data access
  • πŸ“œ Track changes in domain configuration over time
  • πŸ“ˆ Monitor website health, security and performance
  • πŸ’Ή Keep record of purchase prices and renewal costs
  • πŸ”– Add categories, and link related resources to domains
  • 🎨 Multi-language support, dark/light/custom themes

Demo

Try the live demo to demo.domain-locker.com
(Username: [email protected] Password: domainlocker)


Get Started

To use Domain Locker, you have two options:

  1. πŸ’» The managed instance, at domain-locker.com (free)
  2. πŸ—οΈ Or self-hosting yourself via Docker (also free, ofc!)

Option 1: Domain-Locker.com

Head to our website, and sign up with Google, GitHub or your email.
The starter plan is free, and no setup is required. Just sign in, add your domains, and start tracking them.

Option 2: Self-Hosting

Warning

The self-hosted version is in Alpha phase, and still under active development

TODO
  • Prerequisites:
    • Domain Locker is intended to be run in a container, so you'll need Docker installed on your host system.
  • Containers:
  • Environment:
    • When starting the container, bind PORT to 3000.
    • Then specify the Postgres environmental variables: DL_PG_HOST, DL_PG_PORT, DL_PG_USER, DL_PG_PASSWORD and DL_PG_NAME.
  • Crons
    • /api/domain-updater - Execute this daily, to keep domain data up-to-date and trigger notifications
    • /api/uptime-monitor - Execute this every N minutes, to monitor website uptime and performance
  • Example:

Developing

Project Setup

git clone [email protected]:Lissy93/domain-locker.git    # Get the code
cd domain-locker                                      # Navigate into directory
npm install --legacy-peer-deps                        # Install dependencies
cp .env.example .env                                  # Set environmental variables
npm run dev                                           # Start the dev server
  • Prerequisites
    • You'll need Git and Node installed on your system.
  • Configuring
    • The example .env.sample file includes the public creds for our Supabase dev instance
    • To use alternate db, see the Database section below to configure with Postgres
  • Deploying
    • You can build with code with npm run build, then run with npm start
    • With Docker, you can build the container with docker build -t domain-locker .
    • Don't use the dev Supabase instance in prod, as it's frequently wiped

Tech Stack

Domain Locker is made up of an app, database and some API endpoints.

  • The app is built with Angular, using Analog+Nitro with PrimeNg components, and Tailwind for styling
  • The server is a series of Deno endpoints with Typescript functions
  • The database can be either Postgres or Supabase

While the self-hosted instance is intended to be deployed stand-alone, the managed version however depends on a few additional third-party services, which you can see below, the docs of which are here.

Why Why Angular? As some sort of sick joke to future me, who then needs to maintain this.


You can view docs for the technologies and services used here

Architecture

The architecture is pretty simple. We have an app (consisting of a frontend and API endpoints), where the user can read and write to the database (through adapters). Then a cron service will periodically call API endpoints to keep domain data up-to-date, track changes, monitor health, and trigger notifications on certain changes (according to user preference) or before an upcoming expiration.

graph TD;
    subgraph User Interactions
        User[πŸ‘€ User] -->|Enter domain| WebApp[🌐 Frontend];
        WebApp -->|Send API request| API[βš™οΈ Nitro API];
        API -->|Auth Check| Auth[πŸ” Auth Service];
        API -->|Store domain info| Database[πŸ—„οΈ PostgreSQL / Supabase];
    end

    subgraph Automated Cron Jobs
        CronService[⏳ Cron Service] -->|Trigger Updates| EdgeFunctions[⚑ Edge Functions];
        EdgeFunctions -->|Fetch WHOIS, DNS, SSL| ExternalAPIs[🌎 Analysis Services];
        EdgeFunctions -->|Store Data| Database;
        
        CronService -->|Monitor Uptime| WebsiteMonitor[πŸ“‘ Uptime Monitor];
        WebsiteMonitor -->|Store Metrics| Database;

        CronService -->|Check Expirations| ExpiryChecker[πŸ“† Expiration Check];
        ExpiryChecker -->|Update Status| Database;
        
        CronService -->|Send Notifications| NotificationService[πŸ”” Notification System];
        NotificationService -->|Email| Resend[πŸ“§ Resend];
        NotificationService -->|SMS| Twilio[πŸ“± Twilio];
    end

    Database -->|Serve Data| WebApp;
Loading

Database

A database is needed to store all your domains and associated info. Domain Locker supports both Supabase and standard Postgres for storing data. The db used will depend on which env vars are set.

  • Supabase: Follow the Supabase self-hosting docs, then use dl-sb-iac to import the schema and configure auth, edge functions, emails, etc.
    • Then set: SUPABASE_URL and SUPABASE_ANON_KEY environmental variables
  • Postgres: Deploy a Postgres instance, then use our setup-postgres.sh script to init your DB with ourschema.sql
    • Then set: DL_PG_HOST, DL_PG_PORT, DL_PG_USER, DL_PG_PASSWORD, DL_PG_NAME
classDiagram
  class users {
    uuid id
    text email
    timestamp created_at
    timestamp updated_at
  }

  class domains {
    uuid id
    uuid user_id
    text domain_name
    date expiry_date
    text notes
    timestamp created_at
    timestamp updated_at
    uuid registrar_id
    timestamp registration_date
    timestamp updated_date
  }

  class registrars {
    uuid id
    text name
    text url
    uuid user_id
  }

  class tags {
    uuid id
    text name
    text color
    text description
    text icon
    uuid user_id
  }

  class domain_tags {
    uuid domain_id
    uuid tag_id
  }

  class notifications {
    uuid id
    uuid user_id
    uuid domain_id
    text change_type
    text message
    boolean sent
    boolean read
    timestamp created_at
  }

  class billing {
    uuid id
    uuid user_id
    text current_plan
    timestamp next_payment_due
    text billing_method
    timestamp created_at
    timestamp updated_at
    jsonb meta
  }

  class dns_records {
    uuid id
    uuid domain_id
    text record_type
    text record_value
    timestamp created_at
    timestamp updated_at
  }

  class domain_costings {
    uuid id
    uuid domain_id
    numeric purchase_price
    numeric current_value
    numeric renewal_cost
    boolean auto_renew
    timestamp created_at
    timestamp updated_at
  }

  class domain_hosts {
    uuid domain_id
    uuid host_id
  }

  class domain_links {
    uuid id
    uuid domain_id
    text link_name
    text link_url
    timestamp created_at
    timestamp updated_at
    text link_description
  }

  class domain_statuses {
    uuid id
    uuid domain_id
    text status_code
    timestamp created_at
  }

  class domain_updates {
    uuid id
    uuid domain_id
    uuid user_id
    text change
    text change_type
    text old_value
    text new_value
    timestamp date
  }

  class uptime {
    uuid id
    uuid domain_id
    timestamp checked_at
    boolean is_up
    integer response_code
    numeric response_time_ms
    numeric dns_lookup_time_ms
    numeric ssl_handshake_time_ms
    timestamp created_at
  }

  class ssl_certificates {
    uuid id
    uuid domain_id
    text issuer
    text issuer_country
    text subject
    date valid_from
    date valid_to
    text fingerprint
    integer key_size
    text signature_algorithm
    timestamp created_at
    timestamp updated_at
  }

  class whois_info {
    uuid id
    uuid domain_id
    text country
    text state
    text name
    text organization
    text street
    text city
    text postal_code
  }

  class user_info {
    uuid id
    uuid user_id
    jsonb notification_channels
    timestamp created_at
    timestamp updated_at
    text current_plan
  }

  class hosts {
    uuid id
    inet ip
    numeric lat
    numeric lon
    text isp
    text org
    text as_number
    text city
    text region
    text country
    uuid user_id
  }

  class ip_addresses {
    uuid id
    uuid domain_id
    inet ip_address
    boolean is_ipv6
    timestamp created_at
    timestamp updated_at
  }

  class notification_preferences {
    uuid id
    uuid domain_id
    text notification_type
    boolean is_enabled
    timestamp created_at
    timestamp updated_at
  }

  class sub_domains {
    uuid id
    uuid domain_id
    text name
    timestamp created_at
    timestamp updated_at
    jsonb sd_info
  }

  users --> domains : user_id
  registrars --> domains : registrar_id
  users --> registrars : user_id
  users --> tags : user_id
  domains --> domain_tags : domain_id
  tags --> domain_tags : tag_id
  users --> notifications : user_id
  domains --> notifications : domain_id
  users --> billing : user_id
  domains --> dns_records : domain_id
  domains --> domain_costings : domain_id
  domains --> domain_hosts : domain_id
  hosts --> domain_hosts : host_id
  domains --> domain_links : domain_id
  domains --> domain_statuses : domain_id
  domains --> domain_updates : domain_id
  users --> domain_updates : user_id
  domains --> uptime : domain_id
  domains --> ssl_certificates : domain_id
  domains --> whois_info : domain_id
  users --> user_info : user_id
  users --> hosts : user_id
  domains --> ip_addresses : domain_id
  domains --> notification_preferences : domain_id
  domains --> sub_domains : domain_id
Loading

You can download the schema from db/schema.sql

Contributing

Contributions, of any kind are always welcome, and very much appreciated! πŸ’—

If you're new to Git, the general flow of contributing, is as follows:

  • Fork the repo, by clicking here
  • Clone your fork (with git clone [email protected]:[your_username]/domain-locker.git)
  • Follow the Project Setup above, to get the project running in development mode
  • Implement your awesome new feature or amazing bug fix...
  • Checkout a branch, with git checkout -b feature-branch, then git add your changes and git commit using conventional commits, before git pushing to your branch
  • Head back to GitHub, and you can then open up a PR against our main branch. Don't forget to include what you changed, why and link to any associated issues.
  • We'll then review, feedback, and merge, and once released your changes will go live to prod, as well as be available in the latest Docker image.

Attributions

Contributors

contributors

Sponsors

sponsors


License

Lissy93/Domain-Locker is licensed under MIT Β© Alicia Sykes 2025.
For information, see TLDR Legal > MIT

Expand License
The MIT License (MIT)
Copyright (c) Alicia Sykes <[email protected]> 

Permission is hereby granted, free of charge, to any person obtaining a copy 
of this software and associated documentation files (the "Software"), to deal 
in the Software without restriction, including without limitation the rights 
to use, copy, modify, merge, publish, distribute, sub-license, and/or sell 
copies of the Software, and to permit persons to whom the Software is furnished 
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included install 
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANT ABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Β© Alicia Sykes 2025
Licensed under MIT

Thanks for visiting :)