Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
14605c1
refactor: mkdirTemp
ZorTik Apr 19, 2026
4173361
refactor: better error logging & remove unused function
ZorTik May 8, 2026
f361f89
refactor: prettify
ZorTik May 10, 2026
701fe96
refactor(compose): dev environment
ZorTik Jun 10, 2026
30ec614
refactor: stop flow (use stop cmd if present)
ZorTik Jun 10, 2026
655fc2e
fix: test env in gh actions
ZorTik Jun 11, 2026
2f85ae9
fix: test env in gh actions
ZorTik Jun 11, 2026
77374bf
fix: test env in gh actions
ZorTik Jun 11, 2026
36311cd
feat: Makefile, fix tests
ZorTik Jun 11, 2026
7b863e1
feat: Makefile
ZorTik Jun 11, 2026
0ca3780
feat: dind for dev environment
ZorTik Jun 11, 2026
483bee6
feat: delete db migrate from Dockerfile cmd
ZorTik Jun 11, 2026
2156b18
fix: tests
ZorTik Jun 11, 2026
a1d74c7
todo
ZorTik Jun 11, 2026
b3fbf53
fix: reboot
ZorTik Jun 11, 2026
741ee73
feat: openapi force param in reboot route
ZorTik Jun 11, 2026
011d240
feat: refactor http handling & parseModel
ZorTik Jun 11, 2026
334bdb1
feat: synchronout actions processing in routes
ZorTik Jun 12, 2026
e377fd7
fix: express version
ZorTik Jun 12, 2026
fde8779
fix: global error handling
ZorTik Jun 12, 2026
cee5076
fix: reboot endpoint
ZorTik Jun 12, 2026
88ecf52
feat: fixes
ZorTik Jun 12, 2026
91faed0
feat: STOPPING state
ZorTik Jun 12, 2026
aaf97ca
refactor: ServiceManager
ZorTik Jun 13, 2026
7bc4ebf
refactor: ServiceManager
ZorTik Jun 13, 2026
a7e29d8
feat: remove stop cmd route
ZorTik Jun 14, 2026
4c999a9
refactor: 1.2
ZorTik Jun 14, 2026
14671f3
feat: tighten ServiceActionType in middle
ZorTik Jun 14, 2026
e60b3ff
refactor
ZorTik Jun 14, 2026
3c6d9e7
feat: stop strategy
ZorTik Jun 15, 2026
5eb0573
refactor
ZorTik Jun 15, 2026
d481bfe
fix
ZorTik Jun 15, 2026
cb85d65
refactor: extract prepareEnvForTemplate from TemplateManager
ZorTik Jun 15, 2026
4d168df
feat: nested env config filling
ZorTik Jun 15, 2026
93987c1
feat: new template system
ZorTik Jun 15, 2026
22249c7
feat: template list route
ZorTik Jun 15, 2026
3f2c1b8
feat: remove old test resources logic
ZorTik Jun 15, 2026
0ca0e6f
refactor: few method markups
ZorTik Jun 15, 2026
7494695
feat: update zod to 4.4.3, rename input options from env to args
ZorTik Jun 15, 2026
f8cd2c3
feat: replace env column with args column in perma
ZorTik Jun 15, 2026
e01769c
refactor: move networking folder to docker module
ZorTik Jun 15, 2026
391c094
fix: recalculate hash of template if has not been recalculated yet an…
ZorTik Jun 15, 2026
21a8b0e
fix: demux out stream from docker container logs
ZorTik Jun 15, 2026
727f77b
feat: minecraft dev template
ZorTik Jun 15, 2026
5b5bc1c
fix: throw error if service not found
ZorTik Jun 15, 2026
dc35ed0
fix
ZorTik Jun 15, 2026
3ad7984
fix
ZorTik Jun 15, 2026
d696f37
feat: optional immediate resume after create
ZorTik Jun 16, 2026
123501e
feat: container runtime preprocessing
ZorTik Jun 16, 2026
72df975
fix
ZorTik Jun 16, 2026
ca699e7
feat: repositories, better engine logging, ...
ZorTik Jun 16, 2026
bf5f30d
feat: validate docker repository config, refactor
ZorTik Jun 17, 2026
be9c47b
feat: todo
ZorTik Jul 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions .github/workflows/jest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ jobs:
test:
runs-on: ubuntu-latest
env:
DATABASE_URL: 'mysql://test:test@localhost:3306/test'
CONFIG_DOCKER_HOST: '///var/run/docker.sock'
DEBUG: 'true'
DATABASE_URL: "mysql://test:test@localhost:3306/test"
CONFIG_DOCKER_HOST: "///var/run/docker.sock"
CONFIG_RESOURCES_PATH: "./resources"
DEBUG: "true"
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -26,14 +27,20 @@ jobs:
echo "This PR is from the dev branch. Exiting..."
exit 0
fi
- name: Prepare resources folder for tests
run: |
# Create test template folder
mkdir -p ./resources/templates/test
# Copy test template files to the resources folder
cp -r ./dev/templates/test/* ./resources/templates/test/
- name: Shutdown default MySQL
run: sudo service mysql stop
- name: Setup MySQL
uses: mirromutth/mysql-action@v1.1
with:
mysql database: 'test'
mysql user: 'test'
mysql password: 'test'
mysql database: "test"
mysql user: "test"
mysql password: "test"
- name: Install Node.js
uses: actions/setup-node@v6
with:
Expand All @@ -48,4 +55,4 @@ jobs:
run: npm test
- name: Publish Test Summary Results
run: npx github-actions-ctrf ctrf/ctrf-report.json
if: always()
if: always()
12 changes: 6 additions & 6 deletions .github/workflows/push-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
workflow_dispatch:
inputs:
tag:
description: 'Tag to use for the image (optional, defaults to branch name and short SHA)'
description: "Tag to use for the image (optional, defaults to branch name and short SHA)"
required: false

jobs:
Expand All @@ -30,20 +30,20 @@ jobs:
run: |
IMAGE_OWNER=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
IMAGE_NAME=ghcr.io/$IMAGE_OWNER/node-server-manager

if [ "${{ github.event_name }}" = "release" ]; then
TAG=${{ github.event.release.tag_name }}
echo "IS_RELEASE=true" >> $GITHUB_ENV

elif [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ github.event.inputs.tag }}" ]; then
TAG=${{ github.event.inputs.tag }}
echo "IS_RELEASE=true" >> $GITHUB_ENV

else
TAG=${GITHUB_REF_NAME}-$(echo $GITHUB_SHA | cut -c1-7)
echo "IS_RELEASE=false" >> $GITHUB_ENV
fi

echo "IMAGE_NAME=$IMAGE_NAME" >> $GITHUB_ENV
echo "IMAGE_TAG=$TAG" >> $GITHUB_ENV

Expand All @@ -66,4 +66,4 @@ jobs:
if: env.IS_RELEASE == 'true'
run: |
docker tag $IMAGE_NAME:$IMAGE_TAG $IMAGE_NAME:latest
docker push $IMAGE_NAME:latest
docker push $IMAGE_NAME:latest
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ dist
.pnp.*

# Other
templates
volumes

# Exclude all addons except the example one
Expand Down
5 changes: 5 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Ignore artifacts:
build
coverage
dev
resources
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
6 changes: 1 addition & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ FROM node:22

WORKDIR /data

# Copy addons before install to install dependencies for addons as well
COPY addons ./addons

COPY installTempDeps.js ./
COPY package*.json ./
RUN npm install

Expand All @@ -23,4 +19,4 @@ COPY index.ts ./

RUN npm run build

CMD npx prisma migrate deploy && npm run start
CMD npm start
34 changes: 34 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.PHONY: build test up down restart logs shell ps

ATTACH ?= 0

all: build

build:
docker compose build

test:
ifeq ($(ATTACH),1) # if ATTACH=1, run tests with debugger attached
docker compose run --rm -p 9229:9229 nsm \
sh -c 'npm run migrate && node --inspect-brk=0.0.0.0:9229 ./node_modules/.bin/jest --runInBand $(ARGS)'
else
docker compose run --rm nsm npm run test $(ARGS)
endif

up:
docker compose up -d

down:
docker compose down

restart:
docker compose restart

logs:
docker compose logs -f

shell:
docker compose exec nsm sh

ps:
docker compose ps
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ NSM is a robust service manager built on Docker Engine. Its primary purpose is t
- **Resources usage management**: NSM provides ability to limit or extend resources limits and view current usage.

## API Specification

<a href="https://zortik.github.io/nsm-spec/" target="_blank">Specification is hosted on external repository here</a>

## Prerequisites
Expand All @@ -27,35 +28,42 @@ Ensure you have the following installed before proceeding with the installation:
Follow these steps to install and set up NSM:

1. **Clone the Repository**

```sh
git clone https://github.com/ZorTik/node-server-manager
```

Alternatively, download the latest release from the [NSM repository](https://github.com/ZorTik/node-server-manager) and extract it.

2. **Configure Environment Variables**
Copy the example environment file and fill in the required values:

```sh
cp .env.example .env
```

Open the `.env` file and provide the necessary configuration values.

3. **Edit Configuration**
Adjust the default configuration settings in `resources/config.yml` according to your requirements. You can also override these settings using environment variables. Detailed information about each configuration option is available within the file.

4. **Install Dependencies**
Install the required Node.js packages:

```sh
npm install
```

5. **Generate Prisma Client**
Generate the Prisma client for database interaction:

```sh
npx prisma generate
```

6. **Sync Database Schema**
Apply the database schema migrations:

```sh
npx prisma migrate deploy
```
Expand Down
14 changes: 0 additions & 14 deletions addons/example_addon/index.ts

This file was deleted.

1 change: 0 additions & 1 deletion addons/example_addon/libraries.txt

This file was deleted.

10 changes: 5 additions & 5 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
'@babel/preset-typescript',
],
};
presets: [
["@babel/preset-env", { targets: { node: "current" } }],
"@babel/preset-typescript",
],
};
45 changes: 45 additions & 0 deletions dev/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# All values here can be overwritten by environment variables
# with CONFIG_<key> format.

# ID of this node. Should be unique.
node_id: "main"
# Listen port.
port: 3000
# Security
# Supported types: 'none', 'auth_token'
auth: "none"
docker_host: "unix:///var/run/docker.sock"
# Override resources path if needed.
# By default, an explicit system-specific data path is used.
# resources_path: '/srv/resources'
repositories:
- id: local
type: filesystem
- id: dockerhub
type: docker-registry
puller:
registry: "https://index.docker.io/v1/"
# optional auth config
# auth:
# username: "your_username"
# password: "your_password"
templates:
- id: redis
image: "redis:latest"
name: "Redis"
description: "Redis template"
config:
port_range:
min: 22222
max: 33333
meta: { }
# Args, and their default values
args: { }
container:
# TODO: port mappings with variables resolving
env: { }
resources:
limits:
ram: 512000000
cpu: 2
disk: 2000000000
6 changes: 6 additions & 0 deletions dev/templates/minecraft/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM itzg/minecraft-server

# Optional ones. From build-stage.yml

# port1 port2 port3
EXPOSE $SERVICE_PORTS
2 changes: 2 additions & 0 deletions dev/templates/minecraft/build-stage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Build stage args to inject. Use ${} placeholders for args passed in settings.yml.
buildargs: {}
21 changes: 21 additions & 0 deletions dev/templates/minecraft/settings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: "Minecraft"
description: "Minecraft template"
port_range:
min: 22222
max: 33333
meta:
internal/stop-command: "stop"
# Args, and their default values
args:
eula: "TRUE"
version: "1.20.4"
container:
env:
EULA: "${args.eula}"
SERVER_PORT: "${service.port}"
VERSION: "${args.version}"
resources:
limits:
ram: 4096000000
cpu: 2
disk: 2000000000
File renamed without changes.
6 changes: 6 additions & 0 deletions dev/templates/nginx/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM nginx

# Optional ones. From build-stage.yml

# port1 port2 port3
EXPOSE $SERVICE_PORTS
2 changes: 2 additions & 0 deletions dev/templates/nginx/build-stage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Build stage args to inject. Use ${} placeholders for args passed in settings.yml.
buildargs: {}
15 changes: 15 additions & 0 deletions dev/templates/nginx/settings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: "Nginx"
description: "Nginx template"
port_range:
min: 22222
max: 33333
meta: {}
# Args, and their default values
args: {}
container:
env: {}
resources:
limits:
ram: 512000000
cpu: 2
disk: 2000000000
2 changes: 2 additions & 0 deletions dev/templates/test/.nsmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Define list of ignored files & directories to NOT include in the container,
# as you would do in .gitignore
9 changes: 9 additions & 0 deletions dev/templates/test/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM busybox

# Don't change this!
WORKDIR /data
COPY . .

# Optional ones. From build-stage.yml

ENTRYPOINT ["tail", "-f", "/dev/null"]
2 changes: 2 additions & 0 deletions dev/templates/test/build-stage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Build stage args to inject. Use ${} placeholders for args passed in settings.yml.
buildargs: {}
21 changes: 21 additions & 0 deletions dev/templates/test/settings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: "Test"
description: "A Test template"
port_range:
min: 22222
max: 33333
defaults:
ram: 512000000 # bytes
cpu: 2 # cores
disk: 2000000000 # bytes
meta:
# Stop command to be sent in stop signal endpoint
internal/stop-command: "stop"
# Args, and their default values
args: {}
container:
env: {}
resources:
limits:
ram: 512000000
cpu: 2
disk: 2000000000
Loading