Deploy Angular with Express server on seenode
Deploy your Angular single-page app with a Node static server (Express) and SPA fallback on Seenode.
This guide explains how to deploy an existing Angular single-page application (SPA) served by a minimal Node server (using Express for static + SPA fallback) to seenode.
Prerequisites
Before you begin, ensure you have:
- A seenode account at seenode.com
- Git configured on your machine
- An existing Angular project ready to build (Angular CLI)
Project Configuration
To deploy your Angular SPA on seenode, you need a simple Express server to serve your built static files. This server handles SPA routing by returning index.html for all routes.
Install Express
First, install Express in your project root:
npm install expressyarn add expresspnpm add expressbun add expressCreate server.js
Create a server.js file at your project root to serve your built Angular app:
const express = require("express");const path = require("path");
const app = express();const PORT = 8080; // * Match the Port field in seenodeconst BUILD_DIR = path.join(__dirname, "client", "dist", "angular-app"); // * Angular CLI default output folder
// * Serve static assets from the build outputapp.use(express.static(BUILD_DIR));
// * SPA fallback: always return index.htmlapp.get("*", (req, res) => { res.sendFile(path.join(BUILD_DIR, "index.html"));});
app.listen(PORT, "0.0.0.0", () => { console.log(`Server running on http://0.0.0.0:${PORT}`);});This server serves your built Angular app and handles client-side routing by returning index.html for all routes.
Note (Angular build output)
Angular CLI builds to dist/angular-app by default (or the project name specified in angular.json). Ensure BUILD_DIR in server.js matches your Angular output directory.
Port Configuration
Set the port in server.js to match the Port field you’ll configure in seenode (for example, 8080). On seenode, there is no default container port—traffic is routed to whatever value you set in the Port field.
For more background on how the Port field controls routing on seenode, see Configuring Your Application’s Port.
Package Scripts
Add these scripts to your root package.json:
{ "scripts": { "client:install": "cd client && npm install", "client:build": "cd client && npm run build", "start": "node server.js" }, "dependencies": { "express": "^4.19.2" }}Recommended Project Structure
Directory/your-angular-spa-app
- server.js Express static server + SPA fallback
- package.json Root scripts and Express dependency
Directoryclient/ Angular app (CLI)
- angular.json
- package.json
- tsconfig.json
Directorysrc/
- main.ts
- index.html
- styles.css
Directoryapp/
- app.component.ts
- app.component.html
- app.component.css
Deploy on seenode
Push to Git
Commit your project and push it to GitHub or GitLab.
Create a Web Service
From the seenode Dashboard, create a new Web Service and connect your repository.
Configure Build & Start
seenode attempts to detect these automatically. Configure:
- Build Command:
npm install && npm run client:install && npm run client:build - Start Command:
node server.js
Set the Port field to
8080(or your chosen value) and ensureserver.jslistens on the same port.- Build Command:
Configure Environment Variables
Add any additional variables your app needs. You do not need to add a
PORTenvironment variable.Deploy
Click Create Web Service and watch logs until your web service is live.
Success
Your Angular SPA is now accessible via your service’s URL.
:::::tip[Troubleshooting] If your deployment fails, first check the Logs tab in your seenode service dashboard. Build and runtime logs often contain valuable information for diagnosing issues.
Port configuration mismatch
- On seenode, there is no default container port. Ensure your server listens on the port you configured in the Port field.
- Update your
server.jsif needed (for example, changeconst PORT = 8080;to match the Port field). - Seeing a 502 Bad Gateway? Your app may not be listening on the expected port.
Build failures
- Missing
client/dist/angular-appdirectory: Ensure your build command runsclient:buildsuccessfully. Angular CLI builds toclient/dist/angular-appby default (checkangular.jsonoutput path). - Build command errors: Check logs for npm install failures. Ensure both root and client
package.jsonfiles are valid JSON. - Client build not found: Verify the build output path in
server.jsmatches your Angular CLI output directory. Angular CLI defaults todist/angular-app(or the project name specified inangular.json). - Missing
src/styles.cssduring build: Ensureclient/src/styles.cssexists (Angular CLI references it inangular.jsonby default), or update thestylesarray inangular.jsonto point to your stylesheet.
Runtime issues
- 404 errors on client routes: Ensure the SPA fallback route (
app.get("*", ...)) is placed afterexpress.static()middleware and returnsindex.htmlfor all routes. - Static assets not loading: Verify
BUILD_DIRinserver.jspoints toclient/dist/angular-app(or your configured Angular output directory). Check that assets are being built correctly. - Server not starting: Check that Express is installed in root
package.jsonand thatserver.jsexists at the repository root.
Monorepo-specific issues
- Multiple lockfiles: If you have
package-lock.jsonin both root andclient/, ensure both are committed to Git. - Nested node_modules: The build process installs dependencies in both root and
client/directories. This is expected behavior for monorepo setups. - Angular CLI version: Ensure you’re using a compatible Angular CLI version. The example uses Angular 18, but older versions may have different build output structures. :::::
Starting from Scratch?
If you don’t have an Angular project yet:
Option 1: Use our Template (Recommended)
Angular SPA Template
Deploy an Angular SPA with Express static server pre-configured for seenode.Option 2: Create from Angular Docs + seenode Setup
Follow the official Angular documentation to create a new project, then follow the Project Configuration steps above to set up the Express server.
Next Steps
Now that your Angular SPA is deployed, here are some things you might want to do next:
Set up a Custom Domain (Coming Soon)
Configure a custom domain to point to your new web service.Connect to a Database
Instantly scaffold and connect PostgreSQL and MySQL databases