Skip to content

Commit 6fd0894

Browse files
feat: docker deployment (#16)
* created multistage Dockerfile with docker-compose.yaml for production and development, added steps on how to run it into README.md * feat: add Docker Hub publishing workflow and improve build - Add GitHub Actions workflow for automated Docker Hub publishing - Increase Node.js heap size to fix build memory issues - Update docker-compose.yaml to use published image - Support multi-platform builds (linux/amd64, linux/arm64) * docs: update README with Docker Hub integration and badges * perf: optimize .dockerignore for smaller build context - Add comprehensive .dockerignore rules to exclude unnecessary files - Reduce build context from ~5.59MB to ~534KB (90% reduction) - Exclude Git, documentation, test files, and mobile SDKs from Docker image - Improve build performance and security by filtering sensitive files - Maintain required files like package.json and pnpm-lock.yaml for builds * created multistage Dockerfile with docker-compose.yaml for production and development, added steps on how to run it into README.md * feat: add Docker Hub publishing workflow and improve build - Add GitHub Actions workflow for automated Docker Hub publishing - Increase Node.js heap size to fix build memory issues - Update docker-compose.yaml to use published image - Support multi-platform builds (linux/amd64, linux/arm64) * perf: optimize .dockerignore for smaller build context - Add comprehensive .dockerignore rules to exclude unnecessary files - Reduce build context from ~5.59MB to ~534KB (90% reduction) - Exclude Git, documentation, test files, and mobile SDKs from Docker image - Improve build performance and security by filtering sensitive files - Maintain required files like package.json and pnpm-lock.yaml for builds * Remove the migration container. --------- Co-authored-by: productdevbook <hi@productdevbook.com>
1 parent ba88fb3 commit 6fd0894

File tree

6 files changed

+260
-1
lines changed

6 files changed

+260
-1
lines changed

.dockerignore

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Dependencies
2+
node_modules
3+
4+
# Git and version control
5+
.git
6+
.gitignore
7+
.github
8+
9+
# Development and testing
10+
tests
11+
coverage
12+
vitest.config.ts
13+
*.test.ts
14+
*.spec.ts
15+
16+
# Documentation
17+
docs
18+
README.md
19+
CLAUDE.md
20+
*.md
21+
!package.json
22+
23+
# Environment and configuration
24+
.env
25+
.env.*
26+
!.env.example
27+
28+
# Build outputs and cache
29+
.output
30+
.data
31+
.nuxt
32+
.nitro
33+
.cache
34+
dist
35+
36+
# IDE and editor files
37+
.idea
38+
.vscode
39+
.DS_Store
40+
*.swp
41+
*.swo
42+
43+
# Mobile SDKs (not needed in Docker)
44+
android
45+
ios
46+
47+
# Logs
48+
*.log
49+
logs
50+
51+
# Configuration files (build-time not needed)
52+
eslint.config.mjs
53+
components.json
54+
graphql.config.ts
55+
56+
# Development utilities
57+
nitroping

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Database
2+
POSTGRES_USER=user
3+
POSTGRES_PASSWORD=password
4+
POSTGRES_DB=nitroping
25
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/nitroping
36

47
# JWT Secret (for API authentication)
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: Build and Push Docker Image
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- 'v*'
9+
pull_request:
10+
branches:
11+
- main
12+
13+
env:
14+
REGISTRY: docker.io
15+
IMAGE_NAME: productdevbook/nitroping
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
permissions:
21+
contents: read
22+
packages: write
23+
24+
steps:
25+
- name: Checkout repository
26+
uses: actions/checkout@v4
27+
28+
- name: Set up Docker Buildx
29+
uses: docker/setup-buildx-action@v3
30+
31+
- name: Log in to Docker Hub
32+
if: github.event_name != 'pull_request'
33+
uses: docker/login-action@v3
34+
with:
35+
username: ${{ secrets.DOCKER_USERNAME }}
36+
password: ${{ secrets.DOCKER_PASSWORD }}
37+
38+
- name: Extract metadata
39+
id: meta
40+
uses: docker/metadata-action@v5
41+
with:
42+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
43+
tags: |
44+
type=ref,event=branch
45+
type=ref,event=pr
46+
type=semver,pattern={{version}}
47+
type=semver,pattern={{major}}.{{minor}}
48+
type=semver,pattern={{major}}
49+
type=raw,value=latest,enable={{is_default_branch}}
50+
51+
- name: Build and push Docker image
52+
uses: docker/build-push-action@v5
53+
with:
54+
context: .
55+
file: ./Dockerfile
56+
target: production
57+
platforms: linux/amd64,linux/arm64
58+
push: ${{ github.event_name != 'pull_request' }}
59+
tags: ${{ steps.meta.outputs.tags }}
60+
labels: ${{ steps.meta.outputs.labels }}
61+
cache-from: type=gha
62+
cache-to: type=gha,mode=max
63+
64+
- name: Test Docker image
65+
if: github.event_name == 'pull_request'
66+
run: |
67+
docker run --rm ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} --help || true

Dockerfile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
FROM node:22 AS base
2+
3+
WORKDIR /app
4+
5+
RUN npm install -g pnpm
6+
7+
COPY . .
8+
9+
RUN pnpm install --frozen-lockfile
10+
11+
FROM base AS build
12+
13+
ENV NODE_OPTIONS="--max-old-space-size=4096"
14+
RUN pnpm run build
15+
16+
FROM base AS dev
17+
18+
EXPOSE 3000
19+
20+
CMD ["pnpm", "dev"]
21+
22+
FROM node:22-alpine3.22 AS production
23+
24+
WORKDIR /app
25+
26+
COPY --from=build /app/.output /app
27+
28+
EXPOSE 3000
29+
30+
CMD ["node", "/app/server/index.mjs"]
31+

README.md

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
<p align="center">
1212
<a href="https://nitroping.dev"><img src="https://img.shields.io/badge/website-nitroping.dev-00DC82?style=flat&colorA=020420" alt="Website"></a>
13+
<a href="https://hub.docker.com/r/productdevbook/nitroping"><img src="https://img.shields.io/docker/pulls/productdevbook/nitroping.svg?style=flat&colorA=020420&colorB=00DC82" alt="Docker Pulls"></a>
1314
<a href="https://npmjs.org/package/nitroping"><img src="https://img.shields.io/npm/v/nitroping.svg?style=flat&colorA=020420&colorB=00DC82" alt="npm version"></a>
1415
<a href="https://npmjs.org/package/nitroping"><img src="https://img.shields.io/npm/dt/nitroping.svg?style=flat&colorA=020420&colorB=00DC82" alt="npm downloads"></a>
1516
<a href="https://github.com/productdevbook/nitroping/blob/main/LICENSE"><img src="https://img.shields.io/github/license/productdevbook/nitroping.svg?style=flat&colorA=020420&colorB=00DC82" alt="License"></a>
@@ -179,6 +180,49 @@ graph TB
179180
```bash
180181
pnpm dev --host # Allows access from mobile devices on same network
181182
```
183+
184+
#### Docker
185+
If you prefer Docker, you can run NitroPing in a containerized environment. Make sure to set up the `.env` file with the necessary secrets and database connection details.
186+
187+
If running Docker compose for the first time, migration is needed. Run the docker compose with `migrate` profile to set up the database schema.
188+
189+
```bash
190+
docker compose up --profile migrate --profile dev -d
191+
```
192+
For subsequent runs, you can use the `dev` profile to start the application without migrating again.
193+
194+
```bash
195+
docker compose up --profile dev -d
196+
```
197+
For production deployments, you can use the `prod` profile to run the application in production mode.
198+
199+
```bash
200+
docker compose up --profile prod -d
201+
```
202+
203+
### 🐳 Docker Hub Image
204+
205+
Pull the latest image from Docker Hub:
206+
207+
```bash
208+
# Pull latest version
209+
docker pull productdevbook/nitroping:latest
210+
211+
# Or specific version
212+
docker pull productdevbook/nitroping:v0.0.1
213+
```
214+
215+
**Using with docker-compose.yaml:**
216+
```yaml
217+
services:
218+
server:
219+
image: productdevbook/nitroping:latest
220+
environment:
221+
DATABASE_URL: postgres://user:password@db:5432/nitroping
222+
ports:
223+
- "3000:3000"
224+
```
225+
182226
183227
### Your First Notification
184228
@@ -368,6 +412,7 @@ pnpm dev --host
368412
- Delivery tracking and metrics
369413
- Encrypted credential storage
370414
- JWT-based authentication
415+
- Docker deployment & Docker Hub publishing
371416

372417
</details>
373418

@@ -376,7 +421,6 @@ pnpm dev --host
376421

377422
- [Swift iOS SDK](https://github.com/productdevbook/nitroping/issues/14) - Native iOS integration
378423
- [Queue System](https://github.com/productdevbook/nitroping/issues/13) - Background job processing
379-
- Docker deployment configuration
380424
- Advanced scheduling features
381425

382426
</details>

docker-compose.yaml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
services:
2+
db:
3+
image: postgres:15
4+
container_name: postgres_db
5+
restart: always
6+
environment:
7+
POSTGRES_USER: ${POSTGRES_USER}
8+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
9+
POSTGRES_DB: ${POSTGRES_DB}
10+
volumes:
11+
- db_data:/var/lib/postgresql/data
12+
redis:
13+
image: redis:latest
14+
restart: always
15+
volumes:
16+
- redis_data:/data
17+
server:
18+
profiles: ["prod"]
19+
image: productdevbook/nitroping:v0.0.1
20+
restart: always
21+
environment:
22+
DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
23+
NITRO_HOST: 0.0.0.0
24+
env_file:
25+
- .env
26+
ports:
27+
- "3000:3000"
28+
depends_on:
29+
- db
30+
- redis
31+
server-dev:
32+
profiles: ["dev"]
33+
container_name: nitro_dev
34+
build:
35+
context: .
36+
dockerfile: Dockerfile
37+
target: development
38+
restart: always
39+
tty: true
40+
environment:
41+
DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
42+
NITRO_HOST: 0.0.0.0
43+
env_file:
44+
- .env
45+
ports:
46+
- "3000:3000"
47+
depends_on:
48+
- db
49+
- redis
50+
volumes:
51+
- ./server:/app
52+
- ./app:/app/app
53+
54+
55+
volumes:
56+
db_data:
57+
redis_data:

0 commit comments

Comments
 (0)