fix(core): Refactor filesystem usage to smartfs async provider, update dependencies, tests and nginx config paths
This commit is contained in:
119
.gitlab-ci.yml
119
.gitlab-ci.yml
@@ -1,119 +0,0 @@
|
|||||||
# gitzone ci_default
|
|
||||||
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
|
||||||
|
|
||||||
cache:
|
|
||||||
paths:
|
|
||||||
- .npmci_cache/
|
|
||||||
key: "$CI_BUILD_STAGE"
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- security
|
|
||||||
- test
|
|
||||||
- release
|
|
||||||
- metadata
|
|
||||||
|
|
||||||
# ====================
|
|
||||||
# security stage
|
|
||||||
# ====================
|
|
||||||
mirror:
|
|
||||||
stage: security
|
|
||||||
script:
|
|
||||||
- npmci git mirror
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
snyk:
|
|
||||||
stage: security
|
|
||||||
script:
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci command npm install -g snyk
|
|
||||||
- npmci command npm install --ignore-scripts
|
|
||||||
- npmci command snyk test
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
# ====================
|
|
||||||
# test stage
|
|
||||||
# ====================
|
|
||||||
|
|
||||||
testLTS:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci node install lts
|
|
||||||
- npmci npm install
|
|
||||||
- npmci npm test
|
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- priv
|
|
||||||
|
|
||||||
testBuild:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci node install lts
|
|
||||||
- npmci npm install
|
|
||||||
- npmci command npm run build
|
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
release:
|
|
||||||
stage: release
|
|
||||||
script:
|
|
||||||
- npmci node install lts
|
|
||||||
- npmci npm publish
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
# ====================
|
|
||||||
# metadata stage
|
|
||||||
# ====================
|
|
||||||
codequality:
|
|
||||||
stage: metadata
|
|
||||||
allow_failure: true
|
|
||||||
script:
|
|
||||||
- npmci command npm install -g tslint typescript
|
|
||||||
- npmci npm install
|
|
||||||
- npmci command "tslint -c tslint.json ./ts/**/*.ts"
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- priv
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
stage: metadata
|
|
||||||
script:
|
|
||||||
- npmci trigger
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
pages:
|
|
||||||
image: hosttoday/ht-docker-dbase:npmci
|
|
||||||
services:
|
|
||||||
- docker:18-dind
|
|
||||||
stage: metadata
|
|
||||||
script:
|
|
||||||
- npmci command npm install -g @gitzone/tsdoc
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci npm install
|
|
||||||
- npmci command tsdoc
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
artifacts:
|
|
||||||
expire_in: 1 week
|
|
||||||
paths:
|
|
||||||
- public
|
|
||||||
allow_failure: true
|
|
||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2016 Lossless GmbH
|
Copyright (c) 2016 Task Venture Capital GmbH
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
59
changelog.md
Normal file
59
changelog.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-11-27 - 2.0.53 - fix(core)
|
||||||
|
Refactor filesystem usage to smartfs async provider, update dependencies, tests and nginx config paths
|
||||||
|
|
||||||
|
- Replace @push.rocks/smartfile usage with @push.rocks/smartfs and introduce a shared SmartFs instance in plugins
|
||||||
|
- Convert sync file operations to async fs APIs (plugins.fs.file(...).write / plugins.fs.directory(...).create) in SmartNginx and NginxHost
|
||||||
|
- Adjust package.json: update test/build scripts, replace dependencies/devDependencies to new packages (@push.rocks/smartfs, @git.zone/*), and update versions
|
||||||
|
- Update test imports to new tapbundle path and node:path; export default tap.start() and remove unused Qenv instantiation
|
||||||
|
- Update internal path imports to 'node:path' and refactor smartnginx.plugins exports
|
||||||
|
- Change generated nginx certificate/config paths in configs from /mnt/HC_Volume_11396573/... to /mnt/data/... and regenerate default cert files
|
||||||
|
- Remove CI config (.gitlab-ci.yml) from repository
|
||||||
|
|
||||||
|
## 2024-05-29 - 2.0.52 - maintenance
|
||||||
|
Various metadata and TypeScript configuration updates; release 2.0.52.
|
||||||
|
|
||||||
|
- Update package description.
|
||||||
|
- Update tsconfig.
|
||||||
|
- Update npmextra.json (githost) entries across multiple commits.
|
||||||
|
- Release tag for 2.0.52.
|
||||||
|
|
||||||
|
## 2023-07-26 - 2.0.51 - maintenance
|
||||||
|
Org migration and core fixes; release 2.0.51.
|
||||||
|
|
||||||
|
- Switch to new organization scheme.
|
||||||
|
- fix(core): miscellaneous updates.
|
||||||
|
- Release tag for 2.0.51.
|
||||||
|
|
||||||
|
## 2019-01-09..2019-08-20 - 2.0.19..2.0.50 - maintenance (multiple patch releases)
|
||||||
|
Series of incremental patch releases with small fixes and cleanups.
|
||||||
|
|
||||||
|
- Many patch releases across the 2.0.x line (2.0.19 through 2.0.50).
|
||||||
|
- Multiple "fix(core): update" commits addressing internal issues.
|
||||||
|
- CI and cleanup fixes (including 2.0.38 cleanup).
|
||||||
|
- Release tags for each patch.
|
||||||
|
|
||||||
|
## 2018-08-10 - 2.0.0 - breaking
|
||||||
|
Major release and scope / packaging changes.
|
||||||
|
|
||||||
|
- 2.0.0 release with core updates.
|
||||||
|
- BREAKING CHANGE: change scope to @pushrocks (package scope/name changed).
|
||||||
|
- Various CI and core fixes accompanying the major release.
|
||||||
|
|
||||||
|
## 2016-08-03..2016-07-25 - 1.0.6..1.0.0 - release / maintenance
|
||||||
|
1.x series consolidations, dependency updates and interface exports.
|
||||||
|
|
||||||
|
- Update dependencies and types.
|
||||||
|
- Consolidate naming and start exporting interfaces.
|
||||||
|
- Add license.
|
||||||
|
- Release tags for 1.0.0 through 1.0.6.
|
||||||
|
|
||||||
|
## 2016-07-06..2016-07-25 - 0.0.0..0.1.0 - initial development
|
||||||
|
Initial implementation and feature work establishing core functionality.
|
||||||
|
|
||||||
|
- Initial project setup, README and CI added.
|
||||||
|
- Implement nginx communication and child process handling.
|
||||||
|
- Start storing generated configs to filesystem and improve config handling.
|
||||||
|
- Add snippets support and tests; multiple README improvements.
|
||||||
|
- Early releases and version tags (0.0.0 through 0.1.0).
|
||||||
@@ -1,15 +1,27 @@
|
|||||||
-----BEGIN RSA PRIVATE KEY-----
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
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
|
||||||
-----END RSA PRIVATE KEY-----
|
-----END RSA PRIVATE KEY-----
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIB/zCCAWigAwIBAgIJH3Pl1mivagGCMA0GCSqGSIb3DQEBBQUAMB4xHDAaBgNV
|
MIIDBDCCAeygAwIBAgIJZid+XT7/NTaWMA0GCSqGSIb3DQEBBQUAMB4xHDAaBgNV
|
||||||
BAMTE3NlbGZzaWduZWQuZ2l0LnpvbmUwHhcNMjMwNzI2MTQwNTIwWhcNMjQwNzI1
|
BAMTE3NlbGZzaWduZWQuZ2l0LnpvbmUwHhcNMjUxMTI3MTMxMzM0WhcNMjYxMTI3
|
||||||
MTQwNTIwWjAeMRwwGgYDVQQDExNzZWxmc2lnbmVkLmdpdC56b25lMIGfMA0GCSqG
|
MTMxMzM0WjAeMRwwGgYDVQQDExNzZWxmc2lnbmVkLmdpdC56b25lMIIBIjANBgkq
|
||||||
SIb3DQEBAQUAA4GNADCBiQKBgQD5b6wtr4xHY5gxH0SR+V9XIQPH6DGe2PXlKWN0
|
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuO16Nu4tMkmBqsNWezt3ENqnsbWNUqC+
|
||||||
2dgvg7Ej/4uA7MmOnem2SUpWE2GwuKCAUCeZkj+riEmky0EWFexaM3BmcvWLSHZ6
|
curHyXURaoIH2wQ16DIZaBIbO/WndNisMy6TnxJtiMVbKGKjkRH4w3qegthIRCKL
|
||||||
MAYg5FxTsUG8IXxNYUdTPpUBxaCX/yp/dvpiDqSMH67y9LwI85oWHx/zk1jMixaZ
|
D3+Yl1ffqpHRz19hkNxVg4HfXRQMfH0Pnvd/4wB7g2mapk8SMwsTuEZ0j/7dAwc0
|
||||||
XvOCXwIDAQABo0UwQzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIC9DAmBgNVHREE
|
dqw94g+aehgZlvxUDFQjI/4kU9EiheDZ9TPREBMfeIb82zapINekKq5TkN/euWfs
|
||||||
HzAdhhtodHRwOi8vZXhhbXBsZS5vcmcvd2ViaWQjbWUwDQYJKoZIhvcNAQEFBQAD
|
fpbZZ6qWZvTX8NegulKOtDCCFauXKv2LNqy4jxWQef2XfMT8Jr4Txud3F8zqfexJ
|
||||||
gYEAQ0pJ279EDgvsY+YjslMdUaJbZcF9rFgUE3t8vDDZH99kth8gqNddahcLqEV2
|
Yq5ywjH07ecsyi7a/ifv7VLNXUEgwI6OFJHYnFZ314S6KlurocQUWQIDAQABo0Uw
|
||||||
8hyx7qcnplpKNVx8DYvDWoTGRdXBhCP/TBBW3jdsqaBHJey+yfAISBk4pbOow260
|
QzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIC9DAmBgNVHREEHzAdhhtodHRwOi8v
|
||||||
tNQngsMDf+PZQMLm2bT1Pxk2KXd0rFMkVWprcRs2qx3Yz0Q=
|
ZXhhbXBsZS5vcmcvd2ViaWQjbWUwDQYJKoZIhvcNAQEFBQADggEBAH3qUHaBnNn+
|
||||||
|
e1qlZ0gUooJlLXU5tLGR9cVFV1dKuE5yxZhT0qal4A6Vif1mGKYXmHC4q0/atNsQ
|
||||||
|
RBvrbpoVtJxWpb6iIh1L5WWeP5OxqeLwZ8gp2Qj67CkwmccjIS66kkpwHBkBmXU9
|
||||||
|
nRlmGOj9OBHczqE0cp4dW6pCVvRtzC+wTX9oqAdmjyD8S8oo8I2fjCL4pJTPQtbV
|
||||||
|
RlaryWxlxscXYArA7iE9A5Cl5DdJtkOKS48Rbfw3BEQpgL0J4VeF8Lbb+ryk6BbG
|
||||||
|
XXkkH570cIdTs588gdfhkS8T6NIl+1Aicqmf+v6j3MHrzyLK3SZTQ83hoCRAEMfW
|
||||||
|
SPkrHSeL6h8=
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ server {
|
|||||||
server {
|
server {
|
||||||
listen *:443 ssl;
|
listen *:443 ssl;
|
||||||
server_name test100.bleu.de;
|
server_name test100.bleu.de;
|
||||||
ssl_certificate /mnt/HC_Volume_11396573/lossless/push.rocks/smartnginx/nginxconfig/hosts/test100.bleu.de.public.pem;
|
ssl_certificate /mnt/data/lossless/push.rocks/smartnginx/nginxconfig/hosts/test100.bleu.de.public.pem;
|
||||||
ssl_certificate_key /mnt/HC_Volume_11396573/lossless/push.rocks/smartnginx/nginxconfig/hosts/test100.bleu.de.private.pem;
|
ssl_certificate_key /mnt/data/lossless/push.rocks/smartnginx/nginxconfig/hosts/test100.bleu.de.private.pem;
|
||||||
location / {
|
location / {
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ server {
|
|||||||
server {
|
server {
|
||||||
listen *:443 ssl;
|
listen *:443 ssl;
|
||||||
server_name test102.bleu.de;
|
server_name test102.bleu.de;
|
||||||
ssl_certificate /mnt/HC_Volume_11396573/lossless/push.rocks/smartnginx/nginxconfig/hosts/test102.bleu.de.public.pem;
|
ssl_certificate /mnt/data/lossless/push.rocks/smartnginx/nginxconfig/hosts/test102.bleu.de.public.pem;
|
||||||
ssl_certificate_key /mnt/HC_Volume_11396573/lossless/push.rocks/smartnginx/nginxconfig/hosts/test102.bleu.de.private.pem;
|
ssl_certificate_key /mnt/data/lossless/push.rocks/smartnginx/nginxconfig/hosts/test102.bleu.de.private.pem;
|
||||||
location / {
|
location / {
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
|
|||||||
@@ -68,12 +68,12 @@ http {
|
|||||||
server {
|
server {
|
||||||
listen *:443 ssl default_server;
|
listen *:443 ssl default_server;
|
||||||
server_name selfsigned.git.zone;
|
server_name selfsigned.git.zone;
|
||||||
ssl_certificate /mnt/HC_Volume_11396573/lossless/push.rocks/smartnginx/nginxconfig/hosts/default.public.pem;
|
ssl_certificate /mnt/data/lossless/push.rocks/smartnginx/nginxconfig/hosts/default.public.pem;
|
||||||
ssl_certificate_key /mnt/HC_Volume_11396573/lossless/push.rocks/smartnginx/nginxconfig/hosts/default.private.pem;
|
ssl_certificate_key /mnt/data/lossless/push.rocks/smartnginx/nginxconfig/hosts/default.private.pem;
|
||||||
rewrite ^ https://git.zone redirect;
|
rewrite ^ https://git.zone redirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
include /mnt/HC_Volume_11396573/lossless/push.rocks/smartnginx/nginxconfig/hosts/*.conf;
|
include /mnt/data/lossless/push.rocks/smartnginx/nginxconfig/hosts/*.conf;
|
||||||
include /etc/nginx/sites-enabled/*;
|
include /etc/nginx/sites-enabled/*;
|
||||||
}
|
}
|
||||||
daemon off;
|
daemon off;
|
||||||
|
|||||||
31
package.json
31
package.json
@@ -6,9 +6,9 @@
|
|||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
"typings": "dist_ts/index.d.ts",
|
"typings": "dist_ts/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "tstest test/",
|
"test": "tstest test/ --verbose",
|
||||||
"cleanTest": "(rm -r nginxconfig) && npm run test",
|
"cleanTest": "(rm -r nginxconfig) && npm run test",
|
||||||
"build": "(tsbuild --allowimplicitany)"
|
"build": "(tsbuild tsfolders --allowimplicitany)"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -30,22 +30,21 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://code.foss.global/push.rocks/smartnginx",
|
"homepage": "https://code.foss.global/push.rocks/smartnginx",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@push.rocks/lik": "^6.0.2",
|
"@push.rocks/lik": "^6.2.2",
|
||||||
"@push.rocks/smartfile": "^10.0.26",
|
"@push.rocks/smartfs": "^1.1.0",
|
||||||
"@push.rocks/smartlog": "^3.0.2",
|
"@push.rocks/smartlog": "^3.1.10",
|
||||||
"@push.rocks/smartpath": "^5.0.11",
|
"@push.rocks/smartpath": "^6.0.0",
|
||||||
"@push.rocks/smartpromise": "^4.0.2",
|
"@push.rocks/smartpromise": "^4.2.3",
|
||||||
"@push.rocks/smartshell": "^3.0.3",
|
"@push.rocks/smartshell": "^3.3.0",
|
||||||
"@push.rocks/smartstring": "^4.0.7",
|
"@push.rocks/smartstring": "^4.1.0",
|
||||||
"@push.rocks/smartunique": "^3.0.3",
|
"@push.rocks/smartunique": "^3.0.9",
|
||||||
"selfsigned": "^2.1.1"
|
"selfsigned": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@gitzone/tsbuild": "^2.1.66",
|
"@git.zone/tsbuild": "^3.1.0",
|
||||||
"@gitzone/tsrun": "^1.2.44",
|
"@git.zone/tsrun": "^2.0.0",
|
||||||
"@gitzone/tstest": "^1.0.77",
|
"@git.zone/tstest": "^3.1.3",
|
||||||
"@push.rocks/qenv": "^5.0.2",
|
"@push.rocks/qenv": "^6.1.3"
|
||||||
"@push.rocks/tapbundle": "^5.0.8"
|
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts/**/*",
|
"ts/**/*",
|
||||||
|
|||||||
11286
pnpm-lock.yaml
generated
11286
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
266
readme.md
266
readme.md
@@ -1,77 +1,251 @@
|
|||||||
# @push.rocks/smartnginx
|
# @push.rocks/smartnginx
|
||||||
control nginx from node, TypeScript ready
|
|
||||||
|
Control Nginx programmatically from Node.js with full TypeScript support 🚀
|
||||||
|
|
||||||
|
## Issue Reporting and Security
|
||||||
|
|
||||||
|
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- 🎯 **Dynamic Configuration** - Generate and manage Nginx configs on the fly
|
||||||
|
- 🔒 **SSL/TLS Ready** - Built-in support for SSL certificates with automatic HTTP→HTTPS redirects
|
||||||
|
- 🔄 **Hot Reload** - Apply configuration changes without downtime
|
||||||
|
- 📦 **Zero-Config Defaults** - Self-signed certificates auto-generated for immediate testing
|
||||||
|
- 🎛️ **Reverse Proxy Made Easy** - Set up proxy hosts with a single method call
|
||||||
|
- 🧠 **Smart Diffing** - Only reloads Nginx when configurations actually change
|
||||||
|
- 📝 **TypeScript First** - Full type definitions included
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
To install `@push.rocks/smartnginx`, you can use npm (Node Package Manager). Open your terminal and run:
|
|
||||||
```bash
|
```bash
|
||||||
npm install @push.rocks/smartnginx --save
|
pnpm add @push.rocks/smartnginx
|
||||||
|
# or
|
||||||
|
npm install @push.rocks/smartnginx
|
||||||
```
|
```
|
||||||
This will download and install `@push.rocks/smartnginx` and its dependencies into your project's `node_modules` folder and save it as a dependency in your project's `package.json` file.
|
|
||||||
|
> **Prerequisites**: Nginx must be installed and available in your system PATH.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { SmartNginx } from '@push.rocks/smartnginx';
|
||||||
|
|
||||||
|
// Create a SmartNginx instance with a default fallback URL
|
||||||
|
const nginx = new SmartNginx({
|
||||||
|
defaultProxyUrl: 'https://your-default-site.com'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add a reverse proxy host
|
||||||
|
nginx.addHostCandidate({
|
||||||
|
hostName: 'api.example.com',
|
||||||
|
destination: 'localhost',
|
||||||
|
destinationPort: 3000,
|
||||||
|
privateKey: '<your-ssl-private-key>',
|
||||||
|
publicKey: '<your-ssl-certificate>'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Deploy and start Nginx
|
||||||
|
await nginx.deploy();
|
||||||
|
```
|
||||||
|
|
||||||
|
That's it! Your reverse proxy is now running 🎉
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
`@push.rocks/smartnginx` is a powerful library for interacting with Nginx programmatically using Node.js and TypeScript. It simplifies tasks such as configuring hosts, deploying configurations, and managing SSL certificates. Below is a comprehensive guide to using the library effectively in your TypeScript projects.
|
|
||||||
|
|
||||||
### Getting Started
|
### Creating the SmartNginx Instance
|
||||||
First, ensure you have imported the library into your TypeScript file. Use ESM syntax as shown:
|
|
||||||
```typescript
|
The `SmartNginx` class is your main interface for managing Nginx:
|
||||||
import { SmartNginx, NginxHost } from '@push.rocks/smartnginx';
|
|
||||||
```
|
|
||||||
|
|
||||||
### Initialize SmartNginx
|
|
||||||
Before you interact with Nginx, you need to create an instance of `SmartNginx`. This object acts as the main interface to your Nginx server. You can specify a default proxy URL that requests will be redirected to if no matching host is found.
|
|
||||||
```typescript
|
```typescript
|
||||||
const smartNginx = new SmartNginx({
|
import { SmartNginx } from '@push.rocks/smartnginx';
|
||||||
defaultProxyUrl: 'https://your-default-url.com'
|
|
||||||
|
const nginx = new SmartNginx({
|
||||||
|
defaultProxyUrl: 'https://fallback.example.com', // Where unmatched requests go
|
||||||
|
logger: myCustomLogger // Optional: pass a @push.rocks/smartlog instance
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Add Host Candidates
|
### Adding Host Configurations
|
||||||
To serve content or applications via Nginx, you will define hosts. Each host corresponds to a domain or subdomain and can be configured with specific rules. Here's how to add host candidates:
|
|
||||||
|
Each host represents a domain/subdomain with its proxy rules and SSL certificates:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
const myHost = smartNginx.addHostCandidate({
|
// Add a host using addHostCandidate()
|
||||||
hostName: 'example.com',
|
const myHost = nginx.addHostCandidate({
|
||||||
|
hostName: 'app.example.com', // Domain name
|
||||||
|
destination: '127.0.0.1', // Backend server address
|
||||||
|
destinationPort: 8080, // Backend port
|
||||||
|
privateKey: sslPrivateKeyPem, // SSL private key (PEM format)
|
||||||
|
publicKey: sslCertificatePem // SSL certificate (PEM format)
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Host Setup
|
||||||
|
|
||||||
|
Run multiple sites through a single Nginx instance:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Production API
|
||||||
|
nginx.addHostCandidate({
|
||||||
|
hostName: 'api.myapp.com',
|
||||||
destination: 'localhost',
|
destination: 'localhost',
|
||||||
|
destinationPort: 3000,
|
||||||
|
privateKey: apiPrivateKey,
|
||||||
|
publicKey: apiCertificate
|
||||||
|
});
|
||||||
|
|
||||||
|
// Admin panel
|
||||||
|
nginx.addHostCandidate({
|
||||||
|
hostName: 'admin.myapp.com',
|
||||||
|
destination: 'localhost',
|
||||||
|
destinationPort: 4000,
|
||||||
|
privateKey: adminPrivateKey,
|
||||||
|
publicKey: adminCertificate
|
||||||
|
});
|
||||||
|
|
||||||
|
// Staging environment
|
||||||
|
nginx.addHostCandidate({
|
||||||
|
hostName: 'staging.myapp.com',
|
||||||
|
destination: '192.168.1.100',
|
||||||
destinationPort: 8080,
|
destinationPort: 8080,
|
||||||
privateKey: '<Your SSL Private Key>',
|
privateKey: stagingPrivateKey,
|
||||||
publicKey: '<Your SSL Public Key>'
|
publicKey: stagingCertificate
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Deploy all at once
|
||||||
|
await nginx.deploy();
|
||||||
```
|
```
|
||||||
Replace `'example.com'`, `'localhost'`, `8080`, `'<Your SSL Private Key>'`, and `'<Your SSL Public Key>'` with your actual host name, destination IP or hostname, port number, and SSL keys respectively.
|
|
||||||
|
|
||||||
### Deploying Configuration
|
### Deploying Configurations
|
||||||
After adding all your host candidates, you will need to apply these configurations for Nginx to recognize and use them. Deploy the configuration as follows:
|
|
||||||
|
The `deploy()` method is smart about changes:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
await smartNginx.deploy();
|
// First deploy - writes configs and starts Nginx
|
||||||
```
|
await nginx.deploy();
|
||||||
This method checks for any changes in your host configurations compared to what's currently deployed and updates the Nginx configuration accordingly.
|
|
||||||
|
|
||||||
### Managing SSL Certificates
|
// Add more hosts dynamically
|
||||||
When setting up SSL for your hosts, you will provide the paths to the private key and public certificate. It's essential to ensure these files are securely stored and accessible by the library during deployment.
|
nginx.addHostCandidate({
|
||||||
|
hostName: 'newsite.example.com',
|
||||||
### Handling Multiple Hosts
|
|
||||||
You can add multiple host candidates using `addHostCandidate` method for different domains or subdomains, each with unique configurations. Here's an example of adding another host:
|
|
||||||
```typescript
|
|
||||||
const anotherHost = smartNginx.addHostCandidate({
|
|
||||||
hostName: 'sub.example.com',
|
|
||||||
destination: 'localhost',
|
destination: 'localhost',
|
||||||
destinationPort: 9090,
|
destinationPort: 5000,
|
||||||
privateKey: '<Another SSL Private Key>',
|
privateKey: newPrivateKey,
|
||||||
publicKey: '<Another SSL Public Key>'
|
publicKey: newCertificate
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Second deploy - detects changes, updates configs, hot-reloads Nginx
|
||||||
|
await nginx.deploy();
|
||||||
|
|
||||||
|
// If you call deploy() with no changes, it skips the reload (efficient!)
|
||||||
|
await nginx.deploy(); // → "hosts have not diverged, skipping nginx reload"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Reloading Configurations
|
### Querying Deployed Hosts
|
||||||
If at any time you make changes to your host configurations and need to apply these changes, simply call the `deploy` method again. `@push.rocks/smartnginx` efficiently detects changes and reloads Nginx with the new configurations.
|
|
||||||
|
|
||||||
### Stopping SmartNginx
|
|
||||||
To stop the Nginx process managed by `@push.rocks/smartnginx`, use:
|
|
||||||
```typescript
|
```typescript
|
||||||
await smartNginx.stop();
|
// Get all deployed hosts
|
||||||
```
|
const hosts = await nginx.listDeployedHosts();
|
||||||
Bear in mind that this might affect your web services if they rely on the Nginx instance you are stopping.
|
console.log(`Running ${hosts.length} hosts`);
|
||||||
|
|
||||||
### Conclusion
|
// Find a specific host by domain
|
||||||
`@push.rocks/smartnginx` abstracts away much of the complexity involved in managing Nginx configurations, offering a TypeScript-ready solution for Node.js projects. With simple method calls, you can automate and manage your Nginx server programmatically, making it an excellent tool for developers seeking to integrate Nginx management into their applications or deployment workflows.
|
const apiHost = nginx.getDeployedNginxHostByHostName('api.example.com');
|
||||||
|
if (apiHost) {
|
||||||
|
console.log(`API proxying to ${apiHost.destination}:${apiHost.destinationPort}`);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Removing Hosts
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const hostToRemove = nginx.getDeployedNginxHostByHostName('staging.myapp.com');
|
||||||
|
if (hostToRemove) {
|
||||||
|
await nginx.removeDeployedHost(hostToRemove);
|
||||||
|
// Nginx automatically reloaded with updated config
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stopping Nginx
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Gracefully stop the Nginx process
|
||||||
|
await nginx.stop();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Generated Configuration
|
||||||
|
|
||||||
|
SmartNginx generates production-ready Nginx configurations:
|
||||||
|
|
||||||
|
**For each host, you get:**
|
||||||
|
- HTTP (port 80) → HTTPS (port 443) automatic redirect
|
||||||
|
- Upstream with keepalive connections (100 idle connections)
|
||||||
|
- WebSocket-friendly proxy settings (HTTP/1.1, no buffering)
|
||||||
|
- Proper proxy headers (`X-Real-IP`, `X-Forwarded-For`, `X-Forwarded-Proto`)
|
||||||
|
- Smart failover (`proxy_next_upstream` on errors, timeouts, 404/429/500/502)
|
||||||
|
|
||||||
|
**Default server:**
|
||||||
|
- Self-signed certificate for unmatched domains
|
||||||
|
- Redirects to your configured `defaultProxyUrl`
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ SmartNginx │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ hostCandidates[] → deploy() → deployedHosts[] │
|
||||||
|
│ ↓ │
|
||||||
|
│ NginxProcess │
|
||||||
|
│ (start/reload/stop) │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Generated Files │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ nginxconfig/ │
|
||||||
|
│ ├── nginx.conf (main config) │
|
||||||
|
│ └── hosts/ │
|
||||||
|
│ ├── default.private.pem (self-signed key) │
|
||||||
|
│ ├── default.public.pem (self-signed cert) │
|
||||||
|
│ ├── api.example.com.conf │
|
||||||
|
│ ├── api.example.com.private.pem │
|
||||||
|
│ └── api.example.com.public.pem │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
### SmartNginx
|
||||||
|
|
||||||
|
| Method | Description |
|
||||||
|
|--------|-------------|
|
||||||
|
| `addHostCandidate(config)` | Add a new host configuration |
|
||||||
|
| `deploy()` | Write configs and start/reload Nginx |
|
||||||
|
| `listDeployedHosts()` | Get all currently deployed hosts |
|
||||||
|
| `getDeployedNginxHostByHostName(hostname)` | Find a host by domain name |
|
||||||
|
| `removeDeployedHost(host)` | Remove a host and reload Nginx |
|
||||||
|
| `stop()` | Gracefully stop Nginx |
|
||||||
|
|
||||||
|
### IHostConfig
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface IHostConfig {
|
||||||
|
hostName: string; // Domain name (e.g., 'api.example.com')
|
||||||
|
destination: string; // Backend server IP/hostname
|
||||||
|
destinationPort: number; // Backend port
|
||||||
|
privateKey: string; // SSL private key (PEM)
|
||||||
|
publicKey: string; // SSL certificate (PEM)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### NginxHost
|
||||||
|
|
||||||
|
Each host instance exposes:
|
||||||
|
- `hostName` - The configured domain
|
||||||
|
- `destination` - Backend address
|
||||||
|
- `destinationPort` - Backend port
|
||||||
|
- `configString` - The generated Nginx config (after deploy)
|
||||||
|
- `deploy()` - Write this host's config files
|
||||||
|
|
||||||
## License and Legal Information
|
## License and Legal Information
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { tap, expect } from '@push.rocks/tapbundle';
|
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
||||||
import path = require('path');
|
import * as path from 'node:path';
|
||||||
|
|
||||||
import { Qenv } from '@push.rocks/qenv';
|
import { Qenv } from '@push.rocks/qenv';
|
||||||
const testQenv = new Qenv('./', './.nogit/');
|
|
||||||
|
|
||||||
import * as smartnginx from '../ts/index.js';
|
import * as smartnginx from '../ts/index.js';
|
||||||
|
|
||||||
@@ -52,4 +51,4 @@ tap.test('.stop() should end the process', async () => {
|
|||||||
testSmartNginx.nginxProcess.stop();
|
testSmartNginx.nginxProcess.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.start();
|
export default tap.start();
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* autocreated commitinfo by @pushrocks/commitinfo
|
* autocreated commitinfo by @push.rocks/commitinfo
|
||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@push.rocks/smartnginx',
|
name: '@push.rocks/smartnginx',
|
||||||
version: '2.0.52',
|
version: '2.0.53',
|
||||||
description: 'control nginx from node, TypeScript ready'
|
description: 'A TypeScript library for controlling Nginx from Node.js, with support for generating and managing Nginx configurations dynamically.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,10 +53,10 @@ export class NginxHost implements IHostConfig {
|
|||||||
this.destination,
|
this.destination,
|
||||||
this.destinationPort
|
this.destinationPort
|
||||||
);
|
);
|
||||||
plugins.smartfile.memory.toFsSync(this.configString, filePathConfig);
|
await plugins.fs.file(filePathConfig).write(this.configString);
|
||||||
|
|
||||||
// write ssl
|
// write ssl
|
||||||
plugins.smartfile.memory.toFsSync(this.privateKey, filePathPrivate);
|
await plugins.fs.file(filePathPrivate).write(this.privateKey);
|
||||||
plugins.smartfile.memory.toFsSync(this.publicKey, filePathPublic);
|
await plugins.fs.file(filePathPublic).write(this.publicKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,10 +116,9 @@ export class SmartNginx {
|
|||||||
this.hostCandidates.wipe();
|
this.hostCandidates.wipe();
|
||||||
|
|
||||||
// write base config
|
// write base config
|
||||||
plugins.smartfile.fs.ensureDirSync(paths.nginxConfigDirPath);
|
await plugins.fs.directory(paths.nginxConfigDirPath).recursive().create();
|
||||||
plugins.smartfile.memory.toFsSync(
|
await plugins.fs.file(paths.nginxConfFile).write(
|
||||||
snippets.getBaseConfigString(this.options.defaultProxyUrl),
|
snippets.getBaseConfigString(this.options.defaultProxyUrl)
|
||||||
paths.nginxConfFile
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// write standard self signed certificate
|
// write standard self signed certificate
|
||||||
@@ -129,15 +128,13 @@ export class SmartNginx {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// deploy hosts
|
// deploy hosts
|
||||||
plugins.smartfile.fs.ensureDirSync(paths.nginxHostDirPath);
|
await plugins.fs.directory(paths.nginxHostDirPath).recursive().create();
|
||||||
plugins.smartfile.memory.toFsSync(
|
await plugins.fs.file(
|
||||||
selfsignedCert.private,
|
|
||||||
plugins.path.join(paths.nginxHostDirPath, './default.private.pem')
|
plugins.path.join(paths.nginxHostDirPath, './default.private.pem')
|
||||||
);
|
).write(selfsignedCert.private);
|
||||||
plugins.smartfile.memory.toFsSync(
|
await plugins.fs.file(
|
||||||
selfsignedCert.cert,
|
|
||||||
plugins.path.join(paths.nginxHostDirPath, './default.public.pem')
|
plugins.path.join(paths.nginxHostDirPath, './default.public.pem')
|
||||||
);
|
).write(selfsignedCert.cert);
|
||||||
for (const host of this.deployedHosts.getArray()) {
|
for (const host of this.deployedHosts.getArray()) {
|
||||||
await host.deploy();
|
await host.deploy();
|
||||||
this.logger.log('info', `Host ${host.hostName} deployed!`);
|
this.logger.log('info', `Host ${host.hostName} deployed!`);
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
// native
|
// native
|
||||||
import * as path from 'path';
|
import * as path from 'node:path';
|
||||||
|
|
||||||
export { path };
|
export { path };
|
||||||
|
|
||||||
// @pushrocks scope
|
// @push.rocks scope
|
||||||
import * as lik from '@push.rocks/lik';
|
import * as lik from '@push.rocks/lik';
|
||||||
import * as smartfile from '@push.rocks/smartfile';
|
import * as smartfs from '@push.rocks/smartfs';
|
||||||
import * as smartlog from '@push.rocks/smartlog';
|
import * as smartlog from '@push.rocks/smartlog';
|
||||||
import * as smartpath from '@push.rocks/smartpath';
|
import * as smartpath from '@push.rocks/smartpath';
|
||||||
import * as smartpromise from '@push.rocks/smartpromise';
|
import * as smartpromise from '@push.rocks/smartpromise';
|
||||||
import * as smartshell from '@push.rocks/smartshell';
|
import * as smartshell from '@push.rocks/smartshell';
|
||||||
import * as smartstring from '@push.rocks/smartstring';
|
import * as smartstring from '@push.rocks/smartstring';
|
||||||
import * as smartunique from '@push.rocks/smartunique';
|
import * as smartunique from '@push.rocks/smartunique';
|
||||||
|
|
||||||
export { lik, smartfile, smartlog, smartpath, smartpromise, smartshell, smartstring, smartunique };
|
export { lik, smartfs, smartlog, smartpath, smartpromise, smartshell, smartstring, smartunique };
|
||||||
|
|
||||||
|
// Shared filesystem instance
|
||||||
|
const fsProvider = new smartfs.SmartFsProviderNode();
|
||||||
|
export const fs = new smartfs.SmartFs(fsProvider);
|
||||||
|
|
||||||
// thirdparty scope
|
// thirdparty scope
|
||||||
import * as selfsigned from 'selfsigned';
|
import * as selfsigned from 'selfsigned';
|
||||||
|
|||||||
Reference in New Issue
Block a user