fresco 🠖 deployment

Advanced Deployment 

Summary:

This article explains how to deploy Fresco to a VPS or other infrastructure using Docker. For most users, the default deployment process will be sufficient. However, if you are an advanced user, an IT professional, or if you have specific hosting needs, this guide will explain the process.

Prerequisites:

This guide is intended for advanced technical users who are already familiar with Docker and deploying containerised apps. It provides a high-level overview of the steps required to deploy Fresco using Docker, but does not provide detailed instructions for each step.

If you are not already familiar with these technologies, we recommend following our default deployment guide.

Duration:

30 minutes

To assist users who have specialized hosting needs, we have created a Docker container which allows Fresco to be deployed across a variety of contexts, including institutional IT infrastructure, privately owned VPSs, and internal networks. This tutorial will guide you through the requirements of deploying Fresco using our docker image, and will outline the necessary steps.

Requirements for deploying Fresco

Fresco is a NextJS application, which uses Amazon S3 for storage of protocol assets and PostgreSQL for storage of interview and app data.

To deploy Fresco, you'll need:

Environment Variables

Fresco is configured using environment variables. These variables specify how to connect to the PostgreSQL database, the keys for using the UploadThing service, and the URL of the Fresco instance.

Create an .env file somewhere on your host machine using the template below. The next steps will guide you through setting up the environment variables and adding them to this file.

# -------------------
# Optional environment variables
# -------------------

# If true, the app will not send anonymous analytics and error data. Defaults to false.                  
#DISABLE_ANALYTICS=

# -------------------
# Required environment variables
# -------------------

UPLOADTHING_SECRET=
UPLOADTHING_APP_ID=

POSTGRES_PRISMA_URL=
POSTGRES_URL_NON_POOLING=

PUBLIC_URL=

Create a storage bucket using UploadThing

Fresco uses a third-party service called 'UploadThing' to store media files, including protocol assets. In order to use this service, you need to create an account with UploadThing that will allow you to generate an API key that Fresco can use to securely communicate with it.

To create an app on UploadThing:

  1. Go to uploadthing.com.

  2. Click "Get started".

    Select "Get Started"
    Select "Get Started"
  3. Sign in with Github.

  4. Authorize UploadThing by clicking "Authorize pingdotgg".

  5. You will be prompted to navigate to your dashboard. From the dashboard Click "Create a new app".

    Create a new app
    Create a new app
  6. Give your app a name and click "Create App". Performance can be improved by selecting a region close to your server, although this will require a paid plan.

    Create app
    Create app
  7. From your dashboard, navigate to the "API Keys" section from the sidebar and copy your API keys using the copy button.

    Copy your API keys
    Copy your API keys
  8. Pate your API keys into the .env file you created in the previous step:

# -------------------
# Optional environment variables
# -------------------

# If true, the app will not send anonymous analytics and error data. Defaults to false.                  
#DISABLE_ANALYTICS=

# -------------------
# Required environment variables
# -------------------
UPLOADTHING_SECRET=sk-your-secret-key
UPLOADTHING_APP_ID=your-app-id

POSTGRES_PRISMA_URL=
POSTGRES_URL_NON_POOLING=

PUBLIC_URL=

Postgres Configuration

Fresco uses a PostgreSQL database to store protocol and interview data. You will need to set up a PostgreSQL database on your server, or provide connection details to an external service.

Fresco requires two connection strings to PostgreSQL:

VariableDetails
POSTGRES_PRISMA_URLA pooled connection URL for Prisma. Connection pooling allows for efficient re-use of connections, and avoids potential issues caused by large numbers of concurrent users.
POSTGRES_URL_NON_POOLINGA non-pooling connection URL for Prisma. This is primarily used for database migrations when upgrading.

If you do not have a connection pooler such as PgBouncer, you can use the same connection string for both variables (although this may lead to database errors under heavy load).

If your database is hosted on a service such as PlanetScale or Neon, use the connection strings provided by these services directly.

Add your connection strings to the .env file:

# -------------------
# Optional environment variables
# -------------------

# If true, the app will not send anonymous analytics and error data. Defaults to false.                  
#DISABLE_ANALYTICS=

# -------------------
# Required environment variables
# -------------------
UPLOADTHING_SECRET=sk-your-secret-key
UPLOADTHING_APP_ID=your-app-id

POSTGRES_PRISMA_URL=postgresql://username:password@hostname:port/dbname
POSTGRES_URL_NON_POOLING=postgresql://username:password@hostname:port/dbname

PUBLIC_URL=

Setting the Public URL

The PUBLIC_URL variable is used to configure the URL of your Fresco instance. This is the URL that users will use to access the application, and is used to generate links for study participation. The URL you provide must be accessible from the Internet via HTTPS, with a valid certificate.

If you intend to run your instance on a LAN or private network, at least the api/uploadthing endpoint must be accessible from the Internet. This is used as a callback for uploads to Amazon S3.

Add your URL to the .env file:

# -------------------
# Optional environment variables
# -------------------

# If true, the app will not send anonymous analytics and error data. Defaults to false.                  
#DISABLE_ANALYTICS=

# -------------------
# Required environment variables
# -------------------
UPLOADTHING_SECRET=sk-your-secret-key
UPLOADTHING_APP_ID=your-app-id

POSTGRES_PRISMA_URL=postgresql://username:password@hostname:port/dbname
POSTGRES_URL_NON_POOLING=postgresql://username:password@hostname:port/dbname

PUBLIC_URL=https://your-public-url.com

Running the Application

The Fresco docker image is hosted on the GitHub container registry (ghcr.io). You can browse published images on the Fresco repository. We provide two types of tags for our images:

The container starts a NodeJS based server running on port 3000 by default. You can map this port to any port on your host machine (for example if using an ingress manager such as Traefik), although as mentioned above you must ensure that the application itself is accessed via HTTPS when used.

To pull this image and create a container using your .env file as a source of environment variables, use the following command:

docker run --env-file .env -p 443:3000 ghcr.io/complexdatacollective/fresco:latest

Container Orchestration with Docker Compose

You can optionally use Docker Compose to manage the Postgres container in tandem with the Fresco container. For your convenience, here is a sample docker-compose.yml file that you can use to deploy Fresco with Docker Compose:

services:
  fresco:
    environment:
      - UPLOADTHING_SECRET=sk-your-secret-key
      - UPLOADTHING_APP_ID=your-app-id
      - POSTGRES_PRISMA_URL=postgresql://username:password@postgres:5432/fresco
      - POSTGRES_URL_NON_POOLING=postgresql://username:password@postgres:5432/fresco
      - PUBLIC_URL=https://your-public-url.com
    image: 'ghcr.io/complexdatacollective/fresco:latest'
    depends_on:
      postgres:
        condition: service_healthy
    volumes:
      - .:/app/next-app
    restart: always
    ports:
      - 0:3000
    networks:
      - fresco_network

  postgres:
    image: postgres:16-alpine
    restart: always
    environment:
      POSTGRES_DB: fresco
      POSTGRES_USER: username
      POSTGRES_PASSWORD: password
    volumes:
      - postgres:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD', 'pg_isready', '-U', 'postgres']
      interval: 5s
      timeout: 10s
      retries: 5
    networks:
      - fresco_network

volumes:
  postgres:

networks:
  fresco_network:

Start up your application using this file by running the following command:

docker-compose up -d -f docker-compose.yml

Access Fresco

You can now access Fresco by visiting the PUBLIC_URL that you have configured. You should be greeted with the onboarding wizard, which will guide you through the process of setting up Fresco.

For details on this process, refer to the configuration and setup section of the basic deployment guide.

Updating Fresco

To update Fresco, you can pull the latest image from the GitHub container registry and recreate your container.

docker pull ghcr.io/complexdatacollective/fresco:latest
docker stop fresco
docker rm fresco
docker run --env-file .env -p 443:3000 ghcr.io/complexdatacollective/fresco:latest

If you are using Docker Compose, you can use the following command:

docker-compose up -d -f docker-compose.yml