Wiredoor is four repositories, one Compose stack, and a .env that opens authentication
Self hosted ingress-as-a-service platform that allows you to expose applications and services running in private or local networks to the internet
At a glance
- What is it?
- Wiredoor puts NGINX and WireGuard behind a self-hosted ingress, but the repository you read is not the one you deploy from, the package version disagrees with the release tags, and the shipped environment example selects an OAuth2 provider while leaving both access restrictions switched off.
- Who is it for?
- Wiredoor fits operators who want to own the entry point rather than rent a hosted tunnel, and the parts that decide whether it works for you are unglamorous: whether your platform can run the node type you need, since gateway routing wants Linux iptables, and whether your OAuth2 identity provider matches what the example file assumes.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 8, 2026, and from our analysis. They are not legal advice.
Editorial analysis
You deploy from a different repository than the one you read
The quickstart begins by cloning a setup repository that is not this one.
git clone https://github.com/wiredoor/docker-setup.git
cd docker-setup
cp .env.example .envFrom there the server starts with Compose and you sign in to a web address.
docker compose up -d
docker compose ps wiredoorSo the code in this repository, with its src, frontend, docker and documentation directories, is not what you run to get a server. The platform is spread across at least four places: this application repository, the docker-setup repository you just cloned, a separate Wiredoor CLI repository linked from the header, and a separate Helm chart host at charts.wiredoor.net for the Kubernetes gateway, with the image published on Docker Hub. A container image, an npm package and a Helm chart can each be at a different version, and nothing in this tree ties those three together. Even the CLI is not installed from this repository: the quickstart sends you to per-operating-system installation instructions on the documentation site, and only the registration commands are shown inline.
wiredoor login --url https://wiredoor.example.com
wiredoor statusThe URL in that command is a placeholder you replace with the domain or IP address of your own server.
The manifest says 1.0.0 while the published tags are at v1.8.0
The package manifest carries the name wiredoor-app and the version 1.0.0, while the release list for the repository runs v1.8.0, v1.7.3 and v1.7.2. That is not a small gap: it is a mismatch between the version recorded in the source tree and the version the releases are published under, and it means the number inside package.json tells you nothing about which build you are running. The entry points in the same file are inconsistent in a second way. `main` points at src/main.js, a compiled JavaScript path, while development runs the TypeScript source directly through ts-node with the transpile-only flag, and the build step is tsc against tsconfig.json.
"main": "src/main.js"
"build": "tsc -p tsconfig.json"
"exec": "ts-node --transpile-only ./src/main.ts"So the field npm would read and the file a developer actually executes are not the same path, and nodemon is configured with a 2.5 second delay over js, ts and json extensions while ignoring spec files, stub files and everything under src/public. The manifest also declares its author as Daniel Mesa and its keywords as wiredoor, wireguard, nginx, proxy and vpn, which is the clearest statement of what the project is.
The environment example arrives with an OAuth2 provider already selected
Three lines in the example environment file are not placeholders waiting to be filled in.
OAUTH2_PROXY_PROVIDER=google
OAUTH2_PROXY_CLIENT_ID=
OAUTH2_PROXY_CLIENT_SECRET=The provider is pre-set to google while both credentials are empty, so the one configuration choice that has a default is the one you are least likely to read past. Two lines below, the access restrictions are commented out rather than empty: `OAUTH2_PROXY_ALLOWED_GROUPS` is inactive, and `OAUTH2_PROXY_EMAIL_DOMAINS` is inactive with the note that the domain is a wildcard by default. So a copy of this file, filled in with credentials and nothing else, authenticates everyone the provider will vouch for. The header comment links to the oauth2-proxy provider documentation, which is where the group and domain settings are described.
Gateway routing wants Linux iptables, which narrows the node table
The node types are not four interchangeable options. A Client Node exposes a service on the same Linux, Windows or macOS computer, a Linux Gateway Node routes to several services in an approved subnet, a Docker Gateway runs on Linux, Windows or macOS through Docker, and a Kubernetes Gateway runs through the official chart. The catch is stated directly: gateway routing depends on Linux iptables rules, and native Wiredoor CLI installations on Windows and macOS support Client Node mode only. To run a local gateway on either of those systems the documented path is the Docker Gateway through Docker Desktop, which means adding a container runtime to a machine that did not need one. The two node kinds also differ in scope rather than only in platform: a Client Node exposes one service running on the same computer, while a Gateway Node provides access to approved services in a Docker network, a Kubernetes cluster or a private subnet. The Docker Gateway paragraph then names the desktop systems it supports and stops in the middle of a word, so the detail for those hosts is left to the documentation site.
Public DNS is optional and the certificate type follows from that choice
The requirements list is short and mostly about ports: a reachable Linux server with Docker Engine, Docker Compose and Git, TCP 80 and 443 open on the server, and UDP 51820 open unless another VPN port is configured. Beyond that, a public domain is not required. An internal DNS name works, and so does an entry in the hosts file on Linux, Windows or macOS, which is what makes it possible to try the platform without buying a name. What you give up is the certificate: public domains can get automatic Let's Encrypt certificates when eligible, while local and internal domains fall back to self-signed ones. TLS termination happens on Wiredoor Server itself, which then routes through NGINX for domains, paths and public ports. Two access controls sit alongside the certificate choice rather than replacing it: OAuth2 authentication and IP based access restrictions, with WebSocket support for HTTP services that hold a connection open. Monitoring is optional rather than built in, arriving as Prometheus metrics and Grafana dashboards you turn on yourself, and both the web dashboard and the CLI can manage the same nodes and domains.
Nodes dial out, so the private network never has to accept an inbound VPN
The direction of the connection is the design decision everything else follows from. Remote nodes initiate encrypted WireGuard tunnels to Wiredoor Server, which means a service behind NAT or a firewall never has to accept a public inbound VPN connection. The server receives HTTP, TCP or UDP traffic and selects the configured route, the node reaches the private service, and WebSocket support covers HTTP services that stay open. Exposing a service is a single command naming a name, a domain and a port.
wiredoor http first-app --domain app.example.com --port 3000Registration is a login against the server address followed by a status check, and the node reports what it can reach. Both Client Nodes and Gateway Nodes are described as initiating the connection, so the outbound property is a property of the platform rather than of one node type.
The test script runs serially and silently with generated data
The test command in the manifest is jest with three flags: --runInBand, which forces the suites to execute one after another instead of across workers, --detectOpenHandles, which keeps track of handles that would stop the process from exiting, and --silent, which suppresses the reporter output. Beside it sit a jest.config.ts, a dedicated tsconfig.jest.json and a separate tsconfig.eslint.json, so the project keeps three TypeScript configurations for three purposes. The development dependencies include faker-js, which is how tests obtain data without a network, and jest globals rather than bare globals. Linting is wired through prettier inside eslint rather than run separately, with an eslint-plugin-prettier and an eslint-config-prettier pair plus a prettierrc at the root, and the lint script itself is scoped to src. The root carries three TypeScript configurations and two competing transpiler configs, since babel.config.js sits alongside a babel preset-typescript dependency while the build itself is driven by tsc, so the fast development path and the shipped path do not share a compiler.
A terms file sits in an Apache-2.0 tree beside the automation configs
The root of the repository mixes licensing, automation and documentation config in a way worth knowing before you copy anything out of it. The license is Apache-2.0 and a LICENSE file sits beside it, but TERMS.md is there too, and nothing in the manifest or the README explains what the two govern. The same root carries renovate.json for dependency update automation, context7.json for machine-readable documentation indexing, a devcontainer directory, a vscode directory, a jest config in TypeScript and an eslint config in JavaScript modules. The typeorm migration scripts all point at a single datasource file under src/database, with create, generate, run and revert variants, and the revert script carries an extra double dash before its datasource argument that the other three do not have. Database work is also wired to the environment file: the typeorm entry prefixes the command with dotenv pointed at .env, which is the same file the deployment instructions tell you to create by copying the example. So the migration path and the container path read configuration from a file that only exists after the first install step has been run by hand.
Editorial conclusion
Wiredoor fits operators who want to own the entry point rather than rent a hosted tunnel, and the parts that decide whether it works for you are unglamorous: whether your platform can run the node type you need, since gateway routing wants Linux iptables, and whether your OAuth2 identity provider matches what the example file assumes. Before deploying, change two things in the copied .env rather than none: the provider selection, which arrives set to google with both a client id and a client secret blank, and the two restriction lines, which arrive commented out with the email domain defaulting to a wildcard. Pin the release you install rather than tracking main, and remember that the manifest in this repository still reads 1.0.0 while the published tags are at v1.8.0, so version numbers in this tree will not tell you what you are running.
Frequently asked questions
What does Wiredoor do and what does it replace?
It is a self-hosted ingress platform for HTTP, TCP and UDP services on private networks. Nodes initiate encrypted WireGuard tunnels to Wiredoor Server, which terminates TLS and routes through NGINX, so services can stay behind NAT without accepting inbound connections.
Does Wiredoor require a public domain?
No. An internal DNS name or an entry in the hosts file on Linux, Windows or macOS is enough. Public domains are useful when the service needs a publicly trusted Let's Encrypt certificate, since local and internal domains get self-signed ones.
Can I run a Wiredoor gateway node on Windows or macOS?
Not natively. Gateway routing depends on Linux iptables rules, and native CLI installations on Windows and macOS support Client Node mode only. On those systems the documented path is the Wiredoor Docker Gateway running through Docker Desktop.
Which ports does Wiredoor Server need open?
TCP 80 and 443, plus UDP 51820 for the VPN unless another VPN port is configured. The server itself needs to be a reachable Linux machine with Docker Engine, Docker Compose and Git.
How is authentication configured in Wiredoor?
Through an oauth2-proxy style environment file. The example sets OAUTH2_PROXY_PROVIDER to google with an empty client id and client secret, and leaves OAUTH2_PROXY_ALLOWED_GROUPS and OAUTH2_PROXY_EMAIL_DOMAINS commented out, with the domain noted as a wildcard by default.
Which version of Wiredoor should I install?
Pin a published release rather than tracking the branch. The manifest in the repository still reads 1.0.0 while the release tags are at v1.8.0, and the server itself is deployed from a separate docker-setup repository with the CLI and Helm charts living in their own repositories.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/wiredoor-wiredoor)