Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions dashboard/app/templates/editor/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,7 @@ function TemplateEditorContent() {
<Label className="text-xs">Package</Label>
<Select
value={form.package}
disabled={mode === "edit"}
onValueChange={(value) =>
setForm((prev) => ({
...prev,
Expand Down
9 changes: 9 additions & 0 deletions docker-compose.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ services:
volumes:
# Mount plugins directory for user-installed plugins (optional)
- plugin-data:/app/.plugins
- logs-data:/app/logs
- ./simplens.config.yaml:/app/simplens.config.yaml:ro
command: [ "node", "dist/api/server.js" ]
depends_on:
Expand Down Expand Up @@ -190,6 +191,8 @@ services:
OUTBOX_CLAIM_TIMEOUT_MS: ${OUTBOX_CLAIM_TIMEOUT_MS:-30000}
LOKI_URL: http://loki:3100
LOG_LEVEL: ${LOG_LEVEL:-info}
volumes:
- logs-data:/app/logs
command: [ "node", "dist/workers/worker.js" ]
depends_on:
mongo:
Expand Down Expand Up @@ -231,6 +234,7 @@ services:
volumes:
# Mount plugins directory for user-installed plugins (optional)
- plugin-data:/app/.plugins
- logs-data:/app/logs
- ./simplens.config.yaml:/app/simplens.config.yaml:ro
depends_on:
mongo:
Expand Down Expand Up @@ -264,6 +268,8 @@ services:
# Logging
LOKI_URL: http://loki:3100
LOG_LEVEL: ${LOG_LEVEL:-info}
volumes:
- logs-data:/app/logs
command: [ "node", "dist/processors/delayed/delayed.processor.js" ]
depends_on:
mongo:
Expand Down Expand Up @@ -301,6 +307,8 @@ services:
# Logging
LOKI_URL: http://loki:3100
LOG_LEVEL: ${LOG_LEVEL:-info}
volumes:
- logs-data:/app/logs
command: [ "node", "dist/workers/recovery/recovery.service.js" ]
depends_on:
mongo:
Expand Down Expand Up @@ -355,6 +363,7 @@ volumes:
loki_data:
grafana_data:
plugin-data:
logs-data:


networks:
Expand Down
10 changes: 9 additions & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ services:
- .env
volumes:
- plugin-data:/app/.plugins
- logs-data:/app/logs
- ./simplens.config.yaml:/app/simplens.config.yaml:ro
command: [ "node", "dist/api/server.js" ]
networks:
Expand All @@ -24,6 +25,8 @@ services:
image: ghcr.io/simplenotificationsystem/simplens-core:latest
env_file:
- .env
volumes:
- logs-data:/app/logs
command: [ "node", "dist/workers/worker.js" ]
networks:
- simplens
Expand All @@ -35,6 +38,7 @@ services:
- .env
volumes:
- plugin-data:/app/.plugins
- logs-data:/app/logs
- ./simplens.config.yaml:/app/simplens.config.yaml:ro
command: [ "node", "dist/processors/unified/unified.processor.js" ]
depends_on:
Expand All @@ -48,6 +52,8 @@ services:
image: ghcr.io/simplenotificationsystem/simplens-core:latest
env_file:
- .env
volumes:
- logs-data:/app/logs
command: [ "node", "dist/processors/delayed/delayed.processor.js" ]
networks:
- simplens
Expand All @@ -57,6 +63,8 @@ services:
image: ghcr.io/simplenotificationsystem/simplens-core:latest
env_file:
- .env
volumes:
- logs-data:/app/logs
command: [ "node", "dist/workers/recovery/recovery.service.js" ]
networks:
- simplens
Expand All @@ -80,8 +88,8 @@ services:

volumes:
plugin-data:
logs-data:

networks:
simplens:
driver: bridge

28 changes: 27 additions & 1 deletion packages/onboard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- 🐧 **OS-Aware Configuration** - Automatically detects and configures for Windows, Linux, or macOS
- ⚙️ **Smart Environment Config** - Default or interactive mode for environment variables
- 🔌 **Plugin Management** - Browse and install official SimpleNS plugins
- 🔐 **Optional SSL Setup** - Automatic Let's Encrypt setup with Dockerized Certbot (Windows/macOS/Linux)
- 🚀 **Service Orchestration** - Automatic health checks and sequential service startup
- 📊 **Service Dashboard** - View all running services and their access URLs

Expand Down Expand Up @@ -110,6 +111,9 @@ The CLI will display a security notice with all credentials that need to be upda
| `--core-version <version>` | Override `CORE_VERSION` in generated `.env` (primarily for `--full`) | `latest` |
| `--dashboard-version <version>` | Override `DASHBOARD_VERSION` in generated `.env` (primarily for `--full`) | `latest` |
| `--plugin [plugins...]` | Plugins to install (e.g., `@simplens/mock @simplens/nodemailer-gmail`) | Prompted |
| `--ssl` | Enable optional SSL automation with Certbot | `false` |
| `--ssl-domain <domain>` | Public domain for SSL cert (required with `--ssl` in `--full`) | Prompted |
| `--ssl-email <email>` | Email for Let's Encrypt registration (required with `--ssl` in `--full`) | Prompted |
| `--no-output` | Suppress all console output (silent mode) | `false` |

### Valid Infrastructure Services
Expand All @@ -118,7 +122,7 @@ The CLI will display a security notice with all credentials that need to be upda
- `kafka` - Apache Kafka message queue
- `kafka-ui` - Kafka UI dashboard (optional)
- `redis` - Redis cache
- `nginx` - Nginx reverse proxy (optional, Required only is BASE_PATH is configured)
- `nginx` - Nginx reverse proxy (optional, Required only is BASE_PATH or SSL is configured)
- `loki` - Loki log aggregation (optional)
- `grafana` - Grafana observability dashboard (optional)

Expand Down Expand Up @@ -156,12 +160,18 @@ The CLI will display a security notice with all credentials that need to be upda
- Start application services
- Display service URLs and status

6. **Optional SSL Automation** (if enabled)
- Auto-enables Nginx if required
- Issues cert via Dockerized Certbot (`http-01` webroot challenge)
- Configures auto-renew service and Nginx reload

## Generated Files

- `docker-compose.infra.yaml` - Infrastructure services (if `--infra` used)
- `docker-compose.yaml` - Application services
- `.env` - Environment variables and credentials
- `simplens.config.yaml` - Plugin configuration
- `nginx.conf` - Generated reverse proxy config (HTTP/HTTPS based on options)

## Service URLs

Expand Down Expand Up @@ -243,6 +253,22 @@ cd /app/simplens
docker-compose up -d
```

### Full Setup With SSL Automation

```bash
npx @simplens/onboard \
--full \
--infra mongo kafka redis \
--env default \
--ssl \
--ssl-domain app.example.com \
--ssl-email ops@example.com
```

Notes:
- Your domain DNS must point to the host running onboarding.
- Ports 80 and 443 must be publicly reachable for Let's Encrypt validation.

### Silent Mode (No Console Output)

```bash
Expand Down
4 changes: 2 additions & 2 deletions packages/onboard/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/onboard/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@simplens/onboard",
"version": "1.0.5",
"version": "1.0.6",
"type": "module",
"main": "dist/index.js",
"bin": {
Expand Down
4 changes: 3 additions & 1 deletion packages/onboard/src/__tests__/infra-prompts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ describe('promptInfraServicesWithBasePath', () => {
const mockMultiselect = vi.mocked(multiselect);
mockMultiselect.mockResolvedValue(['mongo', 'redis', 'nginx']);

const result = await promptInfraServicesWithBasePath({ allowNginx: true });
const result = await promptInfraServicesWithBasePath({ allowNginx: true, defaultNginx: true });

// Should include nginx in options
const callArgs = mockMultiselect.mock.calls[0][0] as any;
const values = callArgs.options.map((o: any) => o.value);
expect(values).toContain('nginx');
expect(callArgs.initialValues).toContain('nginx');
expect(callArgs.initialValues).not.toContain('kafka-ui');

expect(result).toContain('nginx');
});
Expand Down
15 changes: 15 additions & 0 deletions packages/onboard/src/__tests__/infra.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,19 @@ describe('infra app compose generation', () => {
expect(compose).toContain(' nginx:');
expect(compose).toContain('./nginx.conf:/etc/nginx/conf.d/default.conf:ro');
});

it('does not include certbot services when ssl is disabled', () => {
const compose = buildAppComposeContent(true, { includeSsl: false });
expect(compose).not.toContain(' certbot:');
expect(compose).not.toContain(' certbot-renew:');
});

it('includes certbot services and volumes when ssl is enabled', () => {
const compose = buildAppComposeContent(false, { includeSsl: true });
expect(compose).toContain(' nginx:');
expect(compose).toContain(' certbot:');
expect(compose).toContain(' certbot-renew:');
expect(compose).toContain('certbot-etc:');
expect(compose).toContain('certbot-www:');
});
});
28 changes: 27 additions & 1 deletion packages/onboard/src/__tests__/validators.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import {
checkDockerRunning,
detectOS,
validatePrerequisites,
validateEnvValue
validateEnvValue,
validatePublicDomain,
validateEmailAddress
} from '../validators.js';
import {
DockerNotInstalledError,
Expand Down Expand Up @@ -192,4 +194,28 @@ describe('validators', () => {
});
});
});

describe('validatePublicDomain', () => {
it('accepts valid public domains', () => {
expect(validatePublicDomain('example.com')).toBe(true);
expect(validatePublicDomain('app.example.com')).toBe(true);
});

it('rejects urls or malformed values', () => {
expect(validatePublicDomain('https://example.com')).not.toBe(true);
expect(validatePublicDomain('example')).not.toBe(true);
expect(validatePublicDomain('example.com/path')).not.toBe(true);
});
});

describe('validateEmailAddress', () => {
it('accepts valid email addresses', () => {
expect(validateEmailAddress('admin@example.com')).toBe(true);
});

it('rejects invalid email values', () => {
expect(validateEmailAddress('admin@')).not.toBe(true);
expect(validateEmailAddress('not-an-email')).not.toBe(true);
});
});
});
Loading