Skip to content

Commit 55b994c

Browse files
authored
feat: runtime env (#320)
* feat: runtime env Signed-off-by: Innei <[email protected]> * feat: build script Signed-off-by: Innei <[email protected]> * update Signed-off-by: Innei <[email protected]> * fix: update Signed-off-by: Innei <[email protected]> --------- Signed-off-by: Innei <[email protected]>
1 parent f20edb9 commit 55b994c

File tree

27 files changed

+238
-139
lines changed

27 files changed

+238
-139
lines changed

.env.template

+2
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ TMDB_API_KEY=
1919

2020
S3_ACCESS_KEY=
2121
S3_SECRET_KEY=
22+
23+
GH_TOKEN=

.github/workflows/build.yml

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
on:
2+
push:
3+
branches: [main]
4+
5+
name: CI Build
6+
7+
jobs:
8+
build:
9+
name: Upload CI Build artifact
10+
runs-on: ubuntu-latest
11+
12+
strategy:
13+
matrix:
14+
node-version: [18.x]
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0
20+
lfs: true
21+
- name: Checkout LFS objects
22+
run: git lfs checkout
23+
24+
- uses: pnpm/[email protected]
25+
with:
26+
version: 8.x.x
27+
- name: Use Node.js ${{ matrix.node-version }}
28+
uses: actions/setup-node@v3
29+
with:
30+
node-version: ${{ matrix.node-version }}
31+
cache: 'pnpm'
32+
- name: Install dependencies
33+
run: pnpm install
34+
- name: Build project
35+
36+
run: |
37+
sh ./ci-release-build.sh
38+
39+
- uses: actions/upload-artifact@v4
40+
with:
41+
name: artifact
42+
path: assets/release.zip

.github/workflows/release-docker.yml

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Docker (release)
2+
3+
on:
4+
push:
5+
# Sequence of patterns matched against refs/tags
6+
tags:
7+
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
8+
9+
jobs:
10+
docker:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v4
15+
- name: Set up QEMU
16+
uses: docker/setup-qemu-action@v3
17+
- name: Set up Docker Buildx
18+
uses: docker/setup-buildx-action@v3
19+
- name: Login to Docker Hub
20+
uses: docker/login-action@v3
21+
with:
22+
username: ${{ secrets.DOCKERHUB_USERNAME }}
23+
password: ${{ secrets.DOCKERHUB_TOKEN }}
24+
25+
- name: Docker meta
26+
id: meta
27+
uses: docker/metadata-action@v5
28+
with:
29+
images: |
30+
innei/mx-server
31+
tags: |
32+
type=ref,event=branch
33+
type=semver,pattern={{version}}
34+
type=semver,pattern={{major}}.{{minor}}
35+
type=semver,pattern={{major}}
36+
type=sha
37+
type=raw,value=latest
38+
- name: Build and export to Docker
39+
uses: docker/build-push-action@v5
40+
with:
41+
context: .
42+
load: true
43+
tags: ${{ steps.meta.outputs.tags }}
44+
labels: ${{ steps.meta.outputs.labels }}
45+
push: true
46+
env:
47+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release.yml

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
on:
2+
push:
3+
# Sequence of patterns matched against refs/tags
4+
tags:
5+
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
6+
7+
name: Release
8+
9+
jobs:
10+
build:
11+
name: Upload Release Asset
12+
runs-on: ubuntu-latest
13+
strategy:
14+
matrix:
15+
node-version: [18.x]
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0
21+
lfs: true
22+
- name: Checkout LFS objects
23+
run: git lfs checkout
24+
25+
- uses: pnpm/[email protected]
26+
with:
27+
version: 8.x.x
28+
- name: Use Node.js ${{ matrix.node-version }}
29+
uses: actions/setup-node@v3
30+
with:
31+
node-version: ${{ matrix.node-version }}
32+
cache: 'pnpm'
33+
- name: Install dependencies
34+
run: pnpm install
35+
- name: Build project
36+
37+
run: |
38+
sh ./ci-release-build.sh
39+
40+
- name: Create Release
41+
id: create_release
42+
uses: actions/create-release@v1
43+
env:
44+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45+
with:
46+
tag_name: ${{ github.ref }}
47+
release_name: Release ${{ github.ref }}
48+
draft: false
49+
prerelease: false
50+
- run: npx changelogithub
51+
continue-on-error: true
52+
env:
53+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
54+
- name: Upload Release Asset
55+
id: upload-release-asset
56+
uses: actions/upload-release-asset@v1
57+
env:
58+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
59+
with:
60+
asset_name: release.zip
61+
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
62+
asset_path: ./assets/release.zip
63+
asset_content_type: application/zip

Dockerfile

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
FROM node:18-alpine AS base
22

3+
RUN npm install -g --arch=x64 --platform=linux sharp
4+
35
FROM base AS deps
46

57
RUN apk add --no-cache libc6-compat
6-
78
RUN apk add --no-cache python3 make g++
89

910
WORKDIR /app
1011

1112
COPY . .
1213

14+
1315
RUN npm install -g pnpm
1416
RUN pnpm install
1517

@@ -26,11 +28,21 @@ ENV NODE_ENV production
2628
ARG BASE_URL
2729
ARG NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
2830
ARG CLERK_SECRET_KEY
31+
ARG S3_ACCESS_KEY
32+
ARG S3_SECRET_KEY
33+
ARG WEBHOOK_SECRET
34+
ARG TMDB_API_KEY
35+
ARG GH_TOKEN
2936
ENV BASE_URL=${BASE_URL}
3037
ENV NEXT_PUBLIC_API_URL=${BASE_URL}/api/v2
3138
ENV NEXT_PUBLIC_GATEWAY_URL=${BASE_URL}
3239
ENV NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=${NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY}
3340
ENV CLERK_SECRET_KEY=${CLERK_SECRET_KEY}
41+
ENV S3_ACCESS_KEY=${S3_ACCESS_KEY}
42+
ENV S3_SECRET_KEY=${S3_SECRET_KEY}
43+
ENV TMDB_API_KEY=${TMDB_API_KEY}
44+
ENV WEBHOOK_SECRET=${WEBHOOK_SECRET}
45+
ENV GH_TOKEN=${GH_TOKEN}
3446

3547
RUN pnpm build
3648

@@ -48,5 +60,5 @@ COPY --from=builder /app/.next/server ./.next/server
4860
EXPOSE 2323
4961

5062
ENV PORT 2323
51-
52-
CMD echo "Mix Space Web [Shiro] Image." && node server.js;
63+
ENV NEXT_SHARP_PATH=/usr/local/lib/node_modules/sharp
64+
CMD echo "Mix Space Web [Shiro] Image." && node server.js;

ci-release-build.sh

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!env bash
2+
set -e
3+
CWD=$(pwd)
4+
5+
npm run build
6+
cd .next
7+
pwd
8+
rm -rf cache
9+
cp -r ../public ./standalone/public
10+
11+
cd ./standalone
12+
echo ';process.title = "Shiro (NextJS)"' >>server.js
13+
mv ../static/ ./.next/static
14+
15+
cp $CWD/ecosystem.standalone.config.js ./ecosystem.config.js
16+
cp $CWD/.env.template .env
17+
18+
cd ..
19+
20+
mkdir -p $CWD/assets
21+
rm -rf $CWD/assets/release.zip
22+
zip --symlinks -r $CWD/assets/release.zip ./*

docker-compose.yml

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
version: "3"
1+
version: '3'
22

33
services:
44
shiro:
55
container_name: shiro
66
build:
77
context: .
8-
args:
9-
- BASE_URL=REPLACE_WITH_YOUR_BASE_URL
10-
- NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=REPLACE_WITH_YOUR_PUBLISHABLE_KEY
11-
- CLERK_SECRET_KEY=REPLACE_WITH_YOUR_SECRET_KEY
8+
volumes:
9+
- /app/.env:./.docker-env
1210
restart: always
1311
ports:
14-
- 2323:2323
12+
- 2323:2323

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
"mermaid": "10.9.0",
9797
"nanoid": "^5.0.6",
9898
"next": "14.1.4",
99+
"next-runtime-env": "3.2.1",
99100
"next-themes": "0.2.1",
100101
"ofetch": "1.3.4",
101102
"openai": "4.29.2",

pnpm-lock.yaml

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/(app)/(home)/layout.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { requestErrorHandler } from '~/lib/request.server'
99

1010
import { queryKey } from './query'
1111

12+
export const dynamic = 'force-dynamic'
1213
export const revalidate = 3600
1314

1415
export default async function HomeLayout(props: PropsWithChildren) {

src/app/(app)/(note-topic)/notes/(topic-detail)/topics/[slug]/layout.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { getQueryClient } from '~/lib/query-client.server'
99

1010
import { getTopicQuery } from './query'
1111

12+
export const dynamic = 'force-dynamic'
1213
export const generateMetadata = async (
1314
props: NextPageParams<{
1415
slug: string

src/app/(app)/(note-topic)/notes/(topic-detail)/topics/[slug]/page.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { routeBuilder, Routes } from '~/lib/route-builder'
1414

1515
import { getTopicQuery } from './query'
1616

17+
export const dynamic = 'force-dynamic'
1718
export default function Page() {
1819
const { slug } = useParams()
1920
const { data } = useQuery({

src/app/(app)/(note-topic)/notes/topics/layout.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { getQueryClient } from '~/lib/query-client.server'
99

1010
import { topicsQuery } from './query'
1111

12+
export const dynamic = 'force-dynamic'
1213
export const metadata: Metadata = {
1314
title: '专栏',
1415
}

src/app/(app)/(page-detail)/[slug]/layout.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
PageTitle,
3131
} from './pageExtra'
3232

33+
export const dynamic = 'force-dynamic'
3334
const getData = async (params: PageParams) => {
3435
attachUAAndRealIp()
3536
const data = await getQueryClient()

src/app/(app)/categories/[slug]/layout.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { getQueryClient } from '~/lib/query-client.server'
99

1010
import { getPageBySlugQuery } from './query'
1111

12+
export const dynamic = 'force-dynamic'
1213
const getData = async (params: { slug: string }) => {
1314
attachUAAndRealIp()
1415
const data = await getQueryClient().fetchQuery(

src/app/(app)/layout.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint-disable no-console */
22
import { cache } from 'react'
33
import { ToastContainer } from 'react-toastify'
4+
import { env, PublicEnvScript } from 'next-runtime-env'
45
import type { Metadata, Viewport } from 'next'
56
import type { PropsWithChildren } from 'react'
67

@@ -128,7 +129,7 @@ export const generateMetadata = async (): Promise<Metadata> => {
128129
},
129130
} satisfies Metadata
130131
}
131-
132+
export const dynamic = 'force-dynamic'
132133
export default async function RootLayout(props: PropsWithChildren) {
133134
const { children } = props
134135

@@ -137,14 +138,15 @@ export default async function RootLayout(props: PropsWithChildren) {
137138
const themeConfig = data.theme
138139

139140
return (
140-
<ClerkProvider>
141+
<ClerkProvider publishableKey={env('NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY')}>
141142
<AppFeatureProvider tmdb={!!process.env.TMDB_API_KEY}>
142143
<html
143144
lang="zh-CN"
144145
className="noise !bg-accent"
145146
suppressHydrationWarning
146147
>
147148
<head>
149+
<PublicEnvScript />
148150
<Global />
149151
<SayHi />
150152
<HydrationEndDetector />

src/app/(app)/notes/[id]/layout.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { Paper } from '../../../../components/layout/container/Paper'
2121
import { getData } from './api'
2222
import { Transition } from './Transition'
2323

24+
export const dynamic = 'force-dynamic'
2425
export const generateMetadata = async ({
2526
params,
2627
}: {

src/app/(app)/notes/[id]/page.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
NoteTitle,
3535
} from './pageExtra'
3636

37+
export const dynamic = 'force-dynamic'
3738
export default async function Page(props: {
3839
params: {
3940
id: string

src/app/(app)/posts/(post-detail)/[category]/[slug]/layout.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { LayoutRightSideProvider } from '~/providers/shared/LayoutRightSideProvi
1515

1616
import { getData } from './api'
1717

18+
export const dynamic = 'force-dynamic'
1819
export const generateMetadata = async ({
1920
params,
2021
}: {

0 commit comments

Comments
 (0)