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 (
+ +