diff --git a/.env.example b/.env.example index e2838a4c..8de38913 100644 --- a/.env.example +++ b/.env.example @@ -15,6 +15,14 @@ NEXT_PUBLIC_NODE_ENV=development ENTERPRISE_API_URL=http://localhost:8080 CONSOLE_BASE_URL=http://localhost:3000 + +## Auth +CLIENT_ID= +SECRET_ID= +DOMAIN=mgmt-20.kubefirst +NEXTAUTH_SECRET=mgmt-20.kubefirst +NEXTAUTH_URL=http://locahost:3000 + ##### Cypress config env ############ # Cypress - Git Provider values diff --git a/Dockerfile b/Dockerfile index 0ee0425a..fea3482d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,12 @@ -FROM node:18 AS builder +FROM node:18-alpine AS base +FROM base AS deps +RUN apk add --no-cache libc6-compat +RUN apk add --no-cache python3 make g++ RUN npm i -g node-gyp - WORKDIR /app + COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ RUN \ if [ -f yarn.lock ]; then yarn --production --frozen-lockfile; \ @@ -12,21 +15,41 @@ RUN \ else echo "Lockfile not found." && exit 1; \ fi +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules + COPY . . +ENV NEXT_TELEMETRY_DISABLED 1 + RUN yarn build -FROM node:18 +# Production image, copy all the files and run next +FROM base AS runner WORKDIR /app -COPY --from=builder /app/node_modules ./node_modules -COPY --from=builder /app/.next ./.next -COPY --from=builder /app/public ./public -COPY --from=builder /app/package*.json ./ +ENV NODE_ENV production +ENV NEXT_TELEMETRY_DISABLED 1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static +COPY --from=builder --chown=nextjs:nodejs /app/next.config.js ./next.config.js +# COPY --from=builder --chown=nextjs:nodejs /app/static ./.next/static +# COPY --from=builder --chown=nextjs:nodejs /app/server.js ./server.js +# COPY --from=builder --chown=nextjs:nodejs /app/.next/public ./.next/static + +USER nextjs EXPOSE 8080 ENV PORT 8080 -CMD ["yarn", "start"] +CMD ["node", "server.js"] diff --git a/app/auth/signin/page.tsx b/app/auth/signin/page.tsx index 3707504a..9c93bc9e 100644 --- a/app/auth/signin/page.tsx +++ b/app/auth/signin/page.tsx @@ -3,23 +3,33 @@ import React from 'next'; import { signIn } from 'next-auth/react'; import Image from 'next/image'; import { useSearchParams } from 'next/navigation'; +import { useMemo } from 'react'; import { Background, Container, ExternalLink, Form, Header, Panel, Title } from './signin.styled'; +import Ray from '@/assets/ray.svg'; +import TitleDark from '@/assets/titleDark.svg'; +import Vault from '@/assets/vault.svg'; import Button from '@/components/button'; import Typography from '@/components/typography'; import { VOLCANIC_SAND } from '@/constants/colors'; export default function SignIn() { const searchParams = useSearchParams(); - const callbackUrl = searchParams?.get('callbackUrl'); + const callbackUrlParam = searchParams?.get('callbackUrl'); + + const callbackUrl = useMemo( + () => + callbackUrlParam && callbackUrlParam.includes('error') ? location.origin : callbackUrlParam, + [callbackUrlParam], + ); return (
Get started with your instant Kubernetes Platforms! - k1-ray-image + k1-ray-image
By using the Kubefirst platform, you agree to our{' '} @@ -38,7 +48,7 @@ export default function SignIn() {
- k1-image + k1-image Welcome @@ -56,7 +66,7 @@ export default function SignIn() { }); }} > - vault-icon + vault-icon Log in with Vault diff --git a/app/layout.tsx b/app/layout.tsx index 81d579ec..7f0445bb 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -15,7 +15,7 @@ export const metadata = { initialScale: 1.0, }, icons: { - shortcut: '/static/ray.svg', + shortcut: 'https://assets.kubefirst.com/console/ray.svg', }, }; diff --git a/assets/box.svg b/assets/box.svg new file mode 100644 index 00000000..7cb920cb --- /dev/null +++ b/assets/box.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/controller.png b/assets/controller.png new file mode 100644 index 00000000..2d55d846 Binary files /dev/null and b/assets/controller.png differ diff --git a/assets/learn.png b/assets/learn.png new file mode 100644 index 00000000..2fc5fb24 Binary files /dev/null and b/assets/learn.png differ diff --git a/assets/ray.svg b/assets/ray.svg new file mode 100644 index 00000000..5d5e93ca --- /dev/null +++ b/assets/ray.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/title.svg b/assets/title.svg new file mode 100644 index 00000000..efcf0e59 --- /dev/null +++ b/assets/title.svg @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/titleDark.svg b/assets/titleDark.svg new file mode 100644 index 00000000..e9ebeff3 --- /dev/null +++ b/assets/titleDark.svg @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/vault.svg b/assets/vault.svg new file mode 100644 index 00000000..11f040c5 --- /dev/null +++ b/assets/vault.svg @@ -0,0 +1,3 @@ + + + diff --git a/components/clusterReady/index.tsx b/components/clusterReady/index.tsx index be43d426..3ced65e1 100644 --- a/components/clusterReady/index.tsx +++ b/components/clusterReady/index.tsx @@ -8,6 +8,8 @@ import Password from '../password'; import { Container, Link, PasswordContainer, Title } from './clusterReady.styled'; +import Box from '@/assets/box.svg'; + export interface ClusterRunningMessageProps { clusterName?: string; domainName?: string; @@ -31,7 +33,7 @@ const ClusterReady: FunctionComponent = ({ return ( - box + box <Typography variant="body1"> Cluster <strong>{clusterName || '<cluster identifier>'}</strong> is now up and running. diff --git a/components/navigation/index.tsx b/components/navigation/index.tsx index 619435fe..0df2fe12 100644 --- a/components/navigation/index.tsx +++ b/components/navigation/index.tsx @@ -20,6 +20,11 @@ import { DocsCard, } from './navigation.styled'; +import Ray from '@/assets/ray.svg'; +import TitleLogo from '@/assets/titleDark.svg'; +import Learn from '@/assets/learn.png'; +import Controller from '@/assets/controller.png'; + const FOOTER_ITEMS = [ { icon: <HelpIcon />, @@ -62,9 +67,9 @@ const Navigation: FunctionComponent<NavigationProps> = ({ <Container> <div> <KubefirstTitle onClick={() => push('/')}> - <Image alt="k1-image" src={'/static/ray.svg'} height={40} width={48} id="ray" /> + <Image alt="k1-image" src={Ray} height={40} width={48} id="ray" /> {/* Only visible above md breakpoint 👇 */} - <Image alt="k1-image" src={'/static/title.svg'} height={40} width={160} id="title" /> + <Image alt="k1-image" src={TitleLogo} height={40} width={160} id="title" /> {kubefirstVersion && ( <KubefirstVersion variant="labelSmall" color={ECHO_BLUE}> {`${kubefirstVersion}`} @@ -89,7 +94,7 @@ const Navigation: FunctionComponent<NavigationProps> = ({ {isProvisionStep && ( <> <DocsCard onClick={handleOpenContent}> - <Image alt="controller-img" src="/static/learn.png" height={80} width={80} /> + <Image alt="controller-img" src={Learn} height={80} width={80} /> <Typography variant="subtitle2" color="secondary"> Got time? Sit back & learn... </Typography> @@ -98,7 +103,7 @@ const Navigation: FunctionComponent<NavigationProps> = ({ <Typography variant="subtitle2" color="secondary"> Bored? Play flappy K-ray and win stuff! </Typography> - <Image alt="controller-img" src="/static/controller.png" height={80} width={80} /> + <Image alt="controller-img" src={Controller} height={80} width={80} /> </FlappyCard> </> )} diff --git a/server.js b/server.js deleted file mode 100644 index 3e93d532..00000000 --- a/server.js +++ /dev/null @@ -1,57 +0,0 @@ -/* eslint-disable no-undef */ -/* eslint-disable @typescript-eslint/no-var-requires */ -const path = require('path'); -const http = require('http'); - -const NextServer = require('next/dist/server/next-server').default; -const defaultNextConfig = require('next/dist/server/config-shared').defaultConfig; -process.env.NODE_ENV = 'production'; -process.chdir(__dirname); - -const nextConfig = require('./next.config'); - -process.on('SIGTERM', () => process.exit(0)); -process.on('SIGINT', () => process.exit(0)); - -let handler; - -const server = http.createServer(async (req, res) => { - try { - await handler(req, res); - } catch (err) { - // eslint-disable-next-line no-console - console.error(err); - res.statusCode = 500; - res.end('internal server error'); - } -}); -const currentPort = parseInt(process.env.PORT, 10) || 3000; - -server.listen(currentPort, (err) => { - if (err) { - // eslint-disable-next-line no-console - console.error('Failed to start server', err); - process.exit(1); - } - const nextServer = new NextServer({ - hostname: 'localhost', - port: currentPort, - dir: path.join(__dirname), - customServer: true, - dev: false, - conf: { - ...defaultNextConfig, - ...nextConfig, - distDir: '.next', - experimental: { - ...defaultNextConfig.experimental, - ...nextConfig.experimental, - serverComponents: true, - }, - }, - }); - handler = nextServer.getRequestHandler(); - - // eslint-disable-next-line no-console - console.log('Kubefirst is Ready on port', currentPort); -});