Skip to content

Commit db9d9bd

Browse files
committed
Speed up App Service deploys and paginated pages
1 parent 757e3fa commit db9d9bd

9 files changed

Lines changed: 84 additions & 109 deletions

File tree

.github/workflows/deploy-appservice.yml

Lines changed: 22 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ concurrency:
1717
cancel-in-progress: true
1818

1919
jobs:
20-
build:
21-
name: Build
20+
deploy:
21+
name: Build and Deploy
2222
runs-on: ubuntu-latest
23+
environment:
24+
name: production
25+
url: https://exam-cooker.acmvit.in
2326

2427
steps:
2528
- name: Checkout
@@ -31,70 +34,47 @@ jobs:
3134
node-version: 24
3235
cache: npm
3336

37+
- name: Restore Next.js build cache
38+
uses: actions/cache@v4
39+
with:
40+
path: .next/cache
41+
key: ${{ runner.os }}-next-${{ hashFiles('package-lock.json') }}-${{ hashFiles('next.config.ts', 'tsconfig.json', 'tailwind.config.ts', 'postcss.config.mjs') }}
42+
restore-keys: |
43+
${{ runner.os }}-next-${{ hashFiles('package-lock.json') }}-
44+
3445
- name: Install dependencies
35-
run: npm ci
46+
run: npm ci --no-audit --prefer-offline
3647

3748
- name: Build application
3849
run: npm run build
3950

40-
- name: Trim dev dependencies
41-
run: npm prune --omit=dev
42-
4351
- name: Package deployment payload
4452
run: |
4553
set -eux
4654
rm -rf deploy
4755
mkdir -p deploy
4856
49-
rsync -a .next/ deploy/.next/
50-
rsync -a node_modules/ deploy/node_modules/
51-
52-
mkdir -p deploy/src/generated
53-
rsync -a src/generated/ deploy/src/generated/
54-
55-
cp package.json deploy/package.json
56-
cp next.config.ts deploy/next.config.ts
57+
rsync -a .next/standalone/ deploy/
58+
mkdir -p deploy/.next
59+
rsync -a .next/static/ deploy/.next/static/
5760
cp startup.sh deploy/startup.sh
5861
59-
if [ -f package-lock.json ]; then
60-
cp package-lock.json deploy/package-lock.json
61-
fi
62-
6362
if [ -d public ]; then
6463
rsync -a public/ deploy/public/
6564
fi
6665
66+
if [ -d src/generated ]; then
67+
mkdir -p deploy/src/generated
68+
rsync -a src/generated/ deploy/src/generated/
69+
fi
70+
6771
if [ -d prisma ]; then
6872
rsync -a prisma/ deploy/prisma/
6973
fi
7074
71-
rm -rf deploy/.next/cache
72-
7375
cd deploy
7476
zip -qry ../webapp-package.zip .
7577
76-
- name: Upload deployment artifact
77-
uses: actions/upload-artifact@v4
78-
with:
79-
name: webapp-package
80-
path: webapp-package.zip
81-
if-no-files-found: error
82-
83-
deploy:
84-
name: Deploy
85-
runs-on: ubuntu-latest
86-
needs: build
87-
environment:
88-
name: production
89-
url: https://exam-cooker.acmvit.in
90-
91-
steps:
92-
- name: Download deployment artifact
93-
uses: actions/download-artifact@v4
94-
with:
95-
name: webapp-package
96-
path: .
97-
9878
- name: Deploy to Azure App Service
9979
uses: azure/webapps-deploy@v3
10080
with:

app/(app)/forum/page.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,21 @@ async function ForumResults({ params }: { params: { page?: string; search?: stri
5555
: (params.tags ? params.tags.split(',') : []);
5656
const normalizedTags = [...tags].sort();
5757

58-
const totalCount = await getForumCount({
59-
search,
60-
tags: normalizedTags,
61-
});
58+
const [totalCount, paginatedForumPosts] = await Promise.all([
59+
getForumCount({
60+
search,
61+
tags: normalizedTags,
62+
}),
63+
getForumPage({
64+
search,
65+
tags: normalizedTags,
66+
page: page > 0 ? page : 1,
67+
pageSize,
68+
currentUserId,
69+
}),
70+
]);
6271
const totalPages = Math.ceil(totalCount / pageSize);
6372
const validatedPage = validatePage(page, totalPages);
64-
const paginatedForumPosts = await getForumPage({
65-
search,
66-
tags: normalizedTags,
67-
page: validatedPage,
68-
pageSize,
69-
currentUserId,
70-
});
7173

7274
if (validatedPage !== page) {
7375
const searchQuery = search ? `&search=${encodeURIComponent(search)}` : '';

app/(app)/notes/page.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,20 @@ async function NotesResults({ params }: { params: { page?: string; search?: stri
4949
: (params.tags ? params.tags.split(',') : []);
5050
const normalizedTags = [...tags].sort();
5151

52-
const totalCount = await getNotesCount({
53-
search,
54-
tags: normalizedTags,
55-
});
52+
const [totalCount, paginatedNotes] = await Promise.all([
53+
getNotesCount({
54+
search,
55+
tags: normalizedTags,
56+
}),
57+
getNotesPage({
58+
search,
59+
tags: normalizedTags,
60+
page: page > 0 ? page : 1,
61+
pageSize,
62+
}),
63+
]);
5664
const totalPages = Math.ceil(totalCount / pageSize);
5765
const validatedPage = validatePage(page, totalPages);
58-
const paginatedNotes = await getNotesPage({
59-
search,
60-
tags: normalizedTags,
61-
page: validatedPage,
62-
pageSize,
63-
});
6466

6567
if (validatedPage !== page) {
6668
const searchQuery = search ? `&search=${encodeURIComponent(search)}` : '';

app/(app)/past_papers/page.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,20 @@ async function PastPaperResults({
5555
: [];
5656
const normalizedTags = [...tags].sort();
5757

58-
const totalCount = await getPastPapersCount({
59-
search,
60-
tags: normalizedTags,
61-
});
58+
const [totalCount, paginatedPastPapers] = await Promise.all([
59+
getPastPapersCount({
60+
search,
61+
tags: normalizedTags,
62+
}),
63+
getPastPapersPage({
64+
search,
65+
tags: normalizedTags,
66+
page: page > 0 ? page : 1,
67+
pageSize,
68+
}),
69+
]);
6270
const totalPages = Math.ceil(totalCount / pageSize);
6371
const validatedPage = validatePage(page, totalPages);
64-
const paginatedPastPapers = await getPastPapersPage({
65-
search,
66-
tags: normalizedTags,
67-
page: validatedPage,
68-
pageSize,
69-
});
7072

7173
if (validatedPage !== page) {
7274
const searchQuery = search ? `&search=${encodeURIComponent(search)}` : "";

app/(app)/resources/page.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,16 @@ async function ResourcesResults({ params }: { params: { page?: string; search?:
4444
const search = params.search || '';
4545
const page = parseInt(params.page || '1', 10);
4646

47-
const totalCount = await getResourcesCount({ search });
47+
const [totalCount, paginatedSubjects] = await Promise.all([
48+
getResourcesCount({ search }),
49+
getResourcesPage({
50+
search,
51+
page: page > 0 ? page : 1,
52+
pageSize,
53+
}),
54+
]);
4855
const totalPages = Math.ceil(totalCount / pageSize);
4956
const validatedPage = validatePage(page, totalPages);
50-
const paginatedSubjects = await getResourcesPage({
51-
search,
52-
page: validatedPage,
53-
pageSize,
54-
});
5557

5658
if (validatedPage !== page) {
5759
redirect(`/resources?page=${validatedPage}${search ? `&search=${encodeURIComponent(search)}` : ''}`);

app/(app)/syllabus/page.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,16 @@ async function SyllabusResults({ params }: { params: { page?: string; search?: s
3838
const search = params.search || '';
3939
const page = parseInt(params.page || '1', 10);
4040

41-
const totalCount = await getSyllabusCount({ search });
41+
const [totalCount, paginatedSyllabi] = await Promise.all([
42+
getSyllabusCount({ search }),
43+
getSyllabusPage({
44+
search,
45+
page: page > 0 ? page : 1,
46+
pageSize,
47+
}),
48+
]);
4249
const totalPages = Math.ceil(totalCount / pageSize);
4350
const validatedPage = validatePage(page, totalPages);
44-
const paginatedSyllabi = await getSyllabusPage({
45-
search,
46-
page: validatedPage,
47-
pageSize,
48-
});
4951

5052
if (validatedPage !== page) {
5153
redirect(`/syllabus?page=${validatedPage}${search ? `&search=${encodeURIComponent(search)}` : ''}`);

next.config.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import type { NextConfig } from "next";
2-
import path from "path";
32

43
const nextConfig: NextConfig = {
4+
output: "standalone",
55
cacheComponents: true,
66
turbopack: {
77
root: __dirname,
88
resolveAlias: {
99
canvas: {
1010
browser: "./lib/shims/canvas",
1111
},
12-
tailwindcss: path.join(__dirname, "node_modules/tailwindcss"),
1312
},
1413
},
1514
serverExternalPackages: ["canvas"],

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"scripts": {
66
"dev": "next dev --webpack",
7-
"build": "npx prisma generate && next build --webpack",
7+
"build": "prisma generate && next build",
88
"start": "next start",
99
"lint": "next lint",
1010
"seed_tags": "node scripts/seed-tags.js",

startup.sh

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,17 @@ set -eu
33

44
cd /home/site/wwwroot
55

6-
if [ -d /home/site/wwwroot/node_modules ]; then
7-
NODE_MODULES_PATH=/home/site/wwwroot/node_modules
8-
elif [ -d /node_modules ]; then
9-
NODE_MODULES_PATH=/node_modules
10-
elif [ -f /home/site/wwwroot/node_modules.tar.gz ]; then
11-
rm -rf /node_modules
12-
mkdir -p /node_modules
13-
tar -xzf /home/site/wwwroot/node_modules.tar.gz -C /node_modules
14-
NODE_MODULES_PATH=/node_modules
15-
else
16-
echo "Could not find node_modules in /home/site/wwwroot or /node_modules." >&2
17-
exit 1
18-
fi
19-
206
export NODE_ENV="${NODE_ENV:-production}"
21-
export NODE_PATH="${NODE_MODULES_PATH}:/usr/local/lib/node_modules:${NODE_PATH:-}"
22-
export PATH="${NODE_MODULES_PATH}/.bin:${PATH}:/home/site/wwwroot"
7+
export HOSTNAME="${HOSTNAME:-0.0.0.0}"
8+
export PORT="${PORT:-8080}"
239

24-
if [ -x "${NODE_MODULES_PATH}/.bin/next" ]; then
25-
exec "${NODE_MODULES_PATH}/.bin/next" start
10+
if [ -f /home/site/wwwroot/server.js ]; then
11+
exec node /home/site/wwwroot/server.js
2612
fi
2713

28-
if [ -f "${NODE_MODULES_PATH}/next/dist/bin/next" ]; then
29-
exec node "${NODE_MODULES_PATH}/next/dist/bin/next" start
14+
if [ -f /home/site/wwwroot/.next/standalone/server.js ]; then
15+
exec node /home/site/wwwroot/.next/standalone/server.js
3016
fi
3117

32-
echo "Could not find the Next.js runtime in ${NODE_MODULES_PATH}." >&2
18+
echo "Could not find the standalone Next.js server entrypoint." >&2
3319
exit 1

0 commit comments

Comments
 (0)