Skip to content

Commit 6989b5e

Browse files
committed
cicd
1 parent b6b04ca commit 6989b5e

File tree

10 files changed

+987
-20
lines changed

10 files changed

+987
-20
lines changed

.dockerignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
node_modules
2+
.next
3+
dist
4+
.git
5+
.github
6+
Dockerfile
7+
.dockerignore
8+
npm-debug.log
9+
docker-compose.override.yml
10+
env.*
11+
backups
12+
.vscode
13+
.cache
14+
*.tgz

.gitattributes

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Default: treat files as text and normalize to LF
2+
* text=auto eol=lf
3+
4+
# Explicit rules for common text file types (ensure LF)
5+
.gitattributes text eol=lf
6+
*.md text eol=lf
7+
*.markdown text eol=lf
8+
*.json text eol=lf
9+
*.yml text eol=lf
10+
*.yaml text eol=lf
11+
*.toml text eol=lf
12+
*.xml text eol=lf
13+
*.html text eol=lf
14+
*.htm text eol=lf
15+
*.js text eol=lf
16+
*.jsx text eol=lf
17+
*.ts text eol=lf
18+
*.tsx text eol=lf
19+
*.css text eol=lf
20+
*.scss text eol=lf
21+
*.less text eol=lf
22+
*.json5 text eol=lf
23+
*.jsonc text eol=lf
24+
*.sh text eol=lf
25+
*.ps1 text eol=lf
26+
*.bat text eol=lf
27+
*.mdx text eol=lf
28+
29+
# Mark typical binary files so Git doesn't attempt line-ending conversions
30+
*.png binary
31+
*.jpg binary
32+
*.jpeg binary
33+
*.gif binary
34+
*.ico binary
35+
*.webp binary
36+
*.zip binary
37+
*.gz binary
38+
*.tar.gz binary
39+
*.tgz binary
40+
*.pdf binary
41+
*.woff binary
42+
*.woff2 binary
43+
*.eot binary
44+
*.ttf binary
45+
46+
# end

.github/workflows/ci.yml

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
name: CI - split: lint, generate, build, migrate, push
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
workflow_dispatch: {}
9+
10+
env:
11+
# Default image name (override by setting the secret IMAGE_NAME to e.g. 'username/repo')
12+
IMAGE: ${{ secrets.IMAGE_NAME || github.repository }}
13+
14+
jobs:
15+
lint:
16+
name: lint + pre-commit
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Setup Node.js
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: '20'
26+
27+
- name: Cache npm
28+
uses: actions/cache@v4
29+
with:
30+
path: ~/.npm
31+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
32+
restore-keys: |
33+
${{ runner.os }}-node-
34+
35+
- name: Install dependencies
36+
run: npm ci
37+
38+
- name: Run lint (eslint)
39+
run: npm run lint
40+
41+
- name: Run pre-commit (lint-staged)
42+
# lint-staged expects staged files; --allow-empty prevents failure when none are staged in CI
43+
run: npx lint-staged --allow-empty --verbose
44+
45+
generate:
46+
name: prisma:generate
47+
runs-on: ubuntu-latest
48+
needs: lint
49+
steps:
50+
- name: Checkout
51+
uses: actions/checkout@v4
52+
53+
- name: Setup Node.js
54+
uses: actions/setup-node@v4
55+
with:
56+
node-version: '20'
57+
58+
- name: Cache npm
59+
uses: actions/cache@v4
60+
with:
61+
path: ~/.npm
62+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
63+
restore-keys: |
64+
${{ runner.os }}-node-
65+
66+
- name: Install dependencies
67+
run: npm ci
68+
69+
- name: Prisma generate (produce client binaries)
70+
run: npx prisma generate
71+
72+
build:
73+
name: build image
74+
runs-on: ubuntu-latest
75+
needs: generate
76+
steps:
77+
- name: Checkout
78+
uses: actions/checkout@v4
79+
80+
- name: Build image (local cache, do not push)
81+
uses: docker/build-push-action@v4
82+
with:
83+
context: .
84+
file: ./Dockerfile
85+
push: false
86+
tags: ${{ env.IMAGE }}:${{ github.sha }}
87+
88+
migrate:
89+
name: optional: prisma migrate deploy
90+
runs-on: ubuntu-latest
91+
needs: build
92+
if: ${{ secrets.DATABASE_URL }}
93+
env:
94+
DATABASE_URL: ${{ secrets.DATABASE_URL }}
95+
steps:
96+
- name: Checkout
97+
uses: actions/checkout@v4
98+
99+
- name: Setup Node.js
100+
uses: actions/setup-node@v4
101+
with:
102+
node-version: '20'
103+
104+
- name: Cache npm
105+
uses: actions/cache@v4
106+
with:
107+
path: ~/.npm
108+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
109+
restore-keys: |
110+
${{ runner.os }}-node-
111+
112+
- name: Install dependencies
113+
run: npm ci
114+
115+
- name: Prisma migrate deploy
116+
run: npx prisma migrate deploy
117+
118+
push:
119+
name: optional: docker push
120+
runs-on: ubuntu-latest
121+
needs: build
122+
if: ${{ secrets.DOCKERHUB_USERNAME && secrets.DOCKERHUB_TOKEN }}
123+
steps:
124+
- name: Checkout
125+
uses: actions/checkout@v4
126+
127+
- name: Login to Docker registry
128+
uses: docker/login-action@v2
129+
with:
130+
username: ${{ secrets.DOCKERHUB_USERNAME }}
131+
password: ${{ secrets.DOCKERHUB_TOKEN }}
132+
133+
- name: Push image
134+
uses: docker/build-push-action@v4
135+
with:
136+
context: .
137+
file: ./Dockerfile
138+
push: true
139+
tags: |
140+
${{ env.IMAGE }}:${{ github.sha }}
141+
${{ env.IMAGE }}:latest
142+
143+
done-notify:
144+
name: done
145+
runs-on: ubuntu-latest
146+
needs: [build]
147+
steps:
148+
- name: Done
149+
run: echo "CI finished. Image: $IMAGE (pushed if credentials provided)"

.husky/pre-commit

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
# Run lint-staged (configured in package.json)
5+
npx --no-install lint-staged

Dockerfile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
FROM node:20-bullseye-slim AS deps
2+
WORKDIR /app
3+
# Install system deps needed by some native modules (sharp, etc.)
4+
RUN apt-get update && apt-get install -y --no-install-recommends build-essential python3 && rm -rf /var/lib/apt/lists/*
5+
6+
# Copy package manifests and install deps first so Docker layer cache helps on rebuilds
7+
COPY package.json package-lock.json* ./
8+
RUN npm ci --ignore-scripts --no-audit --no-fund || npm install --no-audit --no-fund
9+
10+
FROM node:20-bullseye-slim AS base
11+
WORKDIR /app
12+
COPY --from=deps /app/node_modules ./node_modules
13+
COPY . .
14+
15+
FROM base AS dev
16+
ENV NODE_ENV=development
17+
EXPOSE 3000
18+
CMD ["sh", "-c", "npm run dev"]
19+
20+
FROM base AS build
21+
ENV NODE_ENV=production
22+
RUN npm run build
23+
24+
FROM node:20-bullseye-slim AS prod
25+
WORKDIR /app
26+
COPY --from=build /app .
27+
ENV NODE_ENV=production
28+
EXPOSE 3000
29+
CMD ["sh", "-c", "npm run start"]

README.md

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,75 @@
11
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
22

3-
## Getting Started
3+
# Getting started
44

5-
First, prepare the development server:
5+
Requirements
6+
- Docker & Docker Compose
7+
- PowerShell (commands below use PowerShell syntax)
68

7-
```bash
8-
npx prisma generate
9+
Quick start:
10+
11+
```powershell
12+
# Run all services, install dependencies and apply migrations
13+
docker compose up --build
914
```
1015

11-
Then run the dev server:
16+
Open http://localhost:3000 to see the results.
1217

13-
```bash
14-
npm run dev
18+
19+
Services one by one start:
20+
21+
1) Apply migrations (one-off):
22+
23+
```powershell
24+
# Run the migrate service: installs dependencies and runs 'npx prisma migrate deploy'
25+
docker compose -f .\docker-compose.yml run --rm migrate
26+
```
27+
28+
2) Start the app and database in the background:
29+
30+
```powershell
31+
docker compose -f .\docker-compose.yml up -d
1532
```
1633

17-
Open [http://localhost:3000](http://localhost:3000) to see the results.
34+
3) Tail app logs:
35+
36+
```powershell
37+
docker compose -f .\docker-compose.yml logs --follow --tail 200 app
38+
```
1839

40+
Useful commands
1941

42+
```powershell
43+
# Check service status
44+
docker compose -f .\docker-compose.yml ps
2045
21-
## The project features so far
46+
# Run migrate manually (one-off / CI)
47+
docker compose -f .\docker-compose.yml run --rm migrate
48+
49+
# List tables in the Postgres database
50+
docker compose -f .\docker-compose.yml exec postgres psql -U admin -d boardsy -c "\dt"
51+
52+
# Stop and remove containers and volumes (including node_modules volume)
53+
docker compose -f .\docker-compose.yml down --volumes
54+
```
2255

23-
Below is a directory graph of the actual project structure under `src/`, followed by a breakdown of each route and its Server Actions:
56+
Why there is a `migrate` service?
57+
58+
- The `migrate` service is a one-off container that installs project dependencies and runs `npx prisma migrate deploy` against the database running in Compose. This avoids running migrations manually on the host.
59+
- After migrations finish, the `migrate` container exits. This is expected.
60+
61+
About `node_modules` and Windows
62+
63+
- We use a named Docker volume for `node_modules` to avoid common Windows <-> container filesystem issues (for example, `ENOTEMPTY` errors during `npm install`). If something goes wrong, you can remove the volume with `docker compose down --volumes` and restart.
64+
65+
Troubleshooting (common issues)
66+
67+
- Can't reach database (`P1001` / "Can't reach database server at localhost:5432"): make sure services use the internal Compose hostname `postgres`. The compose file in this repo sets `LOCAL_DATABASE_URL` for `app` and `migrate` to use the `postgres` service.
68+
- `ENOTEMPTY` during `npm install` in the container: handled by using a named `node_modules` volume. If it persists, remove that volume and retry.
69+
70+
Open http://localhost:3000 to see the results.
71+
72+
## Project structure (high level)
2473

2574
```bash
2675
src/
@@ -46,13 +95,3 @@ src/
4695
└─ types/
4796
└─ global.d.ts # Global type declarations
4897
```
49-
50-
51-
52-
53-
## Learn More
54-
55-
To learn more about Next.js, take a look at the following resources:
56-
57-
* [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
58-
* [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

0 commit comments

Comments
 (0)