dockerized version instead of nixpack

This commit is contained in:
Greg 2025-08-17 01:01:31 +02:00
parent 7b98d2c894
commit a76b371bda
6 changed files with 77 additions and 21 deletions

11
.dockerignore Normal file
View File

@ -0,0 +1,11 @@
node_modules
dist
.git
.vscode
.idea
.DS_Store
.env
npm-debug.log*
yarn-*.log*
pnpm-debug.log*
docker-compose.yml

28
Dockerfile Normal file
View File

@ -0,0 +1,28 @@
# syntax=docker/dockerfile:1.7
ARG NODE_VERSION=20.15.0
FROM node:${NODE_VERSION}-alpine AS build
WORKDIR /app
# Install deps first for better caching
COPY package*.json ./
RUN npm ci || npm install
# Build
COPY . .
ENV NODE_ENV=production
# Limit Node heap during build to avoid OOM on small builders
ENV NODE_OPTIONS=--max-old-space-size=512
RUN npm run build
# ---- Runtime (Nginx) ----
FROM nginx:1.27-alpine AS runtime
# Remove default site content
RUN rm -rf /usr/share/nginx/html/*
# SPA config (history fallback)
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
# Static assets
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD wget -qO- http://localhost/ >/dev/null 2>&1 || exit 1
CMD ["nginx", "-g", "daemon off;"]

View File

@ -1,29 +1,31 @@
# Reading Goal App # Reading Goal App (Dockerized)
A React + Vite + Tailwind single-page app. Dates are DD/MM/YYYY everywhere and the calendar starts on Monday. React + Vite + Tailwind. Dates use **DD/MM/YYYY** and the calendar week starts on **Monday**.
Includes a multi-stage Dockerfile: Node build → Nginx runtime with SPA fallback.
## Local Development
## Local Dev
```bash ```bash
npm install npm install
npm run dev npm run dev
``` ```
## Production Build ## Production Build (local)
```bash ```bash
npm run build npm run build
npm run preview npm run preview
``` ```
## Deploy with Coolify (Nixpacks) ## Docker (build locally)
```bash
docker build -t reading-goal-app:latest .
docker run -d --name reading-goal-app -p 8080:80 --restart unless-stopped reading-goal-app:latest
# Open http://localhost:8080
```
1. Push this repo to GitHub. ## Deploy in Coolify
2. In Coolify: **Create Application → Git**, select your repo/branch. - Deployment Type: **Dockerfile**
3. **Build Pack**: choose **Nixpacks**. - Dockerfile path: `Dockerfile`
4. No base directory unless you're using a monorepo. - **Internal Port**: `80` (Nginx)
5. (Optional) **Environment**: set `NODE_ENV=production`. - No extra start command needed.
6. Deploy. The container will:
- install dependencies The multi-stage image builds the app (`vite build`) and serves static files via Nginx with history API fallback.
- build with `vite build` (output in `dist/`)
- run `serve -s dist -l $PORT` (Coolify injects `$PORT`)

18
docker/nginx.conf Normal file
View File

@ -0,0 +1,18 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# Serve files if they exist, else fallback to index.html (SPA)
location / {
try_files $uri $uri/ /index.html;
}
# Static assets (cache-friendly)
location ~* \.(?:js|css|png|jpg|jpeg|gif|svg|ico|woff2?)$ {
expires 30d;
add_header Cache-Control "public, immutable";
try_files $uri /index.html;
}
}

View File

@ -6,8 +6,7 @@
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build",
"preview": "vite preview --host 0.0.0.0 --port 5173", "preview": "vite preview --host 0.0.0.0 --port 5173"
"start": "serve -s dist -l ${PORT:-3000}"
}, },
"dependencies": { "dependencies": {
"lucide-react": "^0.452.0", "lucide-react": "^0.452.0",
@ -20,7 +19,6 @@
"@vitejs/plugin-react": "^4.2.0", "@vitejs/plugin-react": "^4.2.0",
"autoprefixer": "^10.4.18", "autoprefixer": "^10.4.18",
"postcss": "^8.4.33", "postcss": "^8.4.33",
"serve": "^14.2.1",
"tailwindcss": "^3.4.9", "tailwindcss": "^3.4.9",
"typescript": "^5.5.4", "typescript": "^5.5.4",
"vite": "^5.3.4" "vite": "^5.3.4"

View File

@ -1,4 +1,3 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { BookOpen, Plus, X, Edit2, Check, ChevronLeft, ChevronRight } from 'lucide-react'; import { BookOpen, Plus, X, Edit2, Check, ChevronLeft, ChevronRight } from 'lucide-react';
@ -598,7 +597,7 @@ const ReadingGoalApp = () => {
<h3 className="font-semibold mb-3">Progress Overview</h3> <h3 className="font-semibold mb-3">Progress Overview</h3>
<div className="space-y-3"> <div className="space-y-3">
<div className="flex justify-between"><span className="text-gray-600">Current Progress</span><span className="font-medium">{book.currentPage} / {book.totalPages} pages</span></div> <div className="flex justify-between"><span className="text-gray-600">Current Progress</span><span className="font-medium">{book.currentPage} / {book.totalPages} pages</span></div>
<div className="w.full bg-gray-200 rounded-full h-3"><div className="bg-blue-500 h-3 rounded-full transition-all" style={{ width: `${Math.min(progressPercent, 100)}%` }} /></div> <div className="w-full bg-gray-200 rounded-full h-3"><div className="bg-blue-500 h-3 rounded-full transition-all" style={{ width: `${Math.min(progressPercent, 100)}%` }} /></div>
<div className="flex justify-between"><span className="text-gray-600">Completion</span><span className="font-medium">{progressPercent.toFixed(1)}%</span></div> <div className="flex justify-between"><span className="text-gray-600">Completion</span><span className="font-medium">{progressPercent.toFixed(1)}%</span></div>
</div> </div>
</div> </div>