umami icon indicating copy to clipboard operation
umami copied to clipboard

Dockerfile "Production Image" breaks BASE_PATH

Open 1cgonza opened this issue 3 years ago • 2 comments

I am trying to install with docker-compose and noticed a strange behaviour when using BASE_PATH. Here are the steps I followed to troubleshoot:

  1. Regular installation from source using .env file with BASE_PATH=/analitica works fine.
  2. Passing BASE_PATH in the enviornment of docker-compose does not work. It seems that BASE_PATH is ignored. (This is the ideal setup, but there are other issues...)
---
version: '3'
services:
  umami:
    image: ghcr.io/mikecao/umami:postgresql-latest
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://umami:umami@db:5432/umami
      DATABASE_TYPE: postgresql
      HASH_SALT: replace-me-with-a-random-string
      BASE_PATH: /analitica
# ...
  1. Building the image in docker-compose and passing BASE_PATH in args partially works, basePath is properly set in Next, but the assets are not found:
---
version: '3'
services:
  umami:
    # image: ghcr.io/mikecao/umami:postgresql-latest
    ports:
      - '3000:3000'
    build:
      context: .
      args:
        DATABASE_URL: postgresql://umami:umami@db:5432/umami
        DATABASE_TYPE: postgresql
        HASH_SALT: replace-me-with-a-random-string
        BASE_PATH: /analitica

The problem here is that assets end up in the root folder and not in the subfolder so the site is broken and throws 404. For instance:

:x: GET http://localhost:3000/analitica/_next/static/css/ce16c43b6179ab29.css net::ERR_ABORTED 404 (Not Found) :white_check_mark: http://localhost:3000/_next/static/css/ce16c43b6179ab29.css

  1. If I use the previous docker-compose with build and args and remove the "Production Image" of the Dockerfile it works!
# 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
# WORKDIR /app

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

# 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"]

So it seems that the "Production Image" in the Dockerfile is moving the files to the wrong folder, but I can't figure out why. Ideally we should be able to pass BASE_PATH to the environment in docker-compose, but before fixing that, I think that the Dockerfile needs some changes in order to use BASE_PATH in any docker installation.

1cgonza avatar Mar 20 '22 15:03 1cgonza

I think I know why it is not possible to use env variables with docker-compose, the variables have already been set in the base image. During the build process in Dockerfile these are the steps in which env variables are used:

These steps can be built into the image since the DATABASE_TYPE defines if the image is Postgres, MySQL, etc. Now, each db type has its own Docker image.

  1. build-tracker: No envs
  2. build-geo: MAXMIND_LICENSE_KEY
  3. copy-db-schema: DATABASE_TYPE

From here on, the user should be able to define their own variables: 5. build-db-client: DATABASE_URL (which includes: POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD) 6. build-app: BASE_PATH, among others described in https://umami.is/docs/environment-variables

Since steps 5 & 6 are baked into the image, no matter what we use as enviroment variables in docker-compose, the app has already been built with the defaults.

A possible solution is to run the build-db-client and build-app in the last CMD of the dockerfile, that way letting users set their own variables. I am doing some tests now but the resulting image is bloated and slow to startup.

1cgonza avatar Mar 21 '22 15:03 1cgonza

From my observation, the problem is not in a compose and defined BASE_PATH env. variable. When you spinning up your container and in compose.yml file specify your BASE_PATH variable - it does get into container and it does available there!

But! The details are hiding in the build time of the frontend. For the frontend process.env.BASE_PATH get evaluated in a build time and substitute but the empty value by default (when we do not submit an ARG value to the build command). That is why if you need to replace BASE_PATH - you have to build your own image and provide the value for build command.

In the backend BASE_PATH is not used!

About:

The problem here is that assets end up in the root folder and not in the subfolder so the site is broken and throws 404. For instance:

there is no subfolder to be created. The build process will be the same regardless the BASE_PATH. BASE_PATH used only to prefix the url of the frontend.

so, you need to have your nginx or other reverse proxy to proxy_pass your /prefixed_subfolder to the umami's container and don't forget to cut off the prefix , otherwise you will be getting 404.

Basically this is what I have did to handle the base_path (nginx):

location ~ /stat(/|$) {
  rewrite ^/stat/(.*)$ /$1 break;
  proxy_pass http://analytics:3000;
}

[update] Remember to set DATABASE_TYPE build ARG if you use mysql and building your own image

nnmer avatar May 08 '22 18:05 nnmer

Hi,

is there any solution for this issue or could someone describe how to configure nginx? location ~ /stat(/|$) { rewrite ^/stat/(.*)$ /$1 break; proxy_pass http://analytics:3000; } This solution is not totally clear to me. Thanks in advance

Eyk

eyk107 avatar May 02 '23 08:05 eyk107

This issue is stale because it has been open for 60 days with no activity.

github-actions[bot] avatar Aug 19 '23 01:08 github-actions[bot]

This issue was closed because it has been inactive for 7 days since being marked as stale.

github-actions[bot] avatar Aug 26 '23 01:08 github-actions[bot]