Skip to content

PhotonSpark

Web Hosting Platform
Docs

Deploy a full-stack App

Build a frontend and backend from one repository, with a scoped shared PostgreSQL database.

Read as text
Read the AI prompt before copying
Help me prepare my existing project for PhotonSpark Webhost using the guide below. Ask for the project requirements and deployment choice when missing. Inspect existing files before editing, preserve behavior and data, and do not invent supported flags or deployment options. Keep credentials out of code and prompts. Explain dashboard settings and test production behavior. Publishing, DNS changes, and destructive actions need my authorization. Report what passed and what remains unverified.

# Deploy a full-stack App

Build a frontend and backend from one repository, with a scoped shared PostgreSQL database.

Source: https://webhost.photonspark.com/docs/apps

## Organize the repository

The standard manifest is platform.app.yaml at the repository root; the manifest path is configurable in Webhost. Frontend buildMode accepts static, node-static, or node-server. Paths are relative to the repository; the Dockerfile path is relative to backend.path.

```text
my-app/
  platform.app.yaml
  frontend/
    package.json
    package-lock.json
    src/
  backend/
    Dockerfile
    .dockerignore
    package.json
    package-lock.json
    src/
```

## Describe the deployment

This example expects a real npm run migrate script in the backend. Omit migrations if you have no migration command. App deployment currently provisions shared PostgreSQL even if the database block is omitted; omission is not a database-disable switch. Your application may leave the database unused. dedicated-ha is reserved and is not provisioned by this platform version.

```yaml
version: 1
frontend:
  path: frontend
  buildMode: node-static
backend:
  path: backend
  dockerfile: Dockerfile
  port: 8080
  healthPath: /healthz
# Shared PostgreSQL is the current App default. Migrations are optional.
database:
  postgres:
    tier: shared
    migrations:
      command: npm run migrate
routing:
  apiPrefix: /api
```

## Package the backend

The backend must listen on 0.0.0.0 at backend.port and serve backend.healthPath. routing.apiPrefix must be /api in this platform version. Keep application endpoints under /api; the gateway preserves that prefix. Return a successful response from the configured health route.

Compile TypeScript or other source during the image build. Start the compiled production entry point. Exclude .env, credentials, node_modules, and unrelated files from the Docker build context.

```dockerfile
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev --no-audit --no-fund
COPY --chown=node:node src/ ./src/
ENV NODE_ENV=production HOST=0.0.0.0 PORT=8080
USER node
EXPOSE 8080
CMD ["node", "src/server.js"]
```

## Connect the database and frontend

- The shared PostgreSQL service gives the app a scoped user and schema. Read DATABASE_URL from the backend environment; never commit it or put it in browser code.
- The optional migration command runs separately using the app database credentials. Make migrations safe to retry and consider compatibility with the currently serving application.
- Browser code calls /api on the application's public hostname. Server-rendered frontend code can use process.env.BACKEND_INTERNAL_URL to reach its own backend.
- The backend also receives FRONTEND_INTERNAL_URL. These internal URLs are server-only settings.
- Do not rely on container memory or local files for durable user data. Use PostgreSQL or another explicitly configured persistent service.

## Build, deploy, and verify

A successful build alone does not prove the backend starts or the application works. A Git polling warning can coexist with a healthy older release.

1. Create an App, connect the repository and branch, and select its manifest path.
2. Configure build, frontend, and backend environment values. Keep secrets out of frontend bundles.
3. Run the deployment. Webhost builds the frontend, builds and publishes the backend image, provisions shared PostgreSQL, and runs the configured migration.
4. Inspect build logs and both runtime components. Verify the homepage, backend health route, real API requests, and database behavior through the public hostname.

- [Frontend Site build contracts](https://webhost.photonspark.com/docs/sites)
- [Deployment workflow](https://webhost.photonspark.com/docs/deployments)

Organize the repository

The standard manifest is platform.app.yaml at the repository root; the manifest path is configurable in Webhost. Frontend buildMode accepts static, node-static, or node-server. Paths are relative to the repository; the Dockerfile path is relative to backend.path.

App repository layout
my-app/
  platform.app.yaml
  frontend/
    package.json
    package-lock.json
    src/
  backend/
    Dockerfile
    .dockerignore
    package.json
    package-lock.json
    src/

Describe the deployment

This example expects a real npm run migrate script in the backend. Omit migrations if you have no migration command. App deployment currently provisions shared PostgreSQL even if the database block is omitted; omission is not a database-disable switch. Your application may leave the database unused. dedicated-ha is reserved and is not provisioned by this platform version.

platform.app.yaml
version: 1
frontend:
  path: frontend
  buildMode: node-static
backend:
  path: backend
  dockerfile: Dockerfile
  port: 8080
  healthPath: /healthz
# Shared PostgreSQL is the current App default. Migrations are optional.
database:
  postgres:
    tier: shared
    migrations:
      command: npm run migrate
routing:
  apiPrefix: /api

Package the backend

The backend must listen on 0.0.0.0 at backend.port and serve backend.healthPath. routing.apiPrefix must be /api in this platform version. Keep application endpoints under /api; the gateway preserves that prefix. Return a successful response from the configured health route.

Compile TypeScript or other source during the image build. Start the compiled production entry point. Exclude .env, credentials, node_modules, and unrelated files from the Docker build context.

Example backend/Dockerfile for an existing JavaScript server
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev --no-audit --no-fund
COPY --chown=node:node src/ ./src/
ENV NODE_ENV=production HOST=0.0.0.0 PORT=8080
USER node
EXPOSE 8080
CMD ["node", "src/server.js"]

Connect the database and frontend

  • The shared PostgreSQL service gives the app a scoped user and schema. Read DATABASE_URL from the backend environment; never commit it or put it in browser code.
  • The optional migration command runs separately using the app database credentials. Make migrations safe to retry and consider compatibility with the currently serving application.
  • Browser code calls /api on the application's public hostname. Server-rendered frontend code can use process.env.BACKEND_INTERNAL_URL to reach its own backend.
  • The backend also receives FRONTEND_INTERNAL_URL. These internal URLs are server-only settings.
  • Do not rely on container memory or local files for durable user data. Use PostgreSQL or another explicitly configured persistent service.

Build, deploy, and verify

A successful build alone does not prove the backend starts or the application works. A Git polling warning can coexist with a healthy older release.

  1. Create an App, connect the repository and branch, and select its manifest path.
  2. Configure build, frontend, and backend environment values. Keep secrets out of frontend bundles.
  3. Run the deployment. Webhost builds the frontend, builds and publishes the backend image, provisions shared PostgreSQL, and runs the configured migration.
  4. Inspect build logs and both runtime components. Verify the homepage, backend health route, real API requests, and database behavior through the public hostname.