Skip to content

Commit

Permalink
feat: deploy next
Browse files Browse the repository at this point in the history
  • Loading branch information
Dovakiin0 committed Nov 19, 2024
1 parent 036ae42 commit 66702fd
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 62 deletions.
32 changes: 32 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

/coverage

/out/

/build

.DS_Store
*.pem

npm-debug.log*
yarn-debug.log*
yarn-error.log*

.env*.local

.vercel

*.tsbuildinfo
next-env.d.ts

.git
.github
.gitignore
.husky
.vscode
Dockerfile
README.md
53 changes: 53 additions & 0 deletions .github/workflows/cd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Build and Deploy Kitsune

on:
push:
branches:
- kitsune-dev # Trigger on push to main branch

jobs:
build:
runs-on: ubuntu-latest

steps:
# Checkout the repository
- name: Checkout code
uses: actions/checkout@v3

# Set up Docker Buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

# Log in to Docker Hub
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}

# Build and push Docker image
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: dovakiin0/kitsune-v2:latest, dovakiin0/kitsune-v2:${{ github.sha }}

# Deploy to VPS via SSH
- name: Deploy to VPS
uses: appleboy/[email protected]
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: 22
script: |
# Pull the latest Docker image
docker pull dovakiin0/kitsune-v2:latest
# Stop and remove the existing container
docker stop kitsune-v2 || true
docker rm kitsune-v2 || true
# Run the new container
docker run -d --name kitsune-v2 -e PORT=3000 -p 3000:3000 dovakiin0/kitsune-v2
41 changes: 41 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
FROM node:20-alpine AS base

# 1. Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat

WORKDIR /app

# Install dependencies based on the preferred package manager
COPY package.json ./
RUN npm install

# 2. Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# 3. Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV=production

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

COPY --from=builder /app/public ./public

COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone/ ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static/ ./.next/static/

USER nextjs

EXPOSE 4000

ENV PORT=4000

CMD ["node", "server.js"]
4 changes: 3 additions & 1 deletion next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "standalone",
swcMinify: true,
reactStrictMode: true,
images: {
remotePatterns: [
{
Expand All @@ -11,4 +14,3 @@ const nextConfig = {
};

export default nextConfig;

84 changes: 43 additions & 41 deletions src/app/anime/watch/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,49 +61,51 @@ const Layout = (props: Props) => {
if (isLoading) return <Loading />;

return (
<Container className="mt-[8.5rem] space-y-10 pb-20">
<div className="grid lg:grid-cols-4 grid-cols-1 gap-y-5 gap-x-10 w-full">
<div className="lg:col-span-3 col-span-1">{props.children}</div>

<EpisodePlaylist
animeId={animeId as string}
title={
!!anime?.anime.info.name
? anime.anime.info.name
: (anime?.anime.moreInfo.japanese as string)
}
anime?.anime.info && (
<Container className="mt-[6.5rem] space-y-10 pb-20">
<div className="grid lg:grid-cols-4 grid-cols-1 gap-y-5 gap-x-10 w-full">
<div className="lg:col-span-3 col-span-1">{props.children}</div>

<EpisodePlaylist
animeId={animeId as string}
title={
!!anime?.anime.info.name
? anime.anime.info.name
: (anime?.anime.moreInfo.japanese as string)
}
/>
</div>
<div className="flex md:flex-row flex-col gap-5 -mt-5">
<AnimeCard
title={anime?.anime.info.name}
poster={anime?.anime.info.poster}
subTitle={anime?.anime.moreInfo.aired}
displayDetails={false}
className="!h-full !rounded-sm"
href={ROUTES.ANIME_DETAILS + "/" + anime?.anime.info.id}
/>
<div className="flex flex-col gap-2">
<h1
className="text-2xl md:font-black font-extrabold z-[100] cursor-pointer"
onClick={() => {
router.push(ROUTES.ANIME_DETAILS + "/" + anime?.anime.info.id);
}}
>
{anime?.anime.info.name}
</h1>
<p>{parse(anime?.anime.info.description as string)}</p>
</div>
</div>
<AnimeCarousel
title={"Also Watch"}
anime={anime?.relatedAnimes as IAnime[]}
/>
</div>
<div className="flex md:flex-row flex-col gap-5 -mt-5">
<AnimeCard
title={anime?.anime.info.name as string}
poster={anime?.anime.info.poster as string}
subTitle={anime?.anime.moreInfo.aired as string}
displayDetails={false}
className="!h-full !rounded-sm !shrink-0"
href={ROUTES.ANIME_DETAILS + "/" + anime?.anime.info.id}
<AnimeCarousel
title={"Recommended"}
anime={anime?.recommendedAnimes as IAnime[]}
/>
<div className="flex flex-col gap-2">
<h1
className="text-2xl md:font-black font-extrabold z-[100] cursor-pointer"
onClick={() => {
router.push(ROUTES.ANIME_DETAILS + "/" + anime?.anime.info.id);
}}
>
{anime?.anime.info.name}
</h1>
<p>{parse(anime?.anime.info.description as string)}</p>
</div>
</div>
<AnimeCarousel
title={"Also Watch"}
anime={anime?.relatedAnimes as IAnime[]}
/>
<AnimeCarousel
title={"Recommended"}
anime={anime?.recommendedAnimes as IAnime[]}
/>
</Container>
</Container>
)
);
};
export default Layout;
8 changes: 3 additions & 5 deletions src/app/anime/watch/video-player-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import { useGetEpisodeServers } from "@/query/get-episode-servers";
const VideoPlayerSection = () => {
const { selectedEpisode, anime } = useAnimeStore();

console.log("selected", selectedEpisode);

const { data: serversData } = useGetEpisodeServers(selectedEpisode);

const { data: episodeData, isLoading } = useGetEpisodeData(
Expand Down Expand Up @@ -55,9 +53,9 @@ const VideoPlayerSection = () => {
const updatedWatchedDetails = watchedDetails.map((watchedAnime) =>
watchedAnime.anime.id === anime.anime.info.id
? {
...watchedAnime,
episodes: [...watchedAnime.episodes, selectedEpisode],
}
...watchedAnime,
episodes: [...watchedAnime.episodes, selectedEpisode],
}
: watchedAnime,
);

Expand Down
4 changes: 0 additions & 4 deletions src/components/art-player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ function ArtPlayer({ option, getInstance, ...rest }: any) {
});
});

art.on("subtitleUpdate", (text) => {
art.template.$subtitle.innerHTML = text;
});

if (getInstance && typeof getInstance === "function") {
getInstance(art);
}
Expand Down
5 changes: 2 additions & 3 deletions src/components/common/episode-card.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use client";

import React from "react";
import Image from "next/image";

import { cn } from "@/lib/utils";

Expand Down Expand Up @@ -84,8 +83,8 @@ const EpisodeCard = ({
? { backgroundColor: "#18181a" }
: hasWatchedEpisode
? {
backgroundColor: "#0f172a",
}
backgroundColor: "#0f172a",
}
: {}
}
>
Expand Down
4 changes: 3 additions & 1 deletion src/components/continue-watching.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ const ContinueWatching = (props: Props) => {
}, []);

if (props.loading) return <LoadingSkeleton />;
if (!anime && !props.loading) return <></>;

console.log(anime)
if ((!anime || !anime.length) && !props.loading) return <></>;

return (
<Container className="flex flex-col gap-5 py-10 items-center lg:items-start ">
Expand Down
2 changes: 1 addition & 1 deletion src/components/episode-playlist.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const EpisodePlaylist = ({ animeId, title }: Props) => {
}, [animeId, episodes]);

return (
<div className="col-span-1 flex flex-col w-full gap-5 border-[.0313rem] border-secondary rounded-md overflow-hidden lg:max-h-[60vh] max-h-[40vh] min-h-[40vh]">
<div className="col-span-1 flex flex-col w-full gap-5 border-[.0313rem] border-secondary rounded-md overflow-hidden lg:max-h-[80vh] max-h-[80vh] min-h-[40vh]">
<div className="h-fit bg-[#18181a] px-5 py-3">
<h3 className="text-lg font-semibold"> Episode Playlist</h3>
<span className="text-sm font-thin">{title}</span>
Expand Down
9 changes: 6 additions & 3 deletions src/components/kitsune-player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const KitsunePlayer = ({ episodeInfo, animeInfo }: KitsunePlayerProps) => {
url: uri,
customType: {
//eslint-disable-next-line
m3u8: function (video: HTMLMediaElement, url: string, art: any) {
m3u8: function(video: HTMLMediaElement, url: string, art: any) {
if (Hls.isSupported()) {
if (art.hls) art.hls.destroy();
const hls = new Hls();
Expand Down Expand Up @@ -72,6 +72,7 @@ const KitsunePlayer = ({ episodeInfo, animeInfo }: KitsunePlayerProps) => {
// Show qualitys in setting
setting: true,
// Get the quality name from level
//eslint-disable-next-line
getName: (level: any) => level.height + "P",
// I18n
title: "Quality",
Expand All @@ -83,6 +84,7 @@ const KitsunePlayer = ({ episodeInfo, animeInfo }: KitsunePlayerProps) => {
// Show audios in setting
setting: true,
// Get the audio name from track
//eslint-disable-next-line
getName: (track: any) => track.name,
// I18n
title: "Audio",
Expand Down Expand Up @@ -162,18 +164,19 @@ const KitsunePlayer = ({ episodeInfo, animeInfo }: KitsunePlayerProps) => {
color: "#fff",
},
encoding: "utf-8",
escape: false,
},
icons: {
loading: `<img width="50" height="50" src="${loadingImage.src}">`,
},
}),
[uri, animeInfo],
[uri, animeInfo, episodeInfo?.tracks],
);

return (
<div
ref={playerRef}
className="w-full h-full lg:max-h-[60vh] max-h-[40vh] min-h-[60vh]"
className="w-full h-full lg:max-h-[80vh] max-h-[40vh] min-h-[80vh]"
>
{uri ? (
<ArtPlayer option={options} className="w-full h-full border-none" />
Expand Down
6 changes: 3 additions & 3 deletions src/query/get-episode-data.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { GET_EPISODE_DATA } from "@/constants/query-keys";
import { api } from "@/lib/api";
import { IEpisodes, IEpisodeSource } from "@/types/episodes";
import { IEpisodeSource } from "@/types/episodes";
import { useQuery } from "react-query";

const getEpisodeData = async (
episodeId: string,
server: string,
server: string | undefined,
subOrDub: string,
) => {
const res = await api.get("/episode/sources", {
Expand All @@ -20,7 +20,7 @@ const getEpisodeData = async (

export const useGetEpisodeData = (
episodeId: string,
server: string,
server: string | undefined,
subOrDub: string = "sub",
) => {
return useQuery({
Expand Down

0 comments on commit 66702fd

Please sign in to comment.