From 247f02aaf2eaae0f15a45d7941f6d3ea77757591 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 3 Apr 2026 12:50:39 +0100 Subject: [PATCH] fix(docker): runtime API_URL for SSR in Docker containers NEXT_PUBLIC_* vars are baked at build time and can't change at runtime. Server-side rendering (getInitialProps, getServerSideProps, rewrites) now reads process.env.API_URL at runtime, falling back to the baked NEXT_PUBLIC_API_URL for client-side code. This allows the Docker image to connect to trade-api via Docker DNS while the browser still uses the public URL. Co-Authored-By: Charon --- .dockerignore | 7 +++++++ next.config.js | 4 +++- src/constants/index.ts | 2 +- src/pages/_app.tsx | 4 +++- src/pages/dex/trading/find-pair/index.tsx | 3 ++- src/utils/methods.ts | 2 +- 6 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..36e7f52 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +node_modules +.next +.env +.env.local +.env.development +.env.production +.git diff --git a/next.config.js b/next.config.js index 9463dde..296b1fe 100644 --- a/next.config.js +++ b/next.config.js @@ -42,10 +42,12 @@ const nextConfig = { return config; }, async rewrites() { + const apiUrl = + process.env.API_URL || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3336'; return [ { source: '/api/:path*', - destination: `${process.env.NEXT_PUBLIC_API_URL}/api/:path*`, + destination: `${apiUrl}/api/:path*`, }, ]; }, diff --git a/src/constants/index.ts b/src/constants/index.ts index 31a769c..206c22b 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,7 +1,7 @@ import PeriodState from '@/interfaces/states/pages/dex/trading/InputPanelItem/PeriodState'; import SelectValue from '@/interfaces/states/pages/dex/trading/InputPanelItem/SelectValue'; -export const API_URL = process.env.NEXT_PUBLIC_API_URL; +export const API_URL = process.env.NEXT_PUBLIC_API_URL || process.env.API_URL; export const periods: PeriodState[] = [ // { name: '1s', code: '1sec' }, diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 6350a1b..67e5643 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -97,7 +97,9 @@ App.getInitialProps = async (context: AppContext) => { try { const pageProps = await NextApp.getInitialProps(context); - const configRes = await axios.get(`${API_URL}/api/config`, { + const serverApiUrl = + typeof window === 'undefined' ? process.env.API_URL || API_URL : API_URL; + const configRes = await axios.get(`${serverApiUrl}/api/config`, { headers: { 'Content-Type': 'application/json', }, diff --git a/src/pages/dex/trading/find-pair/index.tsx b/src/pages/dex/trading/find-pair/index.tsx index d2401b5..68b2342 100644 --- a/src/pages/dex/trading/find-pair/index.tsx +++ b/src/pages/dex/trading/find-pair/index.tsx @@ -14,7 +14,8 @@ export const getServerSideProps: GetServerSideProps = async (context) => { } try { - const idFound = await findPairID(first as string, second as string, API_URL); + const serverApiUrl = process.env.API_URL || API_URL; + const idFound = await findPairID(first as string, second as string, serverApiUrl); console.log('ID found:', idFound); diff --git a/src/utils/methods.ts b/src/utils/methods.ts index 9a29823..064ac17 100644 --- a/src/utils/methods.ts +++ b/src/utils/methods.ts @@ -31,7 +31,7 @@ import { CancelAllData } from '@/interfaces/fetch-data/cancel-all-orders/CancelA import CancelAllRes from '@/interfaces/responses/orders/CancelAllRes'; const isServer = typeof window === 'undefined'; -const baseUrl = isServer ? API_URL : ''; +const baseUrl = isServer ? process.env.API_URL || API_URL || '' : ''; export async function getUser(): Promise { return axios