Skip to content

Deploy a Svelte App

How to host a Svelte app anywhere

In this guide, we’ll deploy a Svelte app using the Svelte Node adapter, Docker, and Caddy Server. This approach ensures a robust, scalable, and secure deployment setup that will work on almost any cloud server with any cloud provider or own hardware.

Setting Up the Server

Prepare a server with a public IP address, SSH access from your development machine, and a fresh Ubuntu 22.04 installation. Ensure that ports 22, 80, and 443 are open (some cloud providers, like AWS, close ports by default; you’ll need to open them before deployment). If you are looking for a new cloud provider, consider Hetzner, DigitalOcean, or OVH, where ports are open by default. However, the deployment script below will close all ports except the ones required.

Prepare a Svelte app for deployment

  • Update the svelte.config.js (in the project's root folder) file to use the Node adapter:
import adapter from '@sveltejs/adapter-node';

export default {
  kit: {
    adapter: adapter(),
  },
};
  • In the root of your project, create a file named Dockerfile:
FROM node:18-alpine AS builder
ENV GCP_BUILDPACKS=1
WORKDIR /app
COPY package*.json .
RUN npm i -D @sveltejs/adapter-node
RUN npm ci
COPY . .
RUN npm run build
RUN npm prune --production

FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/build build/
COPY --from=builder /app/node_modules node_modules/
COPY package.json .
EXPOSE 3000
ENV NODE_ENV=production
CMD [ "node", "build" ]
  • In the root of your project, create a file named .dockerignore to avoid copying unnecessary files:
Dockerfile
.dockerignore
.git
.gitignore
.gitattributes
README.md
.npmrc
.prettierrc
.eslintrc.cjs
.graphqlrc
.editorconfig
.svelte-kit
.vscode
node_modules
build
package
**/.env

Deploy with One Command

If you don't want to manually deploy your Svelte app or simply don’t have the time to implement a deployment pipeline, you can deploy your project to any cloud or self-hosted server with a single command from your local repository (no need for GitHub, Bitbucket, or even Git) using the TurboCloud deployment toolkit. You can also deploy directly from GitHub or Bitbucket.

Deploy from the Local Repository

  • On your development machine, navigate to the folder containing the Rust app code and run the deployment command (replace server_ip with the actual public IP of your server):
cd my_svelte_app
curl https://turbocloud.dev/deploy | bash -s -- -i server_ip -p 3000
  • Wait until the deployment script displays the URL of the deployed Rust application.
  • Full documentation for all available parameters and detailed instructions can be found at turbocloud.dev/docs.

Deploy from GitHub or Bitbucket

  • SSH into your server (replace server_ip with the actual public IP of your server):
ssh root@server_ip
  • Run the setup command:
curl https://turbocloud.dev/setup | bash -s
  • Once installation is complete, start the TurboCloud TUI (Terminal User Interface), which functions similarly to standard applications on macOS, Linux, and other operating systems but can operate on servers without displays. Use the TUI to set up deployments with interactive guides:
turbocloud

Step-by-Step guide

Prerequisites

Before diving into the deployment steps, ensure you have the following:

  • A Svelte project: If you don’t have one, we’ll show you how to create an example app.
  • A VPS: Ensure you have SSH access and a domain pointing to the VPS.

Step 1: Create a Svelte App

Let’s start by creating a simple Svelte app.

Initialize the App

If you don’t already have a Svelte app, create one:

npx degit sveltejs/template my-svelte-app
cd my-svelte-app
npm install

This will create a basic Svelte project structure.

Install SvelteKit with Node Adapter

If you're using SvelteKit, it’s essential to configure it with the Node adapter for server-side rendering (SSR).

Install SvelteKit and the Node adapter:

npm install @sveltejs/kit @sveltejs/adapter-node

Update the svelte.config.js file to use the Node adapter if it has not been configured to do so already::

import adapter from '@sveltejs/adapter-node';

export default {
  kit: {
    adapter: adapter(),
  },
};

Add a Sample Route

Let’s add a simple route to ensure the app is working:

Create a new file src/routes/hello-world.svelte:

<script>
  let message = "Hello, Svelte on VPS!";
</script>

<h1>{message}</h1>

Run the app locally to ensure everything works:

npm run dev

Visit http://localhost:3000 and ensure the app is running.


Step 2: Build the App

Once the app is working locally, build it for production:

npm run build

This generates a production-ready version of your app in the build directory.


Step 3: Dockerize the App

Using Docker makes it easy to deploy the app in any environment without worrying about dependencies or configurations.

Create a Dockerfile

In the root of your project, create a file named Dockerfile if it has not been created already:

FROM node:18-alpine AS builder
ENV GCP_BUILDPACKS=1
WORKDIR /app
COPY package*.json .
RUN npm i -D @sveltejs/adapter-node
RUN npm ci
COPY . .
RUN npm run build
RUN npm prune --production

FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/build build/
COPY --from=builder /app/node_modules node_modules/
COPY package.json .
EXPOSE 3000
ENV NODE_ENV=production
CMD [ "node", "build" ]

Create a .dockerignore File

To avoid copying unnecessary files, create a .dockerignore file if it has not been created already:

Dockerfile
.dockerignore
.git
.gitignore
.gitattributes
README.md
.npmrc
.prettierrc
.eslintrc.cjs
.graphqlrc
.editorconfig
.svelte-kit
.vscode
node_modules
build
package
**/.env

Build and Test the Docker Image

Build the Docker image (Docker should be installed on your local machine):

docker build -t my-svelte-app .

Run the container to test it locally:

docker run -p 3000:3000 my-svelte-app

Visit http://localhost:3000 to confirm it’s working.


Step 4: Set Up Docker on VPS

Install Docker

If Docker is not installed on your VPS, install it:

sudo apt update
sudo apt install -y docker.io
sudo systemctl enable docker

Transfer the project files to the VPS and build the image

  • Copy the project files to the VPS using scp or Git, then rebuild the Docker image directly on the server:
cd /path/to/project
docker build -t my-svelte-app .

Step 5: Configure Caddy

Caddy is a powerful, automatic HTTPS server. It simplifies the process of securing your app with HTTPS.

Install Caddy

On the VPS, install Caddy:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/deb.debian.caddy.repo' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

Configure Caddyfile

Edit the Caddyfile to proxy traffic to your Svelte app running in Docker. Create or edit /etc/caddy/Caddyfile:

mydomain.com {
  reverse_proxy localhost:3000
}

Replace mydomain.com with your domain name.

Restart Caddy

Restart the Caddy service to apply the changes:

sudo systemctl restart caddy

Caddy will automatically fetch and renew SSL certificates for your domain.

Step 6: Run the App in Docker

Start the Docker container on your VPS:

docker run -d --name my-svelte-app -p 3000:3000 my-svelte-app

Visit https://mydomain.com to see your deployed Svelte app in action.

Conclusion

In this guide, we’ve covered two options for deploying Svelte projects:

  1. Using the TurboCloud deployment toolkit with a single command. This option also includes CI/CD, multiple environments, a Web Application Firewall (WAF), a Rate Limiter, and VPN functionality across servers and local machines.
  2. Deploying manually with Docker, Docker Compose, and Caddy. To prepare your server for production, we recommend adding a Web Application Firewall (WAF) and a Rate Limiter.