# What Does the start.js Script Do Before Starting the LunaTV Server?

> Discover what start.js does before launching the LunaTV server. Learn how it prepares the Docker manifest, boots the server, and initializes cron jobs.

- Repository: [MoonTechLab/LunaTV](https://github.com/MoonTechLab/LunaTV)
- Tags: internals
- Published: 2026-09-08

---

**The [`start.js`](https://github.com/MoonTechLab/LunaTV/blob/main/start.js) script generates a Docker-ready manifest, boots the server, polls the `/login` endpoint until it returns a successful response, and then initializes hourly cron jobs.**

The [`start.js`](https://github.com/MoonTechLab/LunaTV/blob/main/start.js) file is the primary entry point for the MoonTechLab/LunaTV repository, orchestrating a strict initialization sequence whenever the application starts via `npm start` or a Docker container. Before the server accepts traffic, the script performs environment preparation, server readiness verification, and background task scheduling to ensure stable deployment.

## Manifest Generation for Docker Deployments

Before the server initializes, [`start.js`](https://github.com/MoonTechLab/LunaTV/blob/main/start.js) invokes the [`generate-manifest.js`](https://github.com/MoonTechLab/LunaTV/blob/main/generate-manifest.js) helper to create a fresh [`manifest.json`](https://github.com/MoonTechLab/LunaTV/blob/main/manifest.json) file. This step is required for Docker and production builds to ensure the manifest reflects the current build state.

According to the source code at lines 8–22, the script dynamically requires [`scripts/generate-manifest.js`](https://github.com/MoonTechLab/LunaTV/blob/main/scripts/generate-manifest.js) using a path resolved relative to the entry point:

```javascript
const path = require('path');
require(path.join(__dirname, 'scripts', 'generate-manifest.js'));

```

This ensures the manifest is always current before the server process begins.

## Server Boot Sequence

Immediately after manifest generation, the script loads the main application server. At line 27 of [`start.js`](https://github.com/MoonTechLab/LunaTV/blob/main/start.js), the script requires [`server.js`](https://github.com/MoonTechLab/LunaTV/blob/main/server.js), which initiates the Next.js/Express-style server that powers LunaTV's UI and API endpoints:

```javascript
// start.js L27
require('./server');

```

This call blocks until the server process is spawned, but does not guarantee the server is fully ready to accept requests.

## Health-Check Polling Mechanism

To prevent dependent services from running prematurely, [`start.js`](https://github.com/MoonTechLab/LunaTV/blob/main/start.js) implements a polling mechanism that verifies the server is actually accepting connections. Lines 30–57 establish a 1-second interval that repeatedly requests `http://<HOST>:<PORT>/login`.

The polling logic checks for a 2xx HTTP status code:

```javascript
// Conceptual implementation based on start.js L30-L57
const timer = setInterval(() => {
  http.get(`http://${HOST}:${PORT}/login`, (res) => {
    if (res.statusCode >= 200 && res.statusCode < 300) {
      clearInterval(timer);
      // Server ready - proceed to cron initialization
    }
  }).on('error', () => {});
}, 1000);

```

This loop guarantees that subsequent cron jobs only execute after the server has successfully started and is responsive.

## Cron Job Initialization and Scheduling

Once the health-check confirms the server is ready, the script triggers background task execution. At line 44, [`start.js`](https://github.com/MoonTechLab/LunaTV/blob/main/start.js) calls `executeCronJob()` after a short delay to run an immediate job, then sets up a recurring hourly interval at lines 47–50.

The cron scheduling logic:

```javascript
// start.js L42-L50
setTimeout(executeCronJob, 1000); // One-off execution

setInterval(() => {
  executeCronJob();
}, 60 * 60 * 1000); // Hourly recurrence

```

The `executeCronJob` function (lines 60–90) performs an HTTP GET request to the internal `/api/cron` endpoint, logging success or failure and implementing timeout handling. This function abstracts the actual background work, allowing the startup script to manage scheduling independently of the job logic.

## Practical Usage Examples

### Running Locally

When executing outside Docker, ensure the `HOSTNAME` and `PORT` environment variables are set (defaults are localhost:3000):

```bash
HOSTNAME=localhost PORT=3000 node start.js

```

### Docker Configuration

The repository's `Dockerfile` uses [`start.js`](https://github.com/MoonTechLab/LunaTV/blob/main/start.js) as the container command:

```dockerfile
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm ci && npm run build
CMD ["node", "start.js"]

```

### Manual Manifest Generation

To replicate the manifest generation step independently:

```javascript
const path = require('path');
require(path.join(__dirname, 'scripts', 'generate-manifest.js'));

```

### Custom Server Polling

You can extract the polling logic for other initialization scripts:

```javascript
const http = require('http');

function waitForServer(url) {
  return new Promise((resolve) => {
    const timer = setInterval(() => {
      http.get(url, (res) => {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          clearInterval(timer);
          resolve();
        }
      }).on('error', () => {});
    }, 1000);
  });
}

```

## Summary

- **Manifest generation**: [`start.js`](https://github.com/MoonTechLab/LunaTV/blob/main/start.js) calls [`scripts/generate-manifest.js`](https://github.com/MoonTechLab/LunaTV/blob/main/scripts/generate-manifest.js) (lines 8–22) to create a Docker-ready [`manifest.json`](https://github.com/MoonTechLab/LunaTV/blob/main/manifest.json) before server boot.
- **Server initialization**: The script requires [`server.js`](https://github.com/MoonTechLab/LunaTV/blob/main/server.js) at line 27 to launch the main application process.
- **Readiness verification**: A 1-second polling loop (lines 30–57) checks the `/login` endpoint for a 2xx response to confirm the server is accepting connections.
- **Cron scheduling**: Only after the server is confirmed ready, the script executes `executeCronJob()` once and schedules hourly recurrences (lines 42–50), which trigger the `/api/cron` endpoint.

## Frequently Asked Questions

### When does the first cron job execute?

The first cron job runs approximately one second after the server returns a successful 2xx response from the `/login` endpoint. This delay, implemented at line 44 of [`start.js`](https://github.com/MoonTechLab/LunaTV/blob/main/start.js), ensures the server is fully initialized before handling background tasks.

### How does start.js determine if the server is ready?

The script polls `http://<HOST>:<PORT>/login` every 1,000 milliseconds until it receives an HTTP response with a status code between 200 and 299. This polling loop, defined in lines 30–57 of [`start.js`](https://github.com/MoonTechLab/LunaTV/blob/main/start.js), prevents dependency race conditions.

### What file is generated before the server starts?

Before booting [`server.js`](https://github.com/MoonTechLab/LunaTV/blob/main/server.js), the script generates [`manifest.json`](https://github.com/MoonTechLab/LunaTV/blob/main/manifest.json) by executing [`scripts/generate-manifest.js`](https://github.com/MoonTechLab/LunaTV/blob/main/scripts/generate-manifest.js). This manifest is required for Docker deployments and production builds to ensure proper versioning and metadata.

### Can I run start.js without Docker?

Yes. While [`start.js`](https://github.com/MoonTechLab/LunaTV/blob/main/start.js) is optimized for Docker workflows (particularly the manifest generation), you can execute it directly with Node.js by setting the `HOSTNAME` and `PORT` environment variables. The script functions identically in both containerized and bare-metal environments.