Skip to content

Commit e505076

Browse files
G3rootdahal
andauthored
feat: add docker image and workflow setup (#306)
* fix: schema and ignore * feat: add standalone output * feat: add docker image * feat: add runtime env * feat: init runtime env * feat: use runtime env * feat: add cleanup cache action * feat: add build docker image job * feat: init changeset * feat: add changeset script * chore: add changeset script * feat: add basic action * feat: refactor action and build app * chore: remove script * fix: add shell * fix: add shell * feat: update image label for docker hub / ghcr * chore: move docker file * feat: fix file location * fix: build error * fix: action * feat: update cache version * fix: fetch depth --------- Co-authored-by: Puru D <puru@dahal.me>
1 parent 68f80bc commit e505076

File tree

19 files changed

+1850
-401
lines changed

19 files changed

+1850
-401
lines changed

.changeset/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Changesets
2+
3+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4+
with multi-package repos, or single-package repos to help you version and publish your code. You can
5+
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6+
7+
We have a quick list of common questions to get you started engaging with this project in
8+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)

.changeset/config.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
3+
"changelog": "@changesets/cli/changelog",
4+
"commit": false,
5+
"fixed": [],
6+
"linked": [],
7+
"access": "restricted",
8+
"baseBranch": "main",
9+
"updateInternalDependencies": "patch",
10+
"ignore": [],
11+
"privatePackages": {
12+
"tag": true,
13+
"version": true
14+
}
15+
}

.dockerignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ yarn-error.log*
3535
# do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables
3636
.env
3737
.env*.local
38-
/prisma/enums
38+
/prisma/enums.ts
3939

4040
# vercel
4141
.vercel

.github/actions/build-app/action.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: "Build captable app"
2+
3+
runs:
4+
using: "composite"
5+
steps:
6+
- name: Copy env
7+
shell: bash
8+
run: cp .env.example .env
9+
10+
- name: Build app
11+
shell: bash
12+
run: npx prisma generate && npm run build
13+
env:
14+
SKIP_ENV_VALIDATION: 1

.github/actions/node-setup/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ runs:
1414
cache: npm
1515

1616
- name: Cache node_modules
17-
uses: actions/cache@v3
17+
uses: actions/cache@v4
1818
id: cache-node-modules
1919
with:
2020
path: node_modules

.github/workflows/ci.yml

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,47 @@ jobs:
1111
steps:
1212
- name: Checkout
1313
uses: actions/checkout@v4
14+
with:
15+
fetch-depth: 2
1416

1517
- uses: ./.github/actions/node-setup
1618

17-
- name: Copy env
18-
run: cp .env.example .env
19+
- uses: ./.github/actions/build-app
1920

20-
- name: Build
21-
run: npm i && npm run build
22-
env:
23-
SKIP_ENV_VALIDATION: "1"
21+
build_docker:
22+
name: Build Docker Image
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: Checkout
26+
uses: actions/checkout@v4
27+
with:
28+
fetch-depth: 2
29+
30+
- name: Set up Docker Buildx
31+
uses: docker/setup-buildx-action@v3
32+
33+
- name: Cache Docker layers
34+
uses: actions/cache@v4
35+
with:
36+
path: /tmp/.buildx-cache
37+
key: ${{ runner.os }}-buildx-${{ github.sha }}
38+
restore-keys: |
39+
${{ runner.os }}-buildx-
40+
41+
- name: Build Docker Image
42+
uses: docker/build-push-action@v5
43+
with:
44+
push: false
45+
context: .
46+
file: ./docker/Dockerfile
47+
tags: captable-${{ github.sha }}
48+
cache-from: type=local,src=/tmp/.buildx-cache
49+
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
50+
51+
- # Temp fix
52+
# https://github.com/docker/build-push-action/issues/252
53+
# https://github.com/moby/buildkit/issues/1896
54+
name: Move cache
55+
run: |
56+
rm -rf /tmp/.buildx-cache
57+
mv /tmp/.buildx-cache-new /tmp/.buildx-cache

.github/workflows/clean-cache.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: cleanup caches by a branch
2+
on:
3+
pull_request:
4+
types:
5+
- closed
6+
7+
jobs:
8+
cleanup:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Cleanup
12+
run: |
13+
gh extension install actions/gh-actions-cache
14+
15+
echo "Fetching list of cache key"
16+
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1 )
17+
18+
## Setting this to not fail the workflow while deleting cache keys.
19+
set +e
20+
echo "Deleting caches..."
21+
for cacheKey in $cacheKeysForPR
22+
do
23+
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
24+
done
25+
echo "Done"
26+
env:
27+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28+
REPO: ${{ github.repository }}
29+
BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge

.github/workflows/publish-docker.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Publish Docker image
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
push_to_registries:
9+
name: Push Docker image to multiple registries
10+
runs-on: ubuntu-latest
11+
permissions:
12+
packages: write
13+
contents: read
14+
attestations: write
15+
steps:
16+
- name: Check out the repo
17+
uses: actions/checkout@v4
18+
19+
- name: Log in to Docker Hub
20+
uses: docker/login-action@v3
21+
with:
22+
username: ${{ secrets.DOCKER_USERNAME }}
23+
password: ${{ secrets.DOCKER_PASSWORD }}
24+
25+
- name: Log in to the Container registry
26+
uses: docker/login-action@v3
27+
with:
28+
registry: ghcr.io
29+
username: ${{ github.actor }}
30+
password: ${{ secrets.GITHUB_TOKEN }}
31+
32+
- name: Extract metadata (tags, labels) for Docker
33+
id: meta
34+
uses: docker/metadata-action@v5
35+
with:
36+
images: |
37+
captable/captable
38+
ghcr.io/${{ github.repository }}
39+
40+
- name: Build and push Docker images
41+
id: push
42+
uses: docker/build-push-action@v5
43+
with:
44+
context: .
45+
file: ./docker/Dockerfile
46+
push: true
47+
tags: ${{ steps.meta.outputs.tags }}
48+
labels: ${{ steps.meta.outputs.labels }}
49+
50+
- name: Generate artifact attestation
51+
uses: actions/attest-build-provenance@v1
52+
with:
53+
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
54+
subject-digest: ${{ steps.push.outputs.digest }}
55+
push-to-registry: true

.github/workflows/release.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
concurrency: ${{ github.workflow }}-${{ github.ref }}
9+
10+
jobs:
11+
release:
12+
name: Release
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
20+
- uses: ./.github/actions/node-setup
21+
22+
- uses: ./.github/actions/build-app
23+
24+
- name: Create Release Pull Request
25+
uses: changesets/action@v1
26+
with:
27+
commit: "chore(release): version packages"
28+
title: "chore(release): version packages"
29+
env:
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,6 @@ pnpm-lock.yaml
4747
#local
4848
/local
4949
.vscode/
50+
51+
52+
/prisma/enums.ts

docker/Dockerfile

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
FROM --platform=linux/amd64 node:20-alpine AS base
2+
3+
FROM base AS deps
4+
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
5+
RUN apk add --no-cache libc6-compat openssl
6+
WORKDIR /app
7+
8+
# Install Prisma Client - remove if not using Prisma
9+
10+
COPY prisma ./prisma
11+
12+
ENV HUSKY 0
13+
14+
# Install dependencies based on the preferred package manager
15+
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
16+
RUN \
17+
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
18+
elif [ -f package-lock.json ]; then npm ci; \
19+
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
20+
else echo "Lockfile not found." && exit 1; \
21+
fi
22+
23+
24+
##### BUILDER
25+
26+
FROM base AS builder
27+
WORKDIR /app
28+
COPY --from=deps /app/node_modules ./node_modules
29+
COPY --from=deps /app/prisma ./prisma
30+
COPY . .
31+
32+
# Next.js collects completely anonymous telemetry data about general usage.
33+
# Learn more here: https://nextjs.org/telemetry
34+
# Uncomment the following line in case you want to disable telemetry during the build.
35+
ENV NEXT_TELEMETRY_DISABLED 1
36+
ENV DOCKER_OUTPUT 1
37+
ENV SKIP_ENV_VALIDATION 1
38+
39+
RUN \
40+
if [ -f yarn.lock ]; then yarn run build; \
41+
elif [ -f package-lock.json ]; then npm run build; \
42+
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
43+
else echo "Lockfile not found." && exit 1; \
44+
fi
45+
46+
##### RUNNER
47+
48+
FROM base AS runner
49+
WORKDIR /app
50+
51+
ENV NODE_ENV production
52+
# Uncomment the following line in case you want to disable telemetry during runtime.
53+
ENV NEXT_TELEMETRY_DISABLED 1
54+
55+
ENV DOCKER_OUTPUT 1
56+
57+
RUN addgroup --system --gid 1001 nodejs
58+
RUN adduser --system --uid 1001 nextjs
59+
60+
COPY --from=builder /app/public ./public
61+
62+
# Set the correct permission for prerender cache
63+
RUN mkdir .next
64+
RUN chown nextjs:nodejs .next
65+
66+
# Automatically leverage output traces to reduce image size
67+
# https://nextjs.org/docs/advanced-features/output-file-tracing
68+
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
69+
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
70+
71+
USER nextjs
72+
73+
EXPOSE 3000
74+
75+
ENV PORT 3000
76+
77+
# server.js is created by next build from the standalone output
78+
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
79+
CMD HOSTNAME="0.0.0.0" node server.js

next.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ await import("./src/env.js");
88

99
/** @type {import("next").NextConfig} */
1010
const config = {
11+
output: process.env.DOCKER_OUTPUT ? "standalone" : undefined,
1112
images: {
1213
remotePatterns: [
1314
{

0 commit comments

Comments
 (0)