From b40db8c6f2285e489c71100c80d3c9845a9feb62 Mon Sep 17 00:00:00 2001
From: Isaac Thoman <49598528+IsaacThoman@users.noreply.github.com>
Date: Mon, 27 Jan 2025 22:43:43 -0500
Subject: [PATCH] ci: cache NPM and Deno dependencies in Dockerfile

---
 Dockerfile      | 35 ++++++++++++++++++++++-------------
 deno.json       |  4 +++-
 import_map.json |  8 ++++++++
 3 files changed, 33 insertions(+), 14 deletions(-)
 create mode 100644 import_map.json

diff --git a/Dockerfile b/Dockerfile
index c40912c..262580a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,24 +1,33 @@
-FROM denoland/deno:2.1.2
-LABEL authors="Candiru <team@candiru.xyz>"
+# Build stage
+FROM denoland/deno:2.1.2 AS builder
+WORKDIR /app
+
+# Copy all source files
+COPY . .
+
+# Cache dependencies
+RUN deno cache --import-map=import_map.json main.ts
+
+# Build the application
+RUN deno task build
 
-# Set working directory
+# Runtime stage
+FROM denoland/deno:2.1.2
 WORKDIR /app
 
-# Install curl
+# Install curl for runtime
 USER root
 RUN apt-get update && apt-get install -y curl
 
-# Copy the project files
-COPY . .
+# Copy ALL source files and build artifacts
+COPY --from=builder /app/ ./
+
+# Copy the Deno cache
+COPY --from=builder /deno-dir/ /deno-dir/
 
-# Ensure the deno user has ownership of the necessary files and directories
+# Set permissions
 RUN chown -R deno:deno /app
 
-# Switch back to deno user
 USER deno
-
-# Expose the port
 EXPOSE 3000
-
-# Run the task
-CMD ["task", "start"]
+CMD ["task", "startnobuild"]
diff --git a/deno.json b/deno.json
index b99aba1..934073e 100644
--- a/deno.json
+++ b/deno.json
@@ -2,9 +2,11 @@
 	"tasks": {
 		"dev": "deno run -A --node-modules-dir npm:vite",
 		"build": "deno run -A --node-modules-dir npm:vite build",
+		"cache": "deno cache --import-map=import_map.json main.ts",
 		"preview": "deno run -A --node-modules-dir npm:vite preview",
 		"serve": "deno run --allow-net --allow-read jsr:@std/http@1/file-server dist/",
-		"start": "deno task build && deno run --allow-read --allow-env --allow-net --allow-write main.ts"
+		"start": "deno task build && deno run --allow-read --allow-env --allow-net --allow-write main.ts",
+		"startnobuild": "deno run --allow-read --allow-env --allow-net --allow-write main.ts"
 	},
 	"compilerOptions": {
 		"lib": ["ES2020", "DOM", "DOM.Iterable", "deno.ns"]
diff --git a/import_map.json b/import_map.json
new file mode 100644
index 0000000..6037fe6
--- /dev/null
+++ b/import_map.json
@@ -0,0 +1,8 @@
+{
+	"imports": {
+		"@deno/vite-plugin": "npm:@deno/vite-plugin@^1.0.0",
+		"@oak/oak": "jsr:@oak/oak@^17.1.3",
+		"@std/http": "jsr:@std/http@^1.0.10",
+		"vite": "npm:vite@^5.4.8"
+	}
+}