Deploying Umami

Hi folks!

I’m trying to deploy umami on fly.io. Currently running into some issues. As of last weekend, I was able to put up a postgres instance, proxy to my localhost and run the sql script with no issues.
The issues that I’m running into are building/deploying the web app console, and then logging into said web app console. With a docker build, the web app is unable to get into a healthy state. It’s stuck in a critical state. I am specifying the build argument --build-arg DATABASE_TYPE=postgresql as is required for the docker build and then also changing the DATABASE_URL inside the Dockerfile to the output after attaching the postgres instance to the app.
I also tried to build from source (I removed the Dockerfile, and added a .env file) and I did get a bit closer with the web app at least starting. However I get an internal 500 error code when trying to log into the web app with the default credentials.

I’d be happy to provide more info if needed. Could anyone try and get this running too? Thanks in advance!

Documentation for umami here

Hey @luap, umani seems like an interesting project that perhaps the community would love so I went ahead and tried to deploy it myself. I made a few modifications to the Dockerfileand added a migration.sh script to make the experience a bit more pleasant but everything afterward was smooth.

  1. After making a local copy for the repository make these changes to the Dockerfile
# Build image
FROM node:12.22-alpine AS build
ARG BASE_PATH
ARG DATABASE_TYPE

ENV BASE_PATH=$BASE_PATH
ENV DATABASE_URL "postgresql://umami:umami@db:5432/umami"
ENV DATABASE_TYPE=$DATABASE_TYPE

WORKDIR /build

RUN yarn config set --home enableTelemetry 0
COPY package.json yarn.lock /build/

# Install only the production dependencies
RUN yarn install --production --frozen-lockfile

# Cache these modules for production
RUN cp -R node_modules/ prod_node_modules/

# Install development dependencies
RUN yarn install --frozen-lockfile

COPY . /build
RUN yarn next telemetry disable
RUN yarn build

# Production image
FROM node:12.22-alpine AS production

+ RUN apk --update add postgresql-client

WORKDIR /app

# Copy cached dependencies
COPY --from=build /build/prod_node_modules ./node_modules

+ # COPY sql migration to make them available to the release command
+ COPY --from=build /build/sql ./sql
+ COPY --from=build /build/migrate.sh ./migrate.sh
+ RUN chmod +x ./migrate.sh

# Copy generated Prisma client
COPY --from=build /build/node_modules/.prisma/ ./node_modules/.prisma/

COPY --from=build /build/yarn.lock /build/package.json ./
COPY --from=build /build/.next ./.next
COPY --from=build /build/public ./public

USER node

EXPOSE 3000
CMD ["yarn", "start"]
  1. Run fly launch --name <app-name> --org personal to create an app and generate a fly.toml file. This command will prompt you for a few things:
  • Creating a database that you can skip if already have one and instead run fly pg attach later. If you do choose to create one it’s name will be <app-name>-db and flyctl will create a DATABASE_URL variable for you.
  • The next prompt will ask you whether you want to deploy now. To which you should say no since we have to make a few modifications to the fly.toml before.
  1. Set the HASH_SALT secret: fly secrets set HASH_SALT=$SECRET

  2. Add a release command to fly.toml.

# fly.toml file generated for umani-test on 2022-05-12T11:02:12+02:00

app = "umani-test"

kill_signal = "SIGINT"
kill_timeout = 5
processes = []

+ [env]
+ DATABASE_TYPE = "PostgreSQL"

+ [deploy]

+ release_command = "./migrate.sh"

[experimental]
allowed_public_ports = []
auto_rollback = true

[[services]]
 http_checks = []
- internal_port = 8080
+ internal_port = 3000
processes = ["app"]
protocol = "tcp"
script_checks = []

[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"

[[services.ports]]
force_https = true
handlers = ["http"]
port = 80

[[services.ports]]
handlers = ["tls", "http"]
port = 443

[[services.tcp_checks]]
grace_period = "1s"
interval = "15s"
restart_limit = 0
timeout = "2s"

The content of migrate.sh are of course:

#!/bin/sh

set -e

psql $DATABASE_URL -f sql/schema.postgresql.sql

You should also notice the DATABASE_TYPE set as an environment variable and the internal_port change to match umami.

  1. Now you can run fly deploy

Hey, thanks for the fast response!

I was able to deploy both the console and database using the above instructions. I generated code from the dashboard and added the javascript snippet to my localhost site and it is receiving traffic. However, I’m getting a series of 500 errors going through data that is hitting umami. The error is:

2022-05-13T03:37:24Z app[7071e349] sjc [info]Error: Unknown database.
2022-05-13T03:37:24Z app[7071e349] sjc [info]    at rawQuery (/app/.next/server/chunks/9718.js:701:31)
2022-05-13T03:37:24Z app[7071e349] sjc [info]    at getActiveVisitors (/app/.next/server/chunks/9718.js:1017:12)
2022-05-13T03:37:24Z app[7071e349] sjc [info]    at __WEBPACK_DEFAULT_EXPORT__ (/app/.next/server/pages/api/website/[id]/active.js:132:102)
2022-05-13T03:37:24Z app[7071e349] sjc [info]    at async Object.apiResolver (/app/node_modules/next/dist/server/api-utils/node.js:182:9)
2022-05-13T03:37:24Z app[7071e349] sjc [info]    at async NextNodeServer.runApi (/app/node_modules/next/dist/server/next-server.js:386:9)
2022-05-13T03:37:24Z app[7071e349] sjc [info]    at async Object.fn (/app/node_modules/next/dist/server/base-server.js:488:37)
2022-05-13T03:37:24Z app[7071e349] sjc [info]    at async Router.execute (/app/node_modules/next/dist/server/router.js:228:32)
2022-05-13T03:37:24Z app[7071e349] sjc [info]    at async NextNodeServer.run (/app/node_modules/next/dist/server/base-server.js:600:29)
2022-05-13T03:37:24Z app[7071e349] sjc [info]    at async NextNodeServer.handleRequest (/app/node_modules/next/dist/server/base-server.js:307:20)

Maybe we need to make a correction to the database URL somehow? This might be out of scope of fly.io. I’ll do some more searching on my end.

I ended up figuring out the issue. There needs to be a change to the fly.toml file. It should be DATABASE_TYPE = "postgresql" rather than DATABASE_TYPE = "PostgreSQL" . There’s code here that checks the database type that’s case sensitive here: umami/queries.js at master · mikecao/umami · GitHub and it’s defined here: umami/constants.js at master · mikecao/umami · GitHub

I think you should update your reply so people don’t run into this issue into the future @rugwiro .

Also on another note for anyone reading this in the future, if you’re looking to make non-atomic changes to the database, I’d highly suggest removing the release_command = "./migrate.sh" from the fly.toml file after the initial deployment so your data doesn’t get blown away. There’s definitely a more elegant solution to this but I’ll leave it as a suggestion for now.