07 Full-Stack Deployments

If you have built a full-stack Lustre application then you can use Docker and a platform provider such as Fly.io to deploy your application.

In this guide, you will learn how to manually deploy a Lustre full-stack application to Fly.io using the flyctl CLI. You will also learn how to leverage GitHub Actions for continuous deployments.

If you are planning on deploying a Lustre SPA without a backend, you probably don’t want to follow this guide! Instead, refer to the Lustre SPA deployment guide.

Prerequisites

In this guide, we assume that you have a Lustre full-stack application with the following monorepo structure consisting of three separate Gleam projects:

common/
client/
server/

Here, the common/ directory contains the Lustre application logic which is agnostic to the platform it runs on.

The client/ directory contains the client-side code, which is typically only responsible for the boilerplate necessary to run the Lustre application in the browser. The client-side code uses the JavaScript target and is built with lustre_dev_tools with the --outdir flag set to ../server/priv/static.

The server/ directory contains the server-side code and runs the same Lustre application as a server component. The server-side code uses the Erlang target.

In this guide, we assume this monorepo structure because it happens to be the same structure used in the Lustre full-stack application guide.

If your full-stack application is structured in a slightly different way, don’t worry! You may need to adjust the Dockerfile but otherwise the other sections in this guide should still be applicable.

flyctl

To generate a fly.toml configuration file and to manually deploy your application to Fly.io, you will need the flyctl CLI installed on your local machine. Please refer to the flyctl installation section in the docs.

Dockerfile

Use this Dockerfile as a starting point for your Lustre full-stack application, regardless if you are planning to use manual deployments or continuous deployments with GitHub Actions.

In the Dockerfile, we compile both the client and server code in a separate build stage and then only copy what is needed to the final image. This reduces the final image size and ensures that only the necessary files are included.

ARG GLEAM_VERSION=v1.4.1

FROM ghcr.io/gleam-lang/gleam:${GLEAM_VERSION}-erlang-alpine AS builder

# Add project code
COPY ./common /build/common
COPY ./client /build/client
COPY ./server /build/server

# Compile the client code
RUN cd /build/client \
  && gleam run -m lustre/dev build app --outdir=/build/server/priv/static

# Compile the server code
RUN cd /build/server \
  && gleam export erlang-shipment

# Start from a clean slate
FROM ghcr.io/gleam-lang/gleam:${GLEAM_VERSION}-erlang-alpine

# Copy the compiled server code from the builder stage
COPY --from=builder /build/server/build/erlang-shipment /app

# Run the server
WORKDIR /app
ENTRYPOINT ["/app/entrypoint.sh"]
CMD ["run"]

Note: Make sure to set the GLEAM_VERSION to match your project’s requirements.

Manual Deployment

In this section, we will learn how to manually deploy a Lustre full-stack application to Fly.io using the flyctl CLI.

Setting Up fly.toml

To deploy your Lustre full-stack application to Fly.io, you will need to create a fly.toml configuration file in the root directory of your project. You can create a fly.toml file by running the following command:

fly launch --no-deploy

When prompted, you will need to name your app and select a region. Confirm the settings after making your selections.

Deploying

Once you have set up the fly.toml configuration file and added the Dockerfile to your project, you can now build and deploy your application to Fly.io by running the following command:

flyctl deploy

The flyctl deploy command will build a Docker image of your application and deploy it to Fly.io. The output will include a URL where you can access your application.

Automated Deployments

In this section, we will learn how to set up automated deployments for a Lustre full-stack application using GitHub Actions.

Setting Up fly.toml

If you did not set up a fly.toml configuration file during the manual deployment process, you can create one by running the following command in your project root directory:

fly launch --no-deploy

When prompted, you will need to name your app and select a region. Confirm the settings after making your selections.

Setting Up GitHub Actions

To enable automated deployments you will need a Fly API token. Navigate to the project root directory and run the following command:

fly tokens create deploy -x 999999h

Copy the entire output, including the FlyV1 prefix, and add the Fly API token to your GitHub repository as a repository secret.

  1. Go to your repository on GitHub.
  2. Navigate to “Settings” > “Secrets and variables” > “Actions”.
  3. Create a new repository secret named FLY_API_TOKEN and paste the Fly API token as the value.

With the API token in place, create a new file in your repository at .github/workflows/fly.yml and use the following template as a starting point:

name: Deploy to Fly.io
on:
  push:
    branches:
      - main

jobs:
  deploy:
    name: Deploy to Fly.io
    runs-on: ubuntu-latest
    concurrency: deploy-group
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl deploy --remote-only
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

This workflow:

Deploying

You should now have a fully automated deployment pipeline for your Lustre full-stack application on Fly.io.

Whenever you push changes to your repository, your application will be automatically rebuilt and redeployed.

Search Document