Dockerfile "Production Image" breaks BASE_PATH
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:
- Regular installation from source using
.envfile withBASE_PATH=/analiticaworks fine. - Passing
BASE_PATHin theenviornmentofdocker-composedoes not work. It seems thatBASE_PATHis 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
# ...
- Building the image in
docker-composeand passingBASE_PATHinargspartially works,basePathis 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
- If I use the previous docker-compose with
buildandargsand remove the "Production Image" of theDockerfileit 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.
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.
build-tracker: No envsbuild-geo: MAXMIND_LICENSE_KEYcopy-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.
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
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
This issue is stale because it has been open for 60 days with no activity.
This issue was closed because it has been inactive for 7 days since being marked as stale.