Skip to main content
Version: Next

Deploy Platformatic Applications to Fly.io

Deploying a Platformatic Runtime Application

This guide provides instructions on deploying a Platformatic Runtime application to Fly.io. With a runtime application, you are deploying your entire application, including all services in the services folder.

Dockerfile for Runtime Application

Here is an example Dockerfile for a Platformatic Runtime application:

FROM node:20-alpine AS builder

ENV APP_HOME=/home/app/node/
WORKDIR $APP_HOME

COPY package.json package-lock.json ./
COPY services/devotion/package.json services/devotion/package.json

RUN npm ci

COPY . .

RUN npx platformatic compile

FROM node:20-alpine

ENV APP_HOME=/home/app/node/
WORKDIR $APP_HOME

COPY package.json package-lock.json ./
RUN npm ci --only=production

COPY --from=builder $APP_HOME/dist ./dist

EXPOSE 3042

CMD ["node", "node_modules/.bin/platformatic", "start"]

Explanation

  • ARG VITE_AI_URL and ENV VITE_AI_URL: Sets up environment variables for your application.
  • WORKDIR $APP_HOME: Sets the working directory inside the container.
  • COPY commands: Copies the necessary files and folders into the container.
  • RUN npm install: Installs the dependencies for all services.
  • RUN cd services/...: Installs dependencies and builds each service in the services folder.
  • EXPOSE 3042: Exposes the application port.
  • CMD ["npm", "start"]: Specifies the command to run all services in the application.
  • FROM node:20-alpine: Specifies the base image for the runtime image.
  • RUN npm ci: Installs all dependencies including development dependencies

It's important to create a .dockerignore file in your project's root directory. This file should exclude unnecessary files and directories, such as node_modules, dist, .env, and any other files that are not required in the Docker image. By doing so, you can avoid copying large and redundant files into the Docker image, which can significantly reduce the image size and build time.

Here is an example of a sample .dockerignore file:

node_modules
npm-debug.log
Dockerfile
.dockerignore
.env
*.log
dist

TypeScript Compilation for Deployment

To compile your TypeScript files before deployment, update your platformatic.runtime.json to include TypeScript settings

{
"plugins": {
"paths": [{
"path": "plugins",
"encapsulate": false
}, "routes"],
"typescript": {
"enabled": "{PLT_TYPESCRIPT}",
"outDir": "dist"
}
}
}

Ensure PLT_TYPESCRIPT=true in your .env file for local development. For deployment, set PLT_TYPESCRIPT=false to avoid compiling TypeScript at runtime.

Compile your TypeScript source files with:

plt runtime compile

This compiles your TypeScript files and outputs them to the specified outDir.

Configure Environment

Start with your local environment. Create a .env file and put the following:

PORT=3042
PLT_SERVER_HOSTNAME=127.0.0.1
PLT_SERVER_LOGGER_LEVEL=debug
DATABASE_URL=sqlite://.platformatic/data/movie-quotes.runtime

Avoid accidental leaks by ignoring your .env file:

echo ".env" >> .gitignore

This same configuration needs to be added to fly.toml:

[env]
PORT = 8080
PLT_SERVER_HOSTNAME = "0.0.0.0"
PLT_SERVER_LOGGER_LEVEL = "info"
DATABASE_URL = "sqlite:///app/.platformatic/data/movie-quotes.runtime"

Deploy Application

Before deploying, make sure a .dockerignore file is created:

cp .gitignore .dockerignore

Finally, deploy the application to Fly.io by running:

fly deploy

Deploy a Platformatic DB Application to Fly.io

To follow this how-to guide, you'll first need to install the Fly CLI and create an account by following this official guide. You will also need an existing Platformatic DB project, please check out our getting started guide if needed.

Navigate to your Platformatic DB project in the terminal on your local machine. Run fly launch and follow the prompts. When it asks if you want to deploy now, say "no" as there are a few things that you'll need to configure first.

You can also create the fly application with one line. This will create your application in London (lhr):

fly launch --no-deploy --generate-name --region lhr --org personal --path .

The fly CLI should have created a fly.toml file in your project directory.

Explicit Builder

The fly.toml file may be missing an explicit builder setting. To have consistent builds, it is best to add a build section:

[build]
builder = "heroku/buildpacks:20"

Database Storage

Create a volume for database storage, naming it data:

fly volumes create data

This will create storage in the same region as the application. The volume defaults to 3GB size, use -s to change the size. For example, -s 10 is 10GB.

Add a mounts section in fly.toml:

[mounts]
source = "data"
destination = "/app/.platformatic/data"

Create a directory in your project where your SQLite database will be created:

mkdir -p .platformatic/data

touch .platformatic/data/.gitkeep

The .gitkeep file ensures that this directory will always be created when your application is deployed.

You should also ensure that your SQLite database is ignored by Git. This helps avoid inconsistencies when your application is deployed:

echo "*.db" >> .gitignore

The command above assumes that your SQLite database file ends with the extension .db — if the extension is different then you must change the command to match.

Update your platformatic.json configuration file to use environment variables for the database connection and server settings:

{
"db": {
"connectionString": "{DATABASE_URL}"
},
"migrations": {
"dir": "./migrations",
"autoApply": true
},
"server": {
"logger": {
"level": "{PLT_SERVER_LOGGER_LEVEL}"
},
"hostname": "{PLT_SERVER_HOSTNAME}",
"port": "{PORT}"
}
}

Configure Environment

Start with your local environment, create a .env file and put the following:

PORT=3042
PLT_SERVER_HOSTNAME=127.0.0.1
PLT_SERVER_LOGGER_LEVEL=debug
DATABASE_URL=sqlite://.platformatic/data/movie-quotes.db

Avoid accidental leaks by ignoring your .env file:

echo ".env" >> .gitignore

This same configuration needs to added to fly.toml:

[env]
PORT = 8080
PLT_SERVER_HOSTNAME = "0.0.0.0"
PLT_SERVER_LOGGER_LEVEL = "info"
DATABASE_URL = "sqlite:///app/.platformatic/data/movie-quotes.db"

TypeScript Compilation for Deployment

To compile your TypeScript files before deployment, update your platformatic.json to include TypeScript settings:

{
"plugins": {
"paths": [{
"path": "plugins",
"encapsulate": false
}, "routes"],
"typescript": {
"enabled": "{PLT_TYPESCRIPT}",
"outDir": "dist"
}
}
}

Ensure PLT_TYPESCRIPT=true in your .env file for local development. For deployment, set PLT_TYPESCRIPT=false to avoid compiling TypeScript at runtime.

Compile your TypeScript source files with:

plt service compile 

This compiles your TypeScript files and outputs them to the specified outDir.

Deploy application

A valid package.json will be needed so if you do not have one, generate one by running npm init.

In your package.json, make sure there is a start script to run your application:

{
"scripts": {
"start": "platformatic start"
}
}

Before deploying, make sure a .dockerignore file is created:

cp .gitignore .dockerignore

Finally, deploy the application to Fly by running:

fly deploy