chore: Add deployment checklist and PM2 configuration examples
Some checks failed
CI / test-backend (pull_request) Successful in 5m30s
CI / build (pull_request) Has been skipped
CI / secret-scanning (pull_request) Has been skipped
CI / dependency-scan (pull_request) Has been skipped
CI / sast-scan (pull_request) Has been skipped
CI / lint-and-type-check (pull_request) Has been cancelled
CI / python-lint (pull_request) Has been cancelled
CI / workflow-summary (pull_request) Has been cancelled
CI / skip-ci-check (pull_request) Has been cancelled
Some checks failed
CI / test-backend (pull_request) Successful in 5m30s
CI / build (pull_request) Has been skipped
CI / secret-scanning (pull_request) Has been skipped
CI / dependency-scan (pull_request) Has been skipped
CI / sast-scan (pull_request) Has been skipped
CI / lint-and-type-check (pull_request) Has been cancelled
CI / python-lint (pull_request) Has been cancelled
CI / workflow-summary (pull_request) Has been cancelled
CI / skip-ci-check (pull_request) Has been cancelled
This commit introduces a new `DEPLOYMENT_CHECKLIST.md` file that outlines the necessary steps for configuring server-specific settings after pulling from Git. It includes instructions for environment files, PM2 configuration, firewall rules, database setup, and building frontends. Additionally, it adds an example `ecosystem.config.js.example` file for PM2 configuration, providing a template for users to customize for their deployment environment. The `.gitignore` file is updated to include the new PM2 ecosystem config file.
This commit is contained in:
parent
9ddd7c04eb
commit
51081c1b5d
4
.gitignore
vendored
4
.gitignore
vendored
@ -80,3 +80,7 @@ archive/
|
||||
demo_photos/
|
||||
data/uploads/
|
||||
data/thumbnails/
|
||||
|
||||
|
||||
# PM2 ecosystem config (server-specific paths)
|
||||
ecosystem.config.js
|
||||
|
||||
93
DEPLOYMENT_CHECKLIST.md
Normal file
93
DEPLOYMENT_CHECKLIST.md
Normal file
@ -0,0 +1,93 @@
|
||||
# Deployment Checklist
|
||||
|
||||
After pulling from Git, configure the following server-specific settings:
|
||||
|
||||
## 1. Environment Files (gitignored - safe to modify)
|
||||
|
||||
### Root `.env`
|
||||
```bash
|
||||
# Database connections
|
||||
DATABASE_URL=postgresql+psycopg2://user:password@10.0.10.181:5432/punimtag
|
||||
DATABASE_URL_AUTH=postgresql+psycopg2://user:password@10.0.10.181:5432/punimtag_auth
|
||||
|
||||
# JWT Secrets
|
||||
SECRET_KEY=your-secret-key-here
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_PASSWORD=admin
|
||||
|
||||
# Photo storage
|
||||
PHOTO_STORAGE_DIR=/opt/punimtag/data/uploads
|
||||
```
|
||||
|
||||
### `admin-frontend/.env`
|
||||
```bash
|
||||
VITE_API_URL=http://10.0.10.121:8000
|
||||
```
|
||||
|
||||
### `viewer-frontend/.env`
|
||||
```bash
|
||||
DATABASE_URL=postgresql://user:password@10.0.10.181:5432/punimtag
|
||||
DATABASE_URL_AUTH=postgresql://user:password@10.0.10.181:5432/punimtag_auth
|
||||
NEXTAUTH_URL=http://10.0.10.121:3001
|
||||
NEXTAUTH_SECRET=your-secret-key-here
|
||||
AUTH_URL=http://10.0.10.121:3001
|
||||
```
|
||||
|
||||
## 2. PM2 Configuration
|
||||
|
||||
Copy the template and customize for your server:
|
||||
|
||||
```bash
|
||||
cp ecosystem.config.js.example ecosystem.config.js
|
||||
```
|
||||
|
||||
Edit `ecosystem.config.js` and update:
|
||||
- All `cwd` paths to your deployment directory
|
||||
- All `error_file` and `out_file` paths to your user's home directory
|
||||
- `PYTHONPATH` and `PATH` environment variables
|
||||
|
||||
## 3. System Configuration (One-time setup)
|
||||
|
||||
### Firewall Rules
|
||||
```bash
|
||||
sudo ufw allow 3000/tcp # Admin frontend
|
||||
sudo ufw allow 3001/tcp # Viewer frontend
|
||||
sudo ufw allow 8000/tcp # Backend API
|
||||
```
|
||||
|
||||
### Database Setup
|
||||
Create admin user in auth database:
|
||||
```bash
|
||||
cd viewer-frontend
|
||||
npx tsx scripts/fix-admin-user.ts
|
||||
```
|
||||
|
||||
## 4. Build Frontends
|
||||
|
||||
```bash
|
||||
# Admin frontend
|
||||
cd admin-frontend
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
# Viewer frontend
|
||||
cd viewer-frontend
|
||||
npm install
|
||||
npm run prisma:generate:all
|
||||
npm run build
|
||||
```
|
||||
|
||||
## 5. Start Services
|
||||
|
||||
```bash
|
||||
pm2 start ecosystem.config.js
|
||||
pm2 save
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- `.env` files are gitignored and safe to modify
|
||||
- `ecosystem.config.js` is gitignored and server-specific
|
||||
- Database changes (admin user) persist across pulls
|
||||
- Firewall rules are system-level and persist
|
||||
|
||||
3
admin-frontend/serve.sh
Normal file
3
admin-frontend/serve.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
cd "$(dirname "$0")"
|
||||
PORT=3000 HOST=0.0.0.0 exec npx --yes serve dist
|
||||
@ -76,6 +76,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
|
||||
const login = async (username: string, password: string) => {
|
||||
try {
|
||||
setAuthState((prev) => ({ ...prev, isLoading: true }))
|
||||
const tokens: TokenResponse = await authApi.login({ username, password })
|
||||
localStorage.setItem('access_token', tokens.access_token)
|
||||
localStorage.setItem('refresh_token', tokens.refresh_token)
|
||||
@ -92,9 +93,11 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
})
|
||||
return { success: true, passwordChangeRequired }
|
||||
} catch (error: any) {
|
||||
setAuthState((prev) => ({ ...prev, isLoading: false }))
|
||||
console.error('Login error:', error)
|
||||
return {
|
||||
success: false,
|
||||
error: error.response?.data?.detail || 'Login failed',
|
||||
error: error.response?.data?.detail || error.message || 'Login failed',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,9 +344,18 @@ def get_current_user_info(
|
||||
is_admin = user.is_admin if user else False
|
||||
|
||||
role_value = _resolve_user_role(user, is_admin)
|
||||
permissions_map = fetch_role_permissions_map(db)
|
||||
permissions = permissions_map.get(role_value, {})
|
||||
|
||||
|
||||
# Fetch permissions - if it fails, return empty permissions to avoid blocking login
|
||||
try:
|
||||
permissions_map = fetch_role_permissions_map(db)
|
||||
permissions = permissions_map.get(role_value, {})
|
||||
except Exception as e:
|
||||
# If permissions fetch fails, return empty permissions to avoid blocking login
|
||||
# Log the error but don't fail the request
|
||||
import traceback
|
||||
print(f"⚠️ Failed to fetch permissions for /me endpoint: {e}")
|
||||
print(f" Traceback: {traceback.format_exc()}")
|
||||
permissions = {}
|
||||
return UserResponse(
|
||||
username=username,
|
||||
is_admin=is_admin,
|
||||
|
||||
@ -634,7 +634,13 @@ async def lifespan(app: FastAPI):
|
||||
# This must happen BEFORE we try to use the engine
|
||||
ensure_postgresql_database(database_url)
|
||||
|
||||
# Note: Auth database is managed by the frontend, not created here
|
||||
# Ensure auth database exists if configured
|
||||
try:
|
||||
auth_db_url = get_auth_database_url()
|
||||
ensure_postgresql_database(auth_db_url)
|
||||
except ValueError:
|
||||
# DATABASE_URL_AUTH not set - that's okay
|
||||
pass
|
||||
|
||||
# Only create tables if they don't already exist (safety check)
|
||||
inspector = inspect(engine)
|
||||
|
||||
69
ecosystem.config.js.example
Normal file
69
ecosystem.config.js.example
Normal file
@ -0,0 +1,69 @@
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: 'punimtag-api',
|
||||
script: 'venv/bin/uvicorn',
|
||||
args: 'backend.app:app --host 0.0.0.0 --port 8000',
|
||||
cwd: '/opt/punimtag', // CHANGE: Update to your deployment directory
|
||||
interpreter: 'none',
|
||||
env: {
|
||||
PYTHONPATH: '/opt/punimtag', // CHANGE: Update to your deployment directory
|
||||
PATH: '/opt/punimtag/venv/bin:/usr/local/bin:/usr/bin:/bin', // CHANGE: Update paths
|
||||
},
|
||||
error_file: '/home/appuser/.pm2/logs/punimtag-api-error.log', // CHANGE: Update user home directory
|
||||
out_file: '/home/appuser/.pm2/logs/punimtag-api-out.log', // CHANGE: Update user home directory
|
||||
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
||||
merge_logs: true,
|
||||
autorestart: true,
|
||||
watch: false,
|
||||
max_memory_restart: '1G',
|
||||
},
|
||||
{
|
||||
name: 'punimtag-worker',
|
||||
script: 'venv/bin/python',
|
||||
args: '-m backend.worker',
|
||||
cwd: '/opt/punimtag', // CHANGE: Update to your deployment directory
|
||||
interpreter: 'none',
|
||||
env: {
|
||||
PYTHONPATH: '/opt/punimtag', // CHANGE: Update to your deployment directory
|
||||
PATH: '/opt/punimtag/venv/bin:/usr/local/bin:/usr/bin:/bin', // CHANGE: Update paths
|
||||
},
|
||||
error_file: '/home/appuser/.pm2/logs/punimtag-worker-error.log', // CHANGE: Update user home directory
|
||||
out_file: '/home/appuser/.pm2/logs/punimtag-worker-out.log', // CHANGE: Update user home directory
|
||||
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
||||
merge_logs: true,
|
||||
autorestart: true,
|
||||
watch: false,
|
||||
max_memory_restart: '1G',
|
||||
},
|
||||
{
|
||||
name: 'punimtag-admin',
|
||||
script: './serve.sh',
|
||||
cwd: '/opt/punimtag/admin-frontend', // CHANGE: Update to your deployment directory
|
||||
interpreter: 'bash',
|
||||
error_file: '/home/appuser/.pm2/logs/punimtag-admin-error.log', // CHANGE: Update user home directory
|
||||
out_file: '/home/appuser/.pm2/logs/punimtag-admin-out.log', // CHANGE: Update user home directory
|
||||
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
||||
merge_logs: true,
|
||||
autorestart: true,
|
||||
watch: false,
|
||||
},
|
||||
{
|
||||
name: 'punimtag-viewer',
|
||||
script: 'npm',
|
||||
args: 'run start:3001',
|
||||
cwd: '/opt/punimtag/viewer-frontend', // CHANGE: Update to your deployment directory
|
||||
interpreter: 'node',
|
||||
env: {
|
||||
PORT: '3001',
|
||||
},
|
||||
error_file: '/home/appuser/.pm2/logs/punimtag-viewer-error.log', // CHANGE: Update user home directory
|
||||
out_file: '/home/appuser/.pm2/logs/punimtag-viewer-out.log', // CHANGE: Update user home directory
|
||||
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
||||
merge_logs: true,
|
||||
autorestart: true,
|
||||
watch: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
23
start_all.sh
23
start_all.sh
@ -18,6 +18,7 @@ echo ""
|
||||
cleanup() {
|
||||
echo ""
|
||||
echo -e "${YELLOW}Shutting down all servers...${NC}"
|
||||
kill $WORKER_PID 2>/dev/null || true
|
||||
kill $BACKEND_PID 2>/dev/null || true
|
||||
kill $ADMIN_PID 2>/dev/null || true
|
||||
kill $VIEWER_PID 2>/dev/null || true
|
||||
@ -45,6 +46,27 @@ if [ -d "venv" ]; then
|
||||
source venv/bin/activate
|
||||
fi
|
||||
export PYTHONPATH="$(pwd)"
|
||||
|
||||
# Check if Redis is running
|
||||
if ! redis-cli ping > /dev/null 2>&1; then
|
||||
echo -e "${YELLOW}⚠️ Redis is not running. Starting Redis...${NC}"
|
||||
redis-server --daemonize yes 2>/dev/null || {
|
||||
echo -e "${YELLOW}❌ Failed to start Redis. Please start it manually: redis-server${NC}"
|
||||
exit 1
|
||||
}
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
# Start RQ worker in background
|
||||
echo -e "${GREEN}🚀 Starting RQ worker...${NC}"
|
||||
env PYTHONPATH="$(pwd)" "$PYTHON_BIN" -m backend.worker > /tmp/worker.log 2>&1 &
|
||||
WORKER_PID=$!
|
||||
|
||||
# Give worker a moment to start
|
||||
sleep 2
|
||||
|
||||
# Start FastAPI server
|
||||
echo -e "${GREEN}🚀 Starting FastAPI server...${NC}"
|
||||
"$PYTHON_BIN" -m uvicorn backend.app:app --host 127.0.0.1 --port 8000 --reload > /tmp/backend.log 2>&1 &
|
||||
BACKEND_PID=$!
|
||||
|
||||
@ -75,6 +97,7 @@ echo -e " Admin Frontend: ${GREEN}http://127.0.0.1:3000${NC}"
|
||||
echo -e " Viewer Frontend: ${GREEN}http://127.0.0.1:3001${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}📋 Logs:${NC}"
|
||||
echo -e " Worker: ${BLUE}/tmp/worker.log${NC}"
|
||||
echo -e " Backend: ${BLUE}/tmp/backend.log${NC}"
|
||||
echo -e " Admin: ${BLUE}/tmp/admin-frontend.log${NC}"
|
||||
echo -e " Viewer: ${BLUE}/tmp/viewer-frontend.log${NC}"
|
||||
|
||||
@ -5,6 +5,7 @@ import bcrypt from 'bcryptjs';
|
||||
|
||||
export const { handlers, signIn, signOut, auth } = NextAuth({
|
||||
secret: process.env.NEXTAUTH_SECRET,
|
||||
trustHost: true, // Trust all hosts (for development/internal network)
|
||||
providers: [
|
||||
CredentialsProvider({
|
||||
name: 'Credentials',
|
||||
|
||||
451
viewer-frontend/package-lock.json
generated
451
viewer-frontend/package-lock.json
generated
@ -39,11 +39,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/better-sqlite3": "^7.6.13",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"better-sqlite3": "^12.5.0",
|
||||
"dotenv": "^17.2.3",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "16.0.3",
|
||||
@ -1993,16 +1991,6 @@
|
||||
"version": "2.4.6",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/better-sqlite3": {
|
||||
"version": "7.6.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.13.tgz",
|
||||
"integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.8",
|
||||
"dev": true,
|
||||
@ -2585,27 +2573,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/baseline-browser-mapping": {
|
||||
"version": "2.9.11",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz",
|
||||
@ -2622,58 +2589,6 @@
|
||||
"bcrypt": "bin/bcrypt"
|
||||
}
|
||||
},
|
||||
"node_modules/better-sqlite3": {
|
||||
"version": "12.5.0",
|
||||
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.5.0.tgz",
|
||||
"integrity": "sha512-WwCZ/5Diz7rsF29o27o0Gcc1Du+l7Zsv7SYtVPG0X3G/uUI1LqdxrQI7c9Hs2FWpqXXERjW9hp6g3/tH7DlVKg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bindings": "^1.5.0",
|
||||
"prebuild-install": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20.x || 22.x || 23.x || 24.x || 25.x"
|
||||
}
|
||||
},
|
||||
"node_modules/bindings": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"file-uri-to-path": "1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bl/node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
"dev": true,
|
||||
@ -2726,31 +2641,6 @@
|
||||
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"node_modules/c12": {
|
||||
"version": "3.1.0",
|
||||
"license": "MIT",
|
||||
@ -2918,13 +2808,6 @@
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/chownr": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/citty": {
|
||||
"version": "0.1.6",
|
||||
"license": "MIT",
|
||||
@ -3093,32 +2976,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decompress-response": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mimic-response": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deep-is": {
|
||||
"version": "0.1.4",
|
||||
"dev": true,
|
||||
@ -3253,16 +3110,6 @@
|
||||
"iconv-lite": "^0.6.2"
|
||||
}
|
||||
},
|
||||
"node_modules/end-of-stream": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
|
||||
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.18.4",
|
||||
"dev": true,
|
||||
@ -4323,16 +4170,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/expand-template": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
|
||||
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
|
||||
"dev": true,
|
||||
"license": "(MIT OR WTFPL)",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/exponential-backoff": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz",
|
||||
@ -4444,13 +4281,6 @@
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/file-uri-to-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.1.1",
|
||||
"dev": true,
|
||||
@ -4533,13 +4363,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/fs-constants": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fs-minipass": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz",
|
||||
@ -4688,13 +4511,6 @@
|
||||
"giget": "dist/cli.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/github-from-package": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
|
||||
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "13.0.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz",
|
||||
@ -4924,27 +4740,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.2",
|
||||
"dev": true,
|
||||
@ -4984,13 +4779,6 @@
|
||||
"version": "2.0.4",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ini": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/internal-slot": {
|
||||
"version": "1.1.0",
|
||||
"dev": true,
|
||||
@ -5908,19 +5696,6 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-response": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"dev": true,
|
||||
@ -6093,13 +5868,6 @@
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp-classic": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/motion-dom": {
|
||||
"version": "12.23.23",
|
||||
"license": "MIT",
|
||||
@ -6132,13 +5900,6 @@
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/napi-build-utils": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
|
||||
"integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/napi-postinstall": {
|
||||
"version": "0.3.4",
|
||||
"dev": true,
|
||||
@ -6272,32 +6033,6 @@
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/node-abi": {
|
||||
"version": "3.85.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.85.0.tgz",
|
||||
"integrity": "sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"semver": "^7.3.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/node-abi/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "8.5.0",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.5.0.tgz",
|
||||
@ -6532,16 +6267,6 @@
|
||||
"version": "2.0.11",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/optionator": {
|
||||
"version": "0.9.4",
|
||||
"dev": true,
|
||||
@ -6762,33 +6487,6 @@
|
||||
"preact": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/prebuild-install": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
|
||||
"integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"detect-libc": "^2.0.0",
|
||||
"expand-template": "^2.0.3",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "^1.2.3",
|
||||
"mkdirp-classic": "^0.5.3",
|
||||
"napi-build-utils": "^2.0.0",
|
||||
"node-abi": "^3.3.0",
|
||||
"pump": "^3.0.0",
|
||||
"rc": "^1.2.7",
|
||||
"simple-get": "^4.0.0",
|
||||
"tar-fs": "^2.0.0",
|
||||
"tunnel-agent": "^0.6.0"
|
||||
},
|
||||
"bin": {
|
||||
"prebuild-install": "bin.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/prelude-ls": {
|
||||
"version": "1.2.1",
|
||||
"dev": true,
|
||||
@ -6858,17 +6556,6 @@
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
|
||||
"integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"dev": true,
|
||||
@ -6914,32 +6601,6 @@
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/rc": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
||||
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
|
||||
"dev": true,
|
||||
"license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
|
||||
"dependencies": {
|
||||
"deep-extend": "^0.6.0",
|
||||
"ini": "~1.3.0",
|
||||
"minimist": "^1.2.0",
|
||||
"strip-json-comments": "~2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"rc": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/rc/node_modules/strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rc9": {
|
||||
"version": "2.1.2",
|
||||
"license": "MIT",
|
||||
@ -7938,53 +7599,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-concat": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
|
||||
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/simple-get": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
|
||||
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"decompress-response": "^6.0.0",
|
||||
"once": "^1.3.1",
|
||||
"simple-concat": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/smart-buffer": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
||||
@ -8294,51 +7908,6 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-fs": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
|
||||
"integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chownr": "^1.1.1",
|
||||
"mkdirp-classic": "^0.5.2",
|
||||
"pump": "^3.0.0",
|
||||
"tar-stream": "^2.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-stream": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
||||
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bl": "^4.0.3",
|
||||
"end-of-stream": "^1.4.1",
|
||||
"fs-constants": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-stream/node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/tar/node_modules/chownr": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
|
||||
@ -8462,19 +8031,6 @@
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/tw-animate-css": {
|
||||
"version": "1.4.0",
|
||||
"dev": true,
|
||||
@ -9140,13 +8696,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "3.1.1",
|
||||
"dev": true,
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
"prebuild": "npm run prisma:generate:all",
|
||||
"build": "./scripts/with-sharp-libpath.sh next build",
|
||||
"start": "./scripts/with-sharp-libpath.sh next start",
|
||||
"start:3001": "PORT=3001 ./scripts/with-sharp-libpath.sh next start",
|
||||
"lint": "next lint",
|
||||
"type-check": "tsc --noEmit",
|
||||
"prisma:generate": "prisma generate",
|
||||
|
||||
@ -6,6 +6,13 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
SHARP_LIB_PATH="$PROJECT_DIR/node_modules/sharp/node_modules/@img/sharp-libvips-linux-x64/lib"
|
||||
|
||||
# Add node_modules/.bin to PATH if it exists
|
||||
if [ -d "$PROJECT_DIR/node_modules/.bin" ]; then
|
||||
export PATH="$PROJECT_DIR/node_modules/.bin:$PATH"
|
||||
fi
|
||||
|
||||
# Change to project directory to ensure relative paths work
|
||||
cd "$PROJECT_DIR" || exit 1
|
||||
if [ -d "$SHARP_LIB_PATH" ]; then
|
||||
export LD_LIBRARY_PATH="$SHARP_LIB_PATH:${LD_LIBRARY_PATH:-}"
|
||||
exec "$@"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user