mirror of
https://github.com/rajnandan1/kener.git
synced 2026-06-23 04:10:22 +00:00
chore: Enhance Docker and documentation for subpath deployment support
This commit is contained in:
@@ -0,0 +1,97 @@
|
|||||||
|
name: Create Release (Deterministic)
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: "Release version (for example: 4.0.0)"
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
make_latest:
|
||||||
|
description: "Mark this release as latest"
|
||||||
|
required: true
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
prerelease:
|
||||||
|
description: "Mark as pre-release"
|
||||||
|
required: true
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
create-release:
|
||||||
|
name: Bump version, tag, and create release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out default branch
|
||||||
|
uses: actions/checkout@v4.2.2
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.repository.default_branch }}
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Validate version format
|
||||||
|
run: |
|
||||||
|
VERSION="${{ inputs.version }}"
|
||||||
|
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
|
||||||
|
echo "Invalid version format: $VERSION"
|
||||||
|
echo "Use semver like 4.0.0 or 4.0.0-rc.1"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Ensure release tag does not already exist
|
||||||
|
run: |
|
||||||
|
TAG="v${{ inputs.version }}"
|
||||||
|
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
||||||
|
echo "Tag $TAG already exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Bump package version
|
||||||
|
run: |
|
||||||
|
VERSION="${{ inputs.version }}"
|
||||||
|
CURRENT_VERSION="$(node -p \"require('./package.json').version\")"
|
||||||
|
|
||||||
|
if [ "$CURRENT_VERSION" != "$VERSION" ]; then
|
||||||
|
npm version "$VERSION" --no-git-tag-version --allow-same-version
|
||||||
|
else
|
||||||
|
echo "package.json already at version $VERSION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Commit version bump
|
||||||
|
run: |
|
||||||
|
VERSION="${{ inputs.version }}"
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
|
git add package.json
|
||||||
|
if [ -f package-lock.json ]; then
|
||||||
|
git add package-lock.json
|
||||||
|
fi
|
||||||
|
|
||||||
|
if git diff --cached --quiet; then
|
||||||
|
echo "No changes to commit"
|
||||||
|
else
|
||||||
|
git commit -m "chore(release): bump version to $VERSION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create and push git tag
|
||||||
|
run: |
|
||||||
|
VERSION="${{ inputs.version }}"
|
||||||
|
TAG="v$VERSION"
|
||||||
|
|
||||||
|
git tag -a "$TAG" -m "Release $TAG"
|
||||||
|
git push origin "HEAD:${{ github.event.repository.default_branch }}"
|
||||||
|
git push origin "$TAG"
|
||||||
|
|
||||||
|
- name: Create GitHub release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
tag_name: v${{ inputs.version }}
|
||||||
|
target_commitish: ${{ github.event.repository.default_branch }}
|
||||||
|
generate_release_notes: true
|
||||||
|
make_latest: ${{ inputs.make_latest && 'true' || 'false' }}
|
||||||
|
prerelease: ${{ inputs.prerelease }}
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
name: Publish Release Docker Images
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types:
|
||||||
|
- published
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
DOCKERHUB_REGISTRY: docker.io
|
||||||
|
GITHUB_REGISTRY: ghcr.io
|
||||||
|
DOCKERHUB_IMAGE_NAME: ${{ secrets.DOCKER_USERNAME }}/${{ github.event.repository.name }}
|
||||||
|
GITHUB_IMAGE_NAME: ${{ github.repository }}
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: release-docker-${{ github.event.release.tag_name || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push-release:
|
||||||
|
name: Build and push release Docker images
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
variant: [debian, alpine]
|
||||||
|
base_path: ["", "/status"]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out release tag
|
||||||
|
uses: actions/checkout@v4.2.2
|
||||||
|
with:
|
||||||
|
ref: refs/tags/${{ github.event.release.tag_name || github.ref_name }}
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Validate package version matches release tag
|
||||||
|
run: |
|
||||||
|
TAG="${{ github.event.release.tag_name || github.ref_name }}"
|
||||||
|
EXPECTED_VERSION="${TAG#v}"
|
||||||
|
PACKAGE_VERSION="$(node -p \"require('./package.json').version\")"
|
||||||
|
|
||||||
|
if [ "$PACKAGE_VERSION" != "$EXPECTED_VERSION" ]; then
|
||||||
|
echo "package.json version mismatch"
|
||||||
|
echo "release tag: $TAG"
|
||||||
|
echo "expected package.json version: $EXPECTED_VERSION"
|
||||||
|
echo "actual package.json version: $PACKAGE_VERSION"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Install cosign
|
||||||
|
uses: sigstore/cosign-installer@v3.8.0
|
||||||
|
with:
|
||||||
|
cosign-release: v2.2.4
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3.8.0
|
||||||
|
|
||||||
|
- name: Log in to Docker Hub
|
||||||
|
uses: docker/login-action@v3.3.0
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Log in to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v3.3.0
|
||||||
|
with:
|
||||||
|
registry: ${{ env.GITHUB_REGISTRY }}
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Compute release tags
|
||||||
|
id: vars
|
||||||
|
run: |
|
||||||
|
TAG="${{ github.event.release.tag_name || github.ref_name }}"
|
||||||
|
NORM_TAG="${TAG#v}"
|
||||||
|
|
||||||
|
if [ "${{ matrix.base_path }}" = "/status" ]; then
|
||||||
|
BASE_SUFFIX="-status"
|
||||||
|
else
|
||||||
|
BASE_SUFFIX=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${{ matrix.variant }}" = "alpine" ]; then
|
||||||
|
VARIANT_SUFFIX="-alpine"
|
||||||
|
else
|
||||||
|
VARIANT_SUFFIX=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
FULL_SUFFIX="${BASE_SUFFIX}${VARIANT_SUFFIX}"
|
||||||
|
|
||||||
|
echo "release_tag=${TAG}${FULL_SUFFIX}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "release_norm_tag=${NORM_TAG}${FULL_SUFFIX}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "latest_tag=latest${FULL_SUFFIX}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
if [ "${{ matrix.variant }}" = "debian" ]; then
|
||||||
|
echo "release_tag_debian_alias=${TAG}${BASE_SUFFIX}-debian" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "release_norm_tag_debian_alias=${NORM_TAG}${BASE_SUFFIX}-debian" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "latest_tag_debian_alias=latest${BASE_SUFFIX}-debian" >> "$GITHUB_OUTPUT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Extract Docker metadata
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5.6.1
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
${{ env.DOCKERHUB_IMAGE_NAME }}
|
||||||
|
${{ env.GITHUB_REGISTRY }}/${{ env.GITHUB_IMAGE_NAME }}
|
||||||
|
tags: |
|
||||||
|
type=raw,value=${{ steps.vars.outputs.latest_tag }}
|
||||||
|
type=raw,value=${{ steps.vars.outputs.release_tag }}
|
||||||
|
type=raw,value=${{ steps.vars.outputs.release_norm_tag }},enable=${{ steps.vars.outputs.release_norm_tag != steps.vars.outputs.release_tag }}
|
||||||
|
type=raw,value=${{ steps.vars.outputs.latest_tag_debian_alias }},enable=${{ matrix.variant == 'debian' }}
|
||||||
|
type=raw,value=${{ steps.vars.outputs.release_tag_debian_alias }},enable=${{ matrix.variant == 'debian' }}
|
||||||
|
type=raw,value=${{ steps.vars.outputs.release_norm_tag_debian_alias }},enable=${{ matrix.variant == 'debian' && steps.vars.outputs.release_norm_tag_debian_alias != steps.vars.outputs.release_tag_debian_alias }}
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3.3.0
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
id: build-and-push
|
||||||
|
uses: docker/build-push-action@v6.13.0
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
build-args: |
|
||||||
|
VARIANT=${{ matrix.variant }}
|
||||||
|
WITH_DOCS=true
|
||||||
|
KENER_BASE_PATH=${{ matrix.base_path }}
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
- name: Sign the published Docker images
|
||||||
|
env:
|
||||||
|
TAGS: ${{ steps.meta.outputs.tags }}
|
||||||
|
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
||||||
|
run: |
|
||||||
|
echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
ARG NODE_VERSION=24
|
ARG NODE_VERSION=24
|
||||||
ARG VARIANT=alpine
|
ARG VARIANT=alpine
|
||||||
ARG WITH_DOCS=false
|
ARG WITH_DOCS=false
|
||||||
|
ARG KENER_BASE_PATH=
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# STAGE 1 — BUILDER (installs deps, compiles native modules, builds app)
|
# STAGE 1 — BUILDER (installs deps, compiles native modules, builds app)
|
||||||
@@ -52,6 +53,9 @@ ENV NPM_CONFIG_LOGLEVEL=error
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
ARG KENER_BASE_PATH
|
||||||
|
ENV KENER_BASE_PATH=${KENER_BASE_PATH}
|
||||||
|
|
||||||
# 1. Copy package manifests first (maximises layer cache hits)
|
# 1. Copy package manifests first (maximises layer cache hits)
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
|
|
||||||
@@ -126,9 +130,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
FROM final-${VARIANT} AS final
|
FROM final-${VARIANT} AS final
|
||||||
|
|
||||||
ARG PORT=3000
|
ARG PORT=3000
|
||||||
|
ARG KENER_BASE_PATH=
|
||||||
|
|
||||||
ENV NODE_ENV=production \
|
ENV NODE_ENV=production \
|
||||||
PORT=${PORT} \
|
PORT=${PORT} \
|
||||||
|
KENER_BASE_PATH=${KENER_BASE_PATH} \
|
||||||
TZ=UTC \
|
TZ=UTC \
|
||||||
# Required so Node can import .ts migration/seed files at runtime
|
# Required so Node can import .ts migration/seed files at runtime
|
||||||
NODE_OPTIONS="--experimental-strip-types"
|
NODE_OPTIONS="--experimental-strip-types"
|
||||||
|
|||||||
@@ -106,6 +106,13 @@ You can use either image:
|
|||||||
- `docker.io/rajnandan1/kener:latest`
|
- `docker.io/rajnandan1/kener:latest`
|
||||||
- `ghcr.io/rajnandan1/kener:latest`
|
- `ghcr.io/rajnandan1/kener:latest`
|
||||||
|
|
||||||
|
For subpath deployments (`/status`), use:
|
||||||
|
|
||||||
|
- `docker.io/rajnandan1/kener:latest-status`
|
||||||
|
- `docker.io/rajnandan1/kener:latest-status-alpine`
|
||||||
|
- `ghcr.io/rajnandan1/kener:latest-status`
|
||||||
|
- `ghcr.io/rajnandan1/kener:latest-status-alpine`
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p database
|
mkdir -p database
|
||||||
docker run -d \
|
docker run -d \
|
||||||
@@ -118,6 +125,24 @@ docker run -d \
|
|||||||
docker.io/rajnandan1/kener:latest
|
docker.io/rajnandan1/kener:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Run pre-built subpath image (`/status`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p database
|
||||||
|
docker run -d \
|
||||||
|
--name kener-status \
|
||||||
|
-p 3000:3000 \
|
||||||
|
-v "$(pwd)/database:/app/database" \
|
||||||
|
-e "KENER_SECRET_KEY=replace_with_a_random_string" \
|
||||||
|
-e "ORIGIN=http://localhost:3000" \
|
||||||
|
-e "KENER_BASE_PATH=/status" \
|
||||||
|
-e "REDIS_URL=redis://host.docker.internal:6379" \
|
||||||
|
docker.io/rajnandan1/kener:latest-status
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> For subpath mode, keep `ORIGIN` as the site origin (`http://localhost:3000`), not `http://localhost:3000/status`.
|
||||||
|
|
||||||
### Run without Docker
|
### Run without Docker
|
||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ services:
|
|||||||
VARIANT: alpine # or "debian"
|
VARIANT: alpine # or "debian"
|
||||||
NODE_VERSION: 24
|
NODE_VERSION: 24
|
||||||
WITH_DOCS: "true"
|
WITH_DOCS: "true"
|
||||||
|
KENER_BASE_PATH: ""
|
||||||
container_name: kener-dev
|
container_name: kener-dev
|
||||||
environment:
|
environment:
|
||||||
KENER_SECRET_KEY: dev-secret-key-for-local-testing-only
|
KENER_SECRET_KEY: dev-secret-key-for-local-testing-only
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# Kener v4 — Production Docker Compose for /status base path
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# docker compose -f docker-compose.status.yml up -d
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
services:
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: kener-redis-status
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- redis_data:/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
kener:
|
||||||
|
image: rajnandan1/kener:latest-status
|
||||||
|
# For Alpine variant use: rajnandan1/kener:latest-status-alpine
|
||||||
|
container_name: kener-status
|
||||||
|
environment:
|
||||||
|
KENER_SECRET_KEY: replace_me_with_a_random_string # generate: openssl rand -base64 32
|
||||||
|
ORIGIN: http://localhost:3000/status
|
||||||
|
REDIS_URL: redis://redis:6379
|
||||||
|
KENER_BASE_PATH: /status
|
||||||
|
|
||||||
|
# DATABASE_URL: sqlite://./database/kener.sqlite.db
|
||||||
|
# DATABASE_URL: postgresql://user:password@postgres:5432/kener
|
||||||
|
# DATABASE_URL: mysql://user:password@mysql:3306/kener
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
volumes:
|
||||||
|
- data:/app/database
|
||||||
|
depends_on:
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
data:
|
||||||
|
name: kener_db_status
|
||||||
|
redis_data:
|
||||||
|
name: kener_redis_status
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="theme-plus-bar sticky top-18 z-20 flex w-full items-center gap-2 overflow-x-auto rounded py-2">
|
<div class="theme-plus-bar scrollbar-hidden sticky top-18 z-20 flex w-full items-center gap-2 rounded py-2">
|
||||||
<PageSelector />
|
<PageSelector />
|
||||||
<div class="ml-auto flex shrink-0 items-center gap-2">
|
<div class="ml-auto flex shrink-0 items-center gap-2">
|
||||||
{#if page.data.isSubsEnabled && page.data.canSendEmail}
|
{#if page.data.isSubsEnabled && page.data.canSendEmail}
|
||||||
|
|||||||
@@ -240,6 +240,10 @@
|
|||||||
{
|
{
|
||||||
"title": "Reverse Proxy Setup",
|
"title": "Reverse Proxy Setup",
|
||||||
"content": "v4/guides/reverse-proxy"
|
"content": "v4/guides/reverse-proxy"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Base Path Deployment",
|
||||||
|
"content": "v4/guides/base-path"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
---
|
||||||
|
title: Base Path Deployment
|
||||||
|
description: Deploy Kener under a subpath like /status using KENER_BASE_PATH with Docker and reverse proxies
|
||||||
|
---
|
||||||
|
|
||||||
|
Use this guide when Kener should be served from a subpath (for example `https://example.com/status`) instead of domain root.
|
||||||
|
|
||||||
|
## Quick setup {#quick-setup}
|
||||||
|
|
||||||
|
Set these values:
|
||||||
|
|
||||||
|
| Variable | Value for subpath setup |
|
||||||
|
| :---------------- | :---------------------- |
|
||||||
|
| `KENER_BASE_PATH` | `/status` |
|
||||||
|
| `ORIGIN` | `https://example.com` |
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> `ORIGIN` must be the site origin only (scheme + host + optional port), not the full `/status` URL.
|
||||||
|
|
||||||
|
## Prebuilt Docker images for subpath {#prebuilt-images}
|
||||||
|
|
||||||
|
Use the prebuilt subpath tags:
|
||||||
|
|
||||||
|
- `docker.io/rajnandan1/kener:latest-status`
|
||||||
|
- `docker.io/rajnandan1/kener:latest-status-alpine`
|
||||||
|
- `ghcr.io/rajnandan1/kener:latest-status`
|
||||||
|
- `ghcr.io/rajnandan1/kener:latest-status-alpine`
|
||||||
|
|
||||||
|
Release tags follow the same pattern:
|
||||||
|
|
||||||
|
- `vX.Y.Z-status`
|
||||||
|
- `vX.Y.Z-status-alpine`
|
||||||
|
|
||||||
|
## Run with Docker {#run-docker}
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name kener-status \
|
||||||
|
-p 3000:3000 \
|
||||||
|
-v "$(pwd)/database:/app/database" \
|
||||||
|
-e "KENER_SECRET_KEY=replace_with_a_random_string" \
|
||||||
|
-e "ORIGIN=https://example.com" \
|
||||||
|
-e "KENER_BASE_PATH=/status" \
|
||||||
|
-e "REDIS_URL=redis://host.docker.internal:6379" \
|
||||||
|
docker.io/rajnandan1/kener:latest-status
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run with Docker Compose {#run-compose}
|
||||||
|
|
||||||
|
Use the provided `docker-compose.status.yml` file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f docker-compose.status.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
This compose file already sets:
|
||||||
|
|
||||||
|
- `image: rajnandan1/kener:latest-status`
|
||||||
|
- `KENER_BASE_PATH: /status`
|
||||||
|
|
||||||
|
## Reverse proxy mapping {#reverse-proxy-mapping}
|
||||||
|
|
||||||
|
Your proxy path and `KENER_BASE_PATH` must match exactly.
|
||||||
|
|
||||||
|
For `/status`, proxy traffic to Kener on the same `/status` path.
|
||||||
|
|
||||||
|
For full examples, see [Reverse Proxy Setup](/docs/v4/guides/reverse-proxy).
|
||||||
|
|
||||||
|
## Verify setup {#verify-setup}
|
||||||
|
|
||||||
|
Check these URLs:
|
||||||
|
|
||||||
|
- `https://example.com/status`
|
||||||
|
- `https://example.com/status/healthcheck`
|
||||||
|
|
||||||
|
If CSS/JS files 404, re-check:
|
||||||
|
|
||||||
|
1. `KENER_BASE_PATH` is set to `/status`
|
||||||
|
2. proxy path is also `/status`
|
||||||
|
3. Kener was rebuilt/restarted after env changes
|
||||||
|
|
||||||
|
## Related docs {#related-docs}
|
||||||
|
|
||||||
|
- [Environment Variables](/docs/v4/setup/environment-variables)
|
||||||
|
- [Reverse Proxy Setup](/docs/v4/guides/reverse-proxy)
|
||||||
@@ -19,6 +19,8 @@ Running Kener behind a reverse proxy is the recommended approach for production
|
|||||||
|
|
||||||
## Before You Begin {#before-you-begin}
|
## Before You Begin {#before-you-begin}
|
||||||
|
|
||||||
|
If you specifically need `/status` (or any subpath) deployment, follow [Base Path Deployment](/docs/v4/guides/base-path) first, then return here for your proxy-specific config.
|
||||||
|
|
||||||
### Prerequisites {#prerequisites}
|
### Prerequisites {#prerequisites}
|
||||||
|
|
||||||
- Kener running on port 3000 (or custom port)
|
- Kener running on port 3000 (or custom port)
|
||||||
|
|||||||
Reference in New Issue
Block a user