Managing local SSL certificates without port (cli)
Tags: docker, productivity, tooling
Published: 2023-06-18 08:39:26

Days ago, I [published a post](https://dev.to/dimaslz/managing-local-ssl-certificates-without-port-3n6d) talking about a script to automate the creation of certificates for local domains: https://github.com/dimaslz/local-ssl-management.

Now I want to share with you a different way to solve the same use case, but in a more convenient manner using a CLI.

## Use case
If you are using a local domain with HTTPS, for example, like https://local.your-domain.com:3000, and you want to remove the port, you can only have one application running on the same port. Another detail is that you need to add a special setup in the project to serve it on port 443. There are other options, but they involve more manual steps.

> I always try to avoid specific settings just for the local environment. The project should have as few differences as possible from the production setup.

Another nuisance with using ports in the URL, in my opinion, is when you have the URL set in multiple services, like GitHub, for the authentication process. If you need to change the port for some reason, you have to go back to GitHub and update the port.

As I enjoy automation scripts, I have created a CLI to automate the creation of local certificates (supported by [mkcert](https://github.com/FiloSottile/mkcert)) and remove the ports from the URL using a Docker image based on Nginx.

## How it works
![How this proxy works](https://raw.githubusercontent.com/dimaslz/local-ssl-management/main/architecture-schema.png)

### Installation
`npm install -g @dimaslz/local-ssl-management-cli` 
> Requirements: docker, node and mkcert

### How to use
> You can read commands here: [https://github.com/dimaslz/local-ssl-management#commands](https://github.com/dimaslz/local-ssl-management#commands)

Once you install the package globally, you can use `local-ssl` command.

```
┌[dimaslz@mbp14] [/dev/ttys106]
└[~]> local-ssl
Usage: local-ssl [options] [command]

Options:
  -h, --help                    display help for command

Commands:
  create [options] <domain>     Create domain
  list                          List domains
  update [options] <domain|id>  update domain
  remove <domain|id>            Create domain
  help [command]                display help for command
```

#### Create your first domain
Now, you do not have any config. If you run the command `local-ssl list` you will see:

```
┌[dimaslz@mbp14] [/dev/ttys106] [1]
└[~]> local-ssl list

id        key        domains        port
```

Then, lets imagine you have a project running on http://localhost:3000 and you want to use a SSL certificate with a custom domain like https://local.your-domain.com. So, first you need to update your `/etc/hosts` as:
```
127.0.0.1       local.your-domain.com
...
```

after, you can run the command:
`local-ssl create local.your-domain.com --port 3000`

```
┌[dimaslz@mbp14] [/dev/ttys106]
└[~]> local-ssl create local.your-domain.com --port 3000

The local ssl proxy is running.

ℹ️  The local ssl proxy is running. Keep it mind that it is important to the local domains that works through HTTPS.


┌──────────────┬──────────────────────┬──────────────────────────────────────────┐
│ container id │ container image      │ port                                     │
├──────────────┼──────────────────────┼──────────────────────────────────────────┤
│ 5f340ae86786 │ local-ssl-management │ 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp │
└──────────────┴──────────────────────┴──────────────────────────────────────────┘


SSL proxy running


domain                                app running
https://local.your-domain.com         ❌
```
> ✅ - is when the application is success on ping
> ❌ - is when the application fails on ping
> In my example, I did not have an application running on port 3000

And now, you can test your domain [https://local.your-domain.com](https://local.your-domain.com) (instead of https://local.your-domain.com:3000) in your browser and should work.

> By default, a SSL cert for `localhost` is created.

#### End
This is something that works for me, and perhaps it can work for you as well. 

Feedback is welcome. If you like it or have any ideas to improve the command, please give me a ⭐️ in Github https://github.com/dimaslz/local-ssl-management to motivate me to continue sharing work.

Thank you for reading and, happy coding! 👨‍💻