# How the Express Server Handles HTTPS with SSL Certificates for Production Deployment in Astro Big Doc

> Learn how the Express server in Astro Big Doc handles HTTPS with SSL certificates for production deployment. Secure your site with our guide.

- Repository: [Micro Web Stacks/astro-big-doc](https://github.com/microwebstacks/astro-big-doc)
- Tags: how-to-guide
- Published: 2026-03-07

---

**The Express server in `microwebstacks/astro-big-doc` conditionally creates an HTTPS server by reading SSL certificate files when the `PROTOCOL` environment variable is set to `https`, falling back to HTTP for development.**

The `astro-big-doc` project provides a lightweight Express wrapper for serving static Astro builds, with built-in support for TLS encryption in production environments. Understanding how the Express server handles HTTPS with SSL certificates for production deployment ensures you can securely serve documentation sites behind TLS without additional reverse proxy complexity.

## Environment-Driven HTTPS Configuration

The server uses a configuration-first approach driven by environment variables loaded via `dotenv.config()`. This allows the same codebase to serve both development HTTP and production HTTPS traffic without code changes.

### Required Environment Variables

For HTTPS operation, three specific variables must be set in your `.env` file or production environment:

- **`PROTOCOL`**: Must be set to `"https"` to trigger TLS mode
- **`KEY_FILE`**: Relative path (from `server/` directory) to your PEM-encoded private key
- **`CERT_FILE`**: Relative path to your PEM-encoded certificate file

```javascript
// server/server.js lines 13-15
const outdir   = process.env.OUT_DIR   ?? "dist"
const protocol = process.env.PROTOCOL ?? "http"
const host     = process.env.HOST     ?? "0.0.0.0"
const port     = process.env.PORT     ?? "3001"

```

## Conditional Server Creation in server.js

The core logic that determines HTTP versus HTTPS operation resides in the server initialization block. After configuring Express middleware for CORS, optional authentication, and static file serving, the code evaluates the `protocol` variable to determine which Node.js server module to invoke.

When `PROTOCOL` equals `"https"`, the server:

1. Synchronously reads the private key and certificate files using `readFileSync`
2. Resolves paths relative to the `server/` directory via `join(__dirname, ...)`
3. Invokes `https.createServer({ key, cert }, app)` to wrap the Express application in a TLS context
4. Binds to the configured host and port

```javascript
// server/server.js lines 38-48
if (protocol == "https") {
    const key  = readFileSync(join(__dirname, process.env.KEY_FILE),  "utf8")
    const cert = readFileSync(join(__dirname, process.env.CERT_FILE), "utf8")
    const httpsServer = https.createServer({ key, cert }, app)
    httpsServer.listen(port, host, () => {
        console.log(`listening on ${protocol}://${host}:${port}`)
    })
} else {
    app.listen(port, host, () => {
        console.log(`listening on ${protocol}://${host}:${port}`)
    })
}

```

## Production Deployment Workflow

Deploying with HTTPS requires three specific preparation steps before starting the Node.js process.

### Step 1: Provide TLS Assets

Place your PEM-encoded private key and certificate files in a directory accessible to the application. Common practice within `astro-big-doc` is creating a `server/ssl/` directory:

```bash
mkdir -p server/ssl
cp /path/to/your/private.key server/ssl/key.pem
cp /path/to/your/certificate.crt server/ssl/cert.pem

```

### Step 2: Configure the Environment

Set the required variables in your production `.env` file or container orchestration environment:

```bash
PROTOCOL=https
HOST=0.0.0.0
PORT=443
OUT_DIR=dist
KEY_FILE=ssl/key.pem
CERT_FILE=ssl/cert.pem
ENABLE_CORS=true

```

### Step 3: Launch the Server

Execute the start command. The server will detect `PROTOCOL=https`, load the certificate files, and bind to port 443:

```bash
npm start

# Output: listening on https://0.0.0.0:443

```

The Express application stack—including static file serving from `OUT_DIR`, optional CORS headers, and the authentication router—functions identically under both HTTP and HTTPS because the TLS layer wraps the entire `app` instance without modifying route handlers.

## Summary

- The Express server in `astro-big-doc` uses the `PROTOCOL` environment variable to toggle between HTTP and HTTPS modes without code changes.
- When `PROTOCOL=https`, the server synchronously reads `KEY_FILE` and `CERT_FILE` from paths relative to the `server/` directory.
- The native Node.js `https.createServer()` method wraps the Express application, providing TLS encryption for all static file and API routes.
- Production deployment requires placing PEM-encoded certificates in the repository or container, setting three environment variables, and exposing port 443.

## Frequently Asked Questions

### What environment variables are required for HTTPS?

You must set `PROTOCOL=https`, `KEY_FILE` (relative path to your private key), and `CERT_FILE` (relative path to your certificate). The server will fail to start if `PROTOCOL=https` is set but the certificate files are missing or unreadable.

### Where should I place my SSL certificate files?

Place them in a directory within the `server/` folder, such as `server/ssl/`, and reference them relative to that directory in your environment variables (e.g., `KEY_FILE=ssl/key.pem`). The code uses `join(__dirname, process.env.KEY_FILE)` to resolve paths, ensuring consistency across different deployment environments.

### Can I run HTTP and HTTPS simultaneously?

The current implementation in [`server/server.js`](https://github.com/microwebstacks/astro-big-doc/blob/main/server/server.js) supports only one protocol at a time based on the `PROTOCOL` variable. To run both simultaneously, you would need to modify the startup logic to create two server instances—one using `http.createServer()` and another using `https.createServer()`—binding them to different ports.

### How does the server handle HTTPS errors?

The server uses synchronous `readFileSync` calls when loading certificate files, which will throw an error and halt startup if the files are missing or invalid. Once running, standard Node.js HTTPS server error handling applies; you can attach an `httpsServer.on('error', ...)` listener to the `httpsServer` instance returned by `https.createServer()` to handle runtime TLS or network errors gracefully.