Sankar
Sankar

Reputation: 359

How to deploy Sveltekit app in node server with HTTPS?

I'm want to deploy my Sveltekit app on HTTPS server. I have key files also. This is my svelte.config.js file

import preprocess from 'svelte-preprocess';
import node from '@sveltejs/adapter-node';
import fs from 'fs';
import https from 'https';
/** @type {import('@sveltejs/kit').Config} **/
const config = {
    // Consult https://github.com/sveltejs/svelte-preprocess
    // for more information about preprocessors
    preprocess: preprocess(),

    kit: {
        // hydrate the <div id="svelte"> element in src/app.html
        target: '#svelte',
        adapter: node(),
        files: { assets: "static" },
        vite: {
          server: {
            https: {
              key: fs.readFileSync("path\\privkey.pem"),
              cert: fs.readFileSync("path\\cert.pem"),
            },
          },
        }
    }
};

export default config;

where should I keep my key files for reading from the config file? I tried a few and got some errors screenshot is attached. enter image description here

enter image description here

Someone please guide me. Thanks in advance.

Upvotes: 4

Views: 7465

Answers (4)

Herlangga Yusuf
Herlangga Yusuf

Reputation: 1

Build the product and then serve it using nginx or lighttpd. don't use the hmr it really slow down the web performance because the module keep checking the file change. then apply https to lighttpd or your nginx.

if it too much.
npm run preview.

Edit 2024

you need build it using bundler. there the docs https://kit.svelte.dev/docs/building-your-app

Upvotes: -1

S&#225;mal Rasmussen
S&#225;mal Rasmussen

Reputation: 3495

Here's an example of using a custom nodejs http/https server. Just put in a js file like serve.js:

import fs from 'fs';
import http from 'http';
import https from 'https';
import { parse } from 'url';

import { handler } from './build/handler.js';

/** @type {https.ServerOptions} */
const httpsOptions = {
    key: fs.readFileSync('./cert.key'),
    cert: fs.readFileSync('./cert.crt'),
};

// Create the HTTPS server
const httpsServer = https.createServer(httpsOptions, (req, res) => {
    const parsedUrl = parse(req.url, true);

    // Check if the request is for the health check
    if (parsedUrl.pathname === '/healthcheck') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('ok');
    } else {
        // Let SvelteKit handle all other requests
        handler(req, res);
    }
});

const httpsPort = 60443;
httpsServer.listen(60443, () => {
    console.log(`HTTPS server listening on port ${httpsPort}`);
});

// Create an HTTP server that redirects all traffic to HTTPS
const httpServer = http.createServer((req, res) => {
    // filter out port from req.headers.host
    const host = req.headers.host.split(':')[0];
    const httpsRedirectUrl = `https://${host}:${httpsPort}${req.url}`;
    res.writeHead(301, { Location: httpsRedirectUrl });
    res.end();
});

const redirectPort = 60080;
httpServer.listen(redirectPort, () => {
    console.log(`HTTP server listening on port ${redirectPort} and redirecting to HTTPS`);
});

Run with node ./serve.js

I am personally forwarding the public ports 80 and 443 to the 60080 and 60443 ports on the machine that is running the node server, so I need to do the port handling in the http handler slightly different:

const httpServer = http.createServer((req, res) => {
    const httpsRedirectUrl = `https://${req.headers.host}${req.url}`;

Upvotes: 0

z.houbin
z.houbin

Reputation: 356

I solved it by using a custom server

The adapter creates two files in your build directory — index.js and handler.js. Running index.js — e.g. node build, if you use the default build directory — will start a server on the configured port.

Alternatively, you can import the handler.js file, which exports a handler suitable for use with Express, Connect or Polka (or even just the built-in http.createServer) and set up your own server

The svelte.config.js can be left unchanged. Run npm run build to generate the build folder, create a server.js in the project root like the example below, then run node server.js.

import {handler} from './build/handler.js';
import express from 'express';
import fs from 'fs';
import http from 'http';
import https from 'https';

const privateKey = fs.readFileSync('./config/ssl/xx.site.key', 'utf8');
const certificate = fs.readFileSync('./config/ssl/xx.site.crt', 'utf8');
const credentials = {key: privateKey, cert: certificate};

const app = express();

const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);

const PORT = 80;
const SSLPORT = 443;

httpServer.listen(PORT, function () {
    console.log('HTTP Server is running on: http://localhost:%s', PORT);
});

httpsServer.listen(SSLPORT, function () {
    console.log('HTTPS Server is running on: https://localhost:%s', SSLPORT);
});

// add a route that lives separately from the SvelteKit app
app.get('/healthcheck', (req, res) => {
    res.end('ok');
});

// let SvelteKit handle everything else, including serving prerendered pages and static assets
app.use(handler);

Upvotes: 7

loop
loop

Reputation: 973

I'm going to explain a solution to my somewhat related problem here, all according to my best understanding, which is limited.

My solution to set up a trusted Sveltekit dev server (running in a private subnet without DNS) was to configure a Nginx reverse proxy that acts as a trusted HTTPS middle man between the Vite server (running in plain HTTP mode) that is bundled in Sveltekit, and the clients (like my Android phone).

I found the most useful guidance from the following resources:

The main steps to the solution were:

  • Become a local certificate authority and register the authority in your clients (like in the Chrome browser on the desktop, or in the Credential storage of an Android phone).
  • Being a certificate authority, sign a x509 certificate for the IP-address (subjectAltName) of the dev server in the local network.
  • Setup a Nginx HTTPS reverse proxy (proxy_pass etc.) to forward traffic to the Vite server (typically running in the port 3000). Assign the created certificate and the key for its use. Also add Websocket support as explained in the setup guide linked above.
  • Declare kit.vite.server.hmr.port = <port of the Nginx proxy> in svelte.config.js. This is important so that the Sveltekit middleware (?) does not try to bypass the proxy.

Relevant snippets from my configuration:

openssl genrsa -out myCA.key 2048
openssl req -x509 -new -nodes -key myCA.key -sha256 -days 10000 -out myCA.pem
openssl genrsa -out 192.168.22.88.key 2048
openssl req -new -key 192.168.22.88.key -out 192.168.22.88.csr

>192.168.22.88.ext cat <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
IP.1 = 192.168.22.88
IP.2 = 127.0.0.1
DNS.1 = localhost
DNS.2 = localhost.local
EOF

openssl x509 -req -in 192.168.22.88.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out 192.168.22.88.crt -days 10000 -sha256 -extfile 192.168.22.88.ext
openssl dhparam -out dhparam.pem 2048

server {
        listen 2200 http2 ssl default_server;
        listen [::]:2200 http2 ssl default_server;
        ssl_certificate     /etc/nginx/ssl/192.168.22.88.crt;
        ssl_certificate_key /etc/nginx/ssl/192.168.22.88.key;
        ssl_dhparam /etc/nginx/ssl/dhparam.pem;
        index index.html;
        server_name 192.168.22.88;

        ssl on;
        ssl_session_cache  builtin:1000  shared:SSL:10m;
        ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
        ssl_prefer_server_ciphers on;

        location / {

            proxy_set_header        Host $host;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header        X-Forwarded-Proto $scheme;

            proxy_pass          http://127.0.0.1:3000;
            proxy_read_timeout  90;

            proxy_redirect      http://127.0.0.1:3000 https://192.168.22.88:2200;

            # WebSocket support
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
 
       }

}

kit: {
    // hydrate the <div id="svelte"> element in src/app.html
    target: '#svelte',
    adapter: adapter(),
    vite: {
        server: {
            hmr: {
                port: 2200,
            }
        }
    }
}

pnpm run dev

Upvotes: 3

Related Questions