mirror of
https://github.com/open-reception/appointment-booking-software.git
synced 2026-08-17 21:25:52 +02:00
Docker configuration, build file for app
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
# Development Environment Configuration
|
||||||
|
# Copy this file to .env and fill in your values
|
||||||
|
|
||||||
|
# Database Configuration
|
||||||
|
POSTGRES_DB=appointment_booking
|
||||||
|
POSTGRES_USER=postgres
|
||||||
|
POSTGRES_PASSWORD=your_secure_password_here
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
|
||||||
|
# Application Configuration
|
||||||
|
NODE_ENV=development
|
||||||
|
APP_PORT=5173
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
node_modules/
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.production
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
.svelte-kit/
|
||||||
|
|
||||||
|
# Production secrets - NEVER commit these
|
||||||
|
secrets/*.txt
|
||||||
|
!secrets/.gitkeep
|
||||||
|
|
||||||
|
# Development
|
||||||
|
.DS_Store
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# Production Caddyfile for appointment booking application
|
||||||
|
# Replace your-domain.com with your actual domain
|
||||||
|
|
||||||
|
your-domain.com {
|
||||||
|
reverse_proxy app:3000
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
header {
|
||||||
|
-Server
|
||||||
|
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||||
|
X-Content-Type-Options "nosniff"
|
||||||
|
X-Frame-Options "DENY"
|
||||||
|
X-XSS-Protection "1; mode=block"
|
||||||
|
Referrer-Policy "strict-origin-when-cross-origin"
|
||||||
|
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'"
|
||||||
|
}
|
||||||
|
|
||||||
|
encode gzip
|
||||||
|
|
||||||
|
log {
|
||||||
|
output file /data/access.log {
|
||||||
|
roll_size 100mb
|
||||||
|
roll_keep 10
|
||||||
|
}
|
||||||
|
format json
|
||||||
|
}
|
||||||
|
|
||||||
|
tls {
|
||||||
|
protocols tls1.2 tls1.3
|
||||||
|
}
|
||||||
|
}
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
# Production Dockerfile for SvelteKit application
|
||||||
|
# Security: rootless container, minimal base image, non-privileged user
|
||||||
|
|
||||||
|
# Build stage
|
||||||
|
FROM node:24-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm ci --only=production --ignore-scripts && \
|
||||||
|
npm cache clean --force
|
||||||
|
|
||||||
|
# Copy source and build
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM node:24-alpine AS production
|
||||||
|
|
||||||
|
# Create non-root user
|
||||||
|
RUN addgroup -g 1001 -S nodejs && \
|
||||||
|
adduser -S sveltekit -u 1001 -G nodejs
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy built application and dependencies
|
||||||
|
COPY --from=builder --chown=sveltekit:nodejs /app/build ./build
|
||||||
|
COPY --from=builder --chown=sveltekit:nodejs /app/package*.json ./
|
||||||
|
COPY --from=builder --chown=sveltekit:nodejs /app/node_modules ./node_modules
|
||||||
|
|
||||||
|
# Create logs directory
|
||||||
|
RUN mkdir -p /app/logs && \
|
||||||
|
chown -R sveltekit:nodejs /app
|
||||||
|
|
||||||
|
# Drop privileges
|
||||||
|
USER sveltekit
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||||
|
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
|
||||||
|
|
||||||
|
# Start application
|
||||||
|
CMD ["node", "build/index.js"]
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: appointment-booking-postgres-dev
|
||||||
|
restart: unless-stopped
|
||||||
|
user: postgres
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB:-appointment_booking}
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
ports:
|
||||||
|
- "${POSTGRES_PORT:-5432}:5432"
|
||||||
|
volumes:
|
||||||
|
- postgres_data_dev:/var/lib/postgresql/data
|
||||||
|
- ./init-db:/docker-entrypoint-initdb.d:ro
|
||||||
|
networks:
|
||||||
|
- appointment-booking-dev
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-appointment_booking}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
tmpfs:
|
||||||
|
- /tmp
|
||||||
|
- /var/run/postgresql
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data_dev:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
appointment-booking-dev:
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: appointment-booking-postgres
|
||||||
|
restart: unless-stopped
|
||||||
|
user: postgres
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB_FILE: /run/secrets/postgres_db
|
||||||
|
POSTGRES_USER_FILE: /run/secrets/postgres_user
|
||||||
|
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
|
||||||
|
POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256 --auth-local=scram-sha-256"
|
||||||
|
secrets:
|
||||||
|
- postgres_db
|
||||||
|
- postgres_user
|
||||||
|
- postgres_password
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
- ./init-db:/docker-entrypoint-initdb.d:ro
|
||||||
|
networks:
|
||||||
|
- appointment-booking-internal
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U $$(cat /run/secrets/postgres_user) -d $$(cat /run/secrets/postgres_db)"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
cap_add:
|
||||||
|
- CHOWN
|
||||||
|
- DAC_OVERRIDE
|
||||||
|
- FOWNER
|
||||||
|
- SETGID
|
||||||
|
- SETUID
|
||||||
|
tmpfs:
|
||||||
|
- /tmp
|
||||||
|
- /var/run/postgresql
|
||||||
|
read_only: true
|
||||||
|
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
target: production
|
||||||
|
container_name: appointment-booking-app
|
||||||
|
restart: unless-stopped
|
||||||
|
user: "1001:1001"
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
POSTGRES_DB_FILE: /run/secrets/postgres_db
|
||||||
|
POSTGRES_USER_FILE: /run/secrets/postgres_user
|
||||||
|
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
|
||||||
|
secrets:
|
||||||
|
- postgres_db
|
||||||
|
- postgres_user
|
||||||
|
- postgres_password
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- appointment-booking-internal
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
tmpfs:
|
||||||
|
- /tmp
|
||||||
|
read_only: true
|
||||||
|
|
||||||
|
caddy:
|
||||||
|
image: caddy:2-alpine
|
||||||
|
container_name: appointment-booking-caddy
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||||
|
- caddy_data:/data
|
||||||
|
- caddy_config:/config
|
||||||
|
networks:
|
||||||
|
- appointment-booking-internal
|
||||||
|
depends_on:
|
||||||
|
app:
|
||||||
|
condition: service_healthy
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
cap_add:
|
||||||
|
- NET_BIND_SERVICE
|
||||||
|
|
||||||
|
secrets:
|
||||||
|
postgres_db:
|
||||||
|
file: ./secrets/postgres_db.txt
|
||||||
|
postgres_user:
|
||||||
|
file: ./secrets/postgres_user.txt
|
||||||
|
postgres_password:
|
||||||
|
file: ./secrets/postgres_password.txt
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
driver: local
|
||||||
|
caddy_data:
|
||||||
|
driver: local
|
||||||
|
caddy_config:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
appointment-booking-internal:
|
||||||
|
driver: bridge
|
||||||
|
internal: false
|
||||||
@@ -0,0 +1,338 @@
|
|||||||
|
# Infrastructure Setup
|
||||||
|
|
||||||
|
This document describes the complete setup for the appointment booking application infrastructure.
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
The application consists of three Docker containers:
|
||||||
|
|
||||||
|
1. **PostgreSQL Database** - Data persistence
|
||||||
|
2. **SvelteKit Application** - Web application (production only)
|
||||||
|
3. **Caddy Reverse Proxy** - HTTPS termination and routing (production only)
|
||||||
|
|
||||||
|
## Development Setup
|
||||||
|
|
||||||
|
Development runs only the PostgreSQL database with a public port for development tools.
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Docker and Docker Compose
|
||||||
|
- Node.js 24+
|
||||||
|
- Git
|
||||||
|
|
||||||
|
### Setup Steps
|
||||||
|
|
||||||
|
1. **Clone the repository**
|
||||||
|
```bash
|
||||||
|
git clone <repository-url>
|
||||||
|
cd appointment-booking-software
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Configure environment**
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
Edit `.env` and set secure values:
|
||||||
|
```
|
||||||
|
POSTGRES_DB=appointment_booking
|
||||||
|
POSTGRES_USER=postgres
|
||||||
|
POSTGRES_PASSWORD=your_secure_development_password
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Start development database**
|
||||||
|
```bash
|
||||||
|
npm run docker:dev:up
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Verify database connection**
|
||||||
|
```bash
|
||||||
|
# Check container status
|
||||||
|
docker ps
|
||||||
|
|
||||||
|
# Test connection
|
||||||
|
psql -h localhost -U postgres -d appointment_booking
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Install SvelteKit dependencies** (when SvelteKit code is added)
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **Start SvelteKit development server** (when SvelteKit code is added)
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Development Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Database management
|
||||||
|
npm run docker:dev:up # Start PostgreSQL
|
||||||
|
npm run docker:dev:down # Stop PostgreSQL
|
||||||
|
npm run docker:dev:logs # View database logs
|
||||||
|
npm run docker:dev:clean # Remove containers and volumes
|
||||||
|
|
||||||
|
# Application (when SvelteKit is implemented)
|
||||||
|
npm run dev # Start development server
|
||||||
|
npm run build # Build for production
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production Setup
|
||||||
|
|
||||||
|
Production runs all three containers with security hardening and HTTPS.
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Docker and Docker Compose
|
||||||
|
- Domain name with DNS pointing to server
|
||||||
|
- Server with public IP
|
||||||
|
|
||||||
|
### Setup Steps
|
||||||
|
|
||||||
|
1. **Configure production secrets**
|
||||||
|
|
||||||
|
Edit the secret files in the `secrets/` directory:
|
||||||
|
```bash
|
||||||
|
# Database configuration
|
||||||
|
echo "appointment_booking" > secrets/postgres_db.txt
|
||||||
|
echo "postgres" > secrets/postgres_user.txt
|
||||||
|
echo "$(openssl rand -base64 32)" > secrets/postgres_password.txt
|
||||||
|
|
||||||
|
# Set proper permissions
|
||||||
|
chmod 600 secrets/*.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Configure domain**
|
||||||
|
|
||||||
|
Edit `Caddyfile` and replace `your-domain.com` with your actual domain:
|
||||||
|
```
|
||||||
|
yourdomain.com {
|
||||||
|
# ... rest of configuration
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Build and start production stack**
|
||||||
|
```bash
|
||||||
|
# Build application image
|
||||||
|
npm run docker:prod:build
|
||||||
|
|
||||||
|
# Start all services
|
||||||
|
npm run docker:prod:up
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Verify deployment**
|
||||||
|
```bash
|
||||||
|
# Check all containers are running
|
||||||
|
docker ps
|
||||||
|
|
||||||
|
# Check application health
|
||||||
|
npm run docker:health
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
npm run docker:prod:logs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Production Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Stack management
|
||||||
|
npm run docker:prod:build # Build application image
|
||||||
|
npm run docker:prod:up # Start all services
|
||||||
|
npm run docker:prod:down # Stop all services
|
||||||
|
npm run docker:prod:logs # View all logs
|
||||||
|
npm run docker:prod:clean # Remove containers and volumes
|
||||||
|
npm run docker:health # Check container status
|
||||||
|
npm run docker:tag-and-push # Build, tag and push the app image to GHCR (Remember to change username accordingly first)
|
||||||
|
```
|
||||||
|
|
||||||
|
## SvelteKit Application Setup
|
||||||
|
|
||||||
|
When implementing the SvelteKit application, follow these steps:
|
||||||
|
|
||||||
|
### Database Connection
|
||||||
|
|
||||||
|
Create `src/lib/database.js`:
|
||||||
|
```javascript
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
|
import pg from 'pg';
|
||||||
|
|
||||||
|
function getDatabaseConfig() {
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
// Read from Docker secrets
|
||||||
|
const user = readFileSync('/run/secrets/postgres_user', 'utf8').trim();
|
||||||
|
const password = readFileSync('/run/secrets/postgres_password', 'utf8').trim();
|
||||||
|
const database = readFileSync('/run/secrets/postgres_db', 'utf8').trim();
|
||||||
|
|
||||||
|
return {
|
||||||
|
host: 'postgres',
|
||||||
|
port: 5432,
|
||||||
|
user,
|
||||||
|
password,
|
||||||
|
database
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// Development configuration
|
||||||
|
return {
|
||||||
|
host: 'localhost',
|
||||||
|
port: process.env.POSTGRES_PORT || 5432,
|
||||||
|
user: process.env.POSTGRES_USER || 'postgres',
|
||||||
|
password: process.env.POSTGRES_PASSWORD,
|
||||||
|
database: process.env.POSTGRES_DB || 'appointment_booking'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const pool = new pg.Pool(getDatabaseConfig());
|
||||||
|
```
|
||||||
|
|
||||||
|
### Health Check Endpoint
|
||||||
|
|
||||||
|
Create `src/routes/health/+server.js`:
|
||||||
|
```javascript
|
||||||
|
import { json } from '@sveltejs/kit';
|
||||||
|
import { pool } from '$lib/database.js';
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
try {
|
||||||
|
await pool.query('SELECT 1');
|
||||||
|
return json({ status: 'healthy', timestamp: new Date().toISOString() });
|
||||||
|
} catch (error) {
|
||||||
|
return json(
|
||||||
|
{ status: 'unhealthy', error: error.message },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### SvelteKit Configuration
|
||||||
|
|
||||||
|
|
||||||
|
Update `vite.config.js`:
|
||||||
|
```javascript
|
||||||
|
import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [sveltekit()],
|
||||||
|
server: {
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: 5173
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Features
|
||||||
|
|
||||||
|
### Container Security
|
||||||
|
- **Rootless containers**: All containers (sans caddy, which needs to access privileged ports) run as non-root users
|
||||||
|
- **Read-only filesystems**: Containers have read-only root filesystems where possible
|
||||||
|
- **No new privileges**: Containers cannot escalate privileges
|
||||||
|
- **Minimal capabilities**: Only necessary Linux capabilities are granted
|
||||||
|
|
||||||
|
### Network Security
|
||||||
|
- **Internal networks**: Database and app communicate via internal Docker network
|
||||||
|
- **No exposed ports**: Only Caddy exposes ports to the host
|
||||||
|
- **HTTPS only**: Caddy handles automatic HTTPS with Let's Encrypt
|
||||||
|
|
||||||
|
### Data Security
|
||||||
|
- **Docker secrets**: Sensitive data stored as Docker secrets
|
||||||
|
- **Encrypted connections**: Database connections use SSL/TLS
|
||||||
|
- **Security headers**: Comprehensive security headers via Caddy
|
||||||
|
|
||||||
|
## Monitoring and Logs
|
||||||
|
|
||||||
|
### Log Locations
|
||||||
|
- **Caddy logs**: Stored in `/data/access.log` inside Caddy container
|
||||||
|
- **Application logs**: Available via `docker logs`
|
||||||
|
- **Database logs**: Available via `docker logs`
|
||||||
|
|
||||||
|
### Health Checks
|
||||||
|
- **Application**: `GET /health` endpoint
|
||||||
|
- **Database**: Built-in PostgreSQL health check
|
||||||
|
- **Caddy**: HTTP response check
|
||||||
|
|
||||||
|
### Monitoring Commands
|
||||||
|
```bash
|
||||||
|
# View real-time logs
|
||||||
|
npm run docker:prod:logs
|
||||||
|
|
||||||
|
# Check container health
|
||||||
|
docker ps
|
||||||
|
npm run docker:health
|
||||||
|
|
||||||
|
# Individual container logs
|
||||||
|
docker logs appointment-booking-app
|
||||||
|
docker logs appointment-booking-postgres
|
||||||
|
docker logs appointment-booking-caddy
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **Container won't start**
|
||||||
|
```bash
|
||||||
|
# Check container logs
|
||||||
|
docker logs <container-name>
|
||||||
|
|
||||||
|
# Check resource usage
|
||||||
|
docker stats
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Database connection issues**
|
||||||
|
```bash
|
||||||
|
# Test database connectivity
|
||||||
|
docker exec -it appointment-booking-postgres psql -U postgres -d appointment_booking
|
||||||
|
|
||||||
|
# Check database logs
|
||||||
|
docker logs appointment-booking-postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **HTTPS certificate issues**
|
||||||
|
```bash
|
||||||
|
# Check Caddy logs
|
||||||
|
docker logs appointment-booking-caddy
|
||||||
|
|
||||||
|
# Verify domain DNS
|
||||||
|
nslookup yourdomain.com
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Application not accessible**
|
||||||
|
```bash
|
||||||
|
# Check if all containers are running
|
||||||
|
docker ps
|
||||||
|
|
||||||
|
# Test internal connectivity
|
||||||
|
docker exec -it appointment-booking-caddy wget -q --spider http://app:3000/health
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reset Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Complete reset (destroys all data)
|
||||||
|
npm run docker:prod:clean
|
||||||
|
npm run docker:dev:clean
|
||||||
|
|
||||||
|
# Rebuild and restart
|
||||||
|
npm run docker:prod:build
|
||||||
|
npm run docker:prod:up
|
||||||
|
```
|
||||||
|
|
||||||
|
## Backup and Restore
|
||||||
|
|
||||||
|
### Database Backup
|
||||||
|
```bash
|
||||||
|
# Create backup
|
||||||
|
docker exec appointment-booking-postgres pg_dump -U postgres appointment_booking > backup.sql
|
||||||
|
|
||||||
|
# Restore backup
|
||||||
|
docker exec -i appointment-booking-postgres psql -U postgres appointment_booking < backup.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
### Volume Backup
|
||||||
|
```bash
|
||||||
|
# Backup PostgreSQL data volume
|
||||||
|
docker run --rm -v appointment-booking-software_postgres_data:/data -v $(pwd):/backup alpine tar czf /backup/postgres-backup.tar.gz /data
|
||||||
|
```
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "appointment-booking-software",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "End-to-end encrypted appointment booking platform",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "echo 'Build placeholder - will be replaced with SvelteKit build'",
|
||||||
|
"docker:dev:up": "docker compose -f docker-compose.dev.yml up -d",
|
||||||
|
"docker:dev:down": "docker compose -f docker-compose.dev.yml down",
|
||||||
|
"docker:dev:logs": "docker compose -f docker-compose.dev.yml logs -f",
|
||||||
|
"docker:dev:clean": "docker compose -f docker-compose.dev.yml down -v --remove-orphans",
|
||||||
|
"docker:prod:build": "docker compose -f docker-compose.prod.yml build --no-cache",
|
||||||
|
"docker:prod:up": "docker compose -f docker-compose.prod.yml up -d",
|
||||||
|
"docker:prod:down": "docker compose -f docker-compose.prod.yml down",
|
||||||
|
"docker:prod:logs": "docker compose -f docker-compose.prod.yml logs -f",
|
||||||
|
"docker:prod:clean": "docker compose -f docker-compose.prod.yml down -v --remove-orphans",
|
||||||
|
"docker:tag-and-push": "npm run docker:prod:build && docker tag appointment-booking-software-app:latest appointment-booking-software:$npm_package_version && docker push ghcr.io/username/appointment-booking-software:$npm_package_version"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=24.0.0"
|
||||||
|
},
|
||||||
|
"license": "AGPL-3.0"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user