From 368086f9bd5d6dafcfb0a54d91f079e2d25ad7b1 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Mon, 8 Sep 2025 19:24:06 +0200 Subject: [PATCH] feat: add Dockerfile and deployment configuration; update metadata and project descriptions --- .gitea/workflows/deploy.yml | 23 +++++++++ Dockerfile | 31 ++++++++++++ app/globals.css | 1 - app/layout.tsx | 72 ++++++++++++++++++++++++++-- app/projects/[projectName]/page.tsx | 15 ++++++ app/projects/page.tsx | 3 +- compose.yml | 15 ++++++ public/images/favicon.ico | Bin 270398 -> 0 bytes 8 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 .gitea/workflows/deploy.yml create mode 100644 Dockerfile create mode 100644 compose.yml delete mode 100644 public/images/favicon.ico diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..6811bf7 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,23 @@ +name: Build and Deploy Gabriel Kaszewski Portfolio + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build-and-deploy-local: + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Rebuild and Deploy with Docker Compose + run: | + docker build --target release -t local/gabriel-portfolio:latest . + docker compose up -d + + # Clean up any old, unused images to save disk space + docker image prune -f \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..57bf94e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +FROM oven/bun:1 AS base +WORKDIR /app + +FROM base AS install +RUN mkdir -p /temp/dev +COPY package.json bun.lock /temp/dev/ +RUN cd /temp/dev && bun install --frozen-lockfile + +RUN mkdir -p /temp/prod +COPY package.json bun.lock /temp/prod/ +RUN cd /temp/prod && bun install --frozen-lockfile --production + +FROM base AS prerelease +COPY --from=install /temp/dev/node_modules node_modules +COPY . . + +ENV NODE_ENV=production +RUN bun run build + +FROM base AS release + +COPY --from=prerelease /app/public ./public +COPY --from=prerelease /app/.next ./.next +COPY --from=prerelease /app/node_modules ./node_modules +COPY --from=prerelease /app/package.json ./package.json + +USER bun +EXPOSE 3000/tcp + +CMD ["bun", "run", "start"] + diff --git a/app/globals.css b/app/globals.css index 02be7db..125e4cb 100644 --- a/app/globals.css +++ b/app/globals.css @@ -42,7 +42,6 @@ } body { - /* background: var(--background); */ background-image: url("/images/background.avif"); background-size: cover; background-attachment: fixed; diff --git a/app/layout.tsx b/app/layout.tsx index d560fb2..76c08e9 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -3,7 +3,6 @@ import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; import Navbar from "@/components/navbar"; import Footer from "@/components/footer"; -import Image from "next/image"; const geistSans = Geist({ variable: "--font-geist-sans", @@ -16,8 +15,48 @@ const geistMono = Geist_Mono({ }); export const metadata: Metadata = { - title: "Gabriel Kaszewski", - description: "Welcome to my portfolio", + title: { + default: "Gabriel Kaszewski | Full-Stack Developer", + template: "%s | Gabriel Kaszewski", + }, + description: + "The portfolio of Gabriel Kaszewski, a self-taught full-stack developer specializing in Rust, Python, and modern web technologies.", + keywords: [ + "Gabriel Kaszewski", + "Full-Stack Developer", + "Rust Developer", + "Python Developer", + "Next.js", + "Portfolio", + ], + openGraph: { + title: "Gabriel Kaszewski | Full-Stack Developer", + description: + "Welcome to my portfolio. Discover my projects, skills, and journey.", + url: "https://gabrielkaszewski.dev", + siteName: "Gabriel Kaszewski's Portfolio", + locale: "en_US", + type: "website", + }, + + twitter: { + card: "summary_large_image", + title: "Gabriel Kaszewski | Full-Stack Developer", + description: + "Explore my work as a full-stack developer, from web apps to game development.", + }, + + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + "max-video-preview": -1, + "max-image-preview": "large", + "max-snippet": -1, + }, + }, }; export default function RootLayout({ @@ -25,11 +64,38 @@ export default function RootLayout({ }: Readonly<{ children: React.ReactNode; }>) { + const jsonLd = { + "@context": "https://schema.org", + "@type": "Person", + name: "Gabriel Kaszewski", + url: "https://gabrielkaszewski.dev", + sameAs: [ + "https://github.com/GKaszewski", + "https://www.linkedin.com/in/gabriel-kaszewski-5344b3183", + ], + jobTitle: "Full-Stack Developer", + alumniOf: "University of GdaƄsk", + knowsAbout: [ + "Rust", + "Python", + "Next.js", + "React", + "Tailwind CSS", + "Game Development", + "Web Development", + ], + }; + return ( +