Skip to main content
Deploying a LiveVue app is similar to deploying a regular Phoenix app, with one key requirement: Node.js version 19 or later must be installed in your production environment.
For detailed SSR configuration options, see Configuration. This guide focuses on deployment-specific setup.

General requirements

Before deploying your LiveVue application, ensure you have:
  1. Node.js 19+ installed in production
  2. Standard Phoenix deployment requirements
  3. Built assets before deployment

Fly.io deployment guide

Here’s a detailed guide for deploying to Fly.io. Similar principles apply to other hosting providers.

Generate Dockerfile

First, generate a Phoenix release Dockerfile:
mix phx.gen.release --docker

Modify Dockerfile

Update the generated Dockerfile to include Node.js. Here are the key sections:
# Build Stage
FROM hexpm/elixir:1.14.4-erlang-25.3.2-debian-bullseye-20230227-slim AS builder

# Install build dependencies
RUN apt-get update -y && apt-get install -y build-essential git curl \
    && apt-get clean && rm -f /var/lib/apt/lists/*_*

# Install Node.js for build stage
RUN curl -fsSL https://deb.nodesource.com/setup_19.x | bash - && apt-get install -y nodejs

# Set build ENV
WORKDIR /app

# Install dependencies
COPY mix.exs mix.lock ./
RUN mix deps.get --only prod

# Copy application code
COPY . .

# Install npm dependencies and build assets
RUN cd /app/assets && npm install
RUN mix assets.deploy

# Compile the release
RUN mix compile
RUN mix release

# Production Stage
FROM ${RUNNER_IMAGE}

RUN apt-get update -y && \
    apt-get install -y libstdc++6 openssl libncurses5 locales ca-certificates curl \
    && apt-get clean && rm -f /var/lib/apt/lists/*_*

# Install Node.js for production
RUN curl -fsSL https://deb.nodesource.com/setup_19.x | bash - && apt-get install -y nodejs

# Copy the release from builder
WORKDIR /app
COPY --from=builder /app/_build/prod/rel/my_app ./

CMD ["/app/bin/server"]
Key changes:
  • Add curl to build dependencies
  • Install Node.js in both build and production stages
  • Add npm install step for assets

Launch on Fly.io

1

Initialize your app

fly launch
2

Configure database

? Do you want to tweak these settings before proceeding? (y/N) y
In the configuration window:
  • Choose “Fly Postgres” for database
  • Name your database
  • Consider development configuration for cost savings
  • Review other settings as needed
3

Deploy

The deployment will begin automatically after configuration. Wait for it to complete.
4

Open your app

fly apps open

Other deployment options

Heroku

For Heroku deployment:
1

Use Phoenix buildpack

2

Add Node.js buildpack

heroku buildpacks:add --index 1 heroku/nodejs
3

Configure environment

Set required environment variables including database URL and secret key base

Docker

If using your own Docker setup:
  1. Ensure Node.js 19+ is installed in your production image
  2. Follow standard Phoenix deployment practices
  3. Configure SSR for production (see Configuration)
# Example production stage
FROM debian:bullseye-slim

# Install runtime dependencies including Node.js
RUN apt-get update && \
    apt-get install -y curl ca-certificates && \
    curl -fsSL https://deb.nodesource.com/setup_19.x | bash - && \
    apt-get install -y nodejs && \
    rm -rf /var/lib/apt/lists/*

# Copy your release
COPY --from=builder /app/_build/prod/rel/my_app /app

WORKDIR /app
CMD ["/app/bin/server"]

Custom server

For bare metal or VM deployments:
1

Install Node.js 19+

curl -fsSL https://deb.nodesource.com/setup_19.x | bash -
apt-get install -y nodejs
2

Follow Phoenix deployment guide

Follow the standard Phoenix deployment guide
3

Configure SSR

Ensure the NodeJS supervisor is properly configured in your application

SSR configuration for production

LiveVue uses the NodeJS mode for production SSR. Add this to your application.ex:
lib/my_app/application.ex
children = [
  # ... other children
  {NodeJS.Supervisor, [path: LiveVue.SSR.NodeJS.server_path(), pool_size: 4]},
]
The pool_size determines how many Node.js processes are maintained in the pool. Adjust based on your needs:
  • Low traffic: pool_size: 2-4
  • Medium traffic: pool_size: 4-8
  • High traffic: pool_size: 8-16
SSR module configurationMake sure your production config uses the NodeJS SSR module:
config/prod.exs
config :live_vue,
  ssr_module: LiveVue.SSR.NodeJS,
  ssr_filepath: "./static/server.mjs"

Production checklist

Use this checklist to ensure your LiveVue app is production-ready:
  • Node.js 19+ installed in production environment
  • Assets built using mix assets.deploy
  • SSR configured properly with NodeJS supervisor
  • Database configured and migrations run
  • Environment variables set (SECRET_KEY_BASE, DATABASE_URL, etc.)
  • SSL certificates configured (if needed)
  • Production secrets generated
  • Release configuration tested locally
  • Health checks configured
  • Monitoring and logging set up

Troubleshooting

SSR not working

node --version  # Should show v19.0.0 or higher
If Node.js is not installed or the version is too old, SSR will fail silently and you’ll see empty component divs.
Ensure your config includes:
config :live_vue,
  ssr_module: LiveVue.SSR.NodeJS,
  ssr_filepath: "./static/server.mjs"
And verify the NodeJS supervisor is in your application supervision tree.
Check that priv/static/server.mjs exists in your release:
ls -la priv/static/server.mjs
If missing, ensure mix assets.deploy runs successfully during build.

Asset loading issues

  • Verify assets were built during deployment
  • Check that static directory is included in your release
  • Inspect the digest manifest in priv/static/cache_manifest.json
  • Ensure your endpoint configuration includes static assets:
plug Plug.Static,
  at: "/",
  from: :my_app,
  gzip: false,
  only: ~w(assets fonts images favicon.ico robots.txt)
  • Check browser console for JavaScript errors
  • Verify Vue components are included in the client bundle
  • Ensure getHooks() is properly configured in your app.js
  • Test SSR by checking the initial HTML source

Performance issues

Consider adjusting the NodeJS pool size:
# Increase pool size for more concurrent SSR requests
{NodeJS.Supervisor, [path: LiveVue.SSR.NodeJS.server_path(), pool_size: 8]}
Monitor your application to find the optimal pool size for your traffic patterns.
  • Reduce NodeJS pool size if memory is constrained
  • Consider disabling SSR for some components using v-ssr={false}
  • Profile your Vue components for memory leaks
  • Ensure components are properly unmounted

Build failures

  • Verify Node.js is installed in the build stage
  • Check that package.json and package-lock.json are copied to the build context
  • Ensure network connectivity in the build environment
  • Try running npm ci instead of npm install for more reproducible builds
  • Check that all npm dependencies are installed
  • Verify Vite configuration is correct
  • Look for TypeScript or compilation errors in assets
  • Ensure the assets directory exists and is accessible

Performance optimization tips

Enable compression

Ensure Gzip compression is enabled for static assets:
config/prod.exs
config :my_app, MyAppWeb.Endpoint,
  http: [compress: true]

Use CDN for assets

Consider using a CDN for static assets in high-traffic applications:
config/prod.exs
config :my_app, MyAppWeb.Endpoint,
  static_url: [host: "cdn.example.com", port: 443, scheme: "https"]

Optimize SSR

  • Disable SSR for components that don’t need it using v-ssr={false}
  • Use SSR primarily for initial page load and SEO
  • Consider caching SSR output for frequently accessed pages

Monitor performance

Set up monitoring to track:
  • SSR rendering time
  • WebSocket message sizes
  • Component mount/update times
  • Memory usage and garbage collection

Next steps

Configuration

Fine-tune your production configuration

Architecture

Understand how LiveVue works under the hood

Testing

Test your application before deployment

GitHub Discussions

Get help from the community

Build docs developers (and LLMs) love