Skip to main content

Installation Guide

This guide covers the complete installation process for OdontologyApp, including system requirements, database setup, environment configuration, and deployment options.

System Requirements

Minimum Requirements

Operating System

  • Linux (Ubuntu 20.04+, Debian 11+)
  • macOS 11+ (Big Sur or later)
  • Windows 10/11 with WSL2

Runtime

  • Node.js 18.x or higher
  • npm 9.x+ / pnpm 8.x+ / bun 1.x+

Database

  • MySQL 8.0+ or MariaDB 10.6+
  • Minimum 1GB storage for database

Memory & CPU

  • 2GB RAM minimum (4GB recommended)
  • 2 CPU cores minimum
  • CPU: 4+ cores
  • RAM: 8GB+
  • Storage: 50GB+ SSD
  • Database: MySQL 8.0+ on dedicated server
  • Node.js: Latest LTS version (20.x)
  • Reverse Proxy: Nginx or Apache for production
  • SSL Certificate: Let’s Encrypt or commercial certificate

Installation Steps

Step 1: Install Node.js

OdontologyApp requires Node.js 18 or higher.
# Install Node.js 20.x LTS
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs

# Verify installation
node --version  # Should show v20.x.x
npm --version   # Should show 10.x.x

Step 2: Install MySQL

1

Install MySQL Server

# Install MySQL Server 8.0
sudo apt update
sudo apt install mysql-server

# Start MySQL service
sudo systemctl start mysql
sudo systemctl enable mysql

# Secure MySQL installation
sudo mysql_secure_installation
2

Create Database User

Login to MySQL and create a dedicated user:
# Login as root
sudo mysql -u root -p

# Create database user
CREATE USER 'odontology_user'@'localhost' IDENTIFIED BY 'your_secure_password';

# Grant privileges (database will be created in next step)
GRANT ALL PRIVILEGES ON ontology_db.* TO 'odontology_user'@'localhost';

# Flush privileges
FLUSH PRIVILEGES;

# Exit MySQL
EXIT;
Replace your_secure_password with a strong password. Save these credentials - you’ll need them for the environment configuration.

Step 3: Import Database Schema

1

Download or locate database.sql

The database schema file is located at workspace/source/database.sql in the OdontologyApp project.
2

Import the schema and seed data

# Import database schema
mysql -u odontology_user -p < database.sql

# Verify database was created
mysql -u odontology_user -p -e "SHOW DATABASES;"
# Should show 'ontology_db' in the list

# Verify tables were created
mysql -u odontology_user -p ontology_db -e "SHOW TABLES;"
You should see 14 tables:
+-------------------------+
| Tables_in_ontology_db   |
+-------------------------+
| appointments            |
| branches                |
| doctor_branches         |
| doctors                 |
| indications             |
| logs                    |
| medical_records         |
| odontograms             |
| patient_files           |
| patients                |
| permissions             |
| user_permissions        |
| users                   |
+-------------------------+
3

Verify seed data

Check that the default users were created:
mysql -u odontology_user -p ontology_db -e "SELECT id, name, username, role FROM users;"
Expected output:
+----+------------------+------------+-----------+
| id | name             | username   | role      |
+----+------------------+------------+-----------+
|  1 | Andrea Rojas     | admin      | admin     |
|  2 | Dr. Carlos Soto  | doctor     | doctor    |
|  3 | Lucía Mendoza    | secretaria | secretary |
+----+------------------+------------+-----------+

Step 4: Clone and Setup Project

1

Clone the repository

# Navigate to your project directory
cd /var/www  # or your preferred location

# Clone the repository (replace with your actual repository)
git clone https://github.com/your-org/odontologyapp.git
cd odontologyapp
2

Install dependencies

npm install
This will install all required dependencies:
  • SvelteKit and Svelte framework
  • MySQL2 database driver
  • bcryptjs for password hashing
  • SvelteKit Superforms and Zod for form validation
  • SweetAlert2 for notifications

Step 5: Configure Environment Variables

OdontologyApp uses environment variables for database configuration and secrets.
1

Create .env file

Create a .env file in the project root:
touch .env
2

Add database configuration

Open .env and add the following configuration:
# Database Configuration
DB_HOST=localhost
DB_USER=odontology_user
DB_PASS=your_secure_password
DB_NAME=ontology_db

# Application Settings
NODE_ENV=development

# Optional: Custom port (default is 5173 in dev)
PORT=5173
Security Note: Never commit the .env file to version control. Add it to .gitignore:
echo ".env" >> .gitignore
3

Configure database connection

The database connection is configured in src/lib/server/db.js:
// src/lib/server/db.js
import mysql from "mysql2/promise";
import { DB_HOST, DB_USER, DB_PASS, DB_NAME } from "$env/static/private";

export const pool = mysql.createPool({
  host: DB_HOST,           // localhost
  user: DB_USER,           // odontology_user
  password: DB_PASS,       // your password
  database: DB_NAME,       // ontology_db
  waitForConnections: true,
  connectionLimit: 10,     // Max 10 concurrent connections
  queueLimit: 0,          // Unlimited queue
});
The connection pool automatically manages database connections, creating up to 10 concurrent connections for optimal performance.

Step 6: Run Development Server

1

Start the development server

npm run dev
The server will start on http://localhost:5173 with hot module replacement enabled.Expected output:
  VITE v7.3.1  ready in 1234 ms

  Local:   http://localhost:5173/
  Network: http://192.168.1.100:5173/
  press h to show help
2

Access the application

Open your browser and navigate to:
http://localhost:5173/login
You should see the OdontologyApp login screen.
3

Login with default credentials

Test the installation by logging in:
Username: admin
Password: admin123
If successful, you’ll be redirected to the dashboard.
The development server runs with --host flag enabled, allowing access from other devices on your network. This is useful for testing on mobile devices.

Building for Production

Step 7: Build Production Bundle

1

Set production environment

Update .env for production:
NODE_ENV=production
DB_HOST=your-production-db-host
DB_USER=production_user
DB_PASS=strong_production_password
DB_NAME=ontology_db
2

Build the application

npm run build
This command:
  1. Runs Vite build process
  2. Compiles Svelte components
  3. Optimizes assets and bundles
  4. Generates production-ready output in build/ directory
Expected output:
vite v7.3.1 building for production...
 1234 modules transformed.
.svelte-kit/output/client/_app/version.json                  0.05 kB gzip: 0.05 kB
.svelte-kit/output/client/_app/immutable/assets/...         x.xx kB gzip: x.xx kB
...
 built in 12.34s
3

Preview production build (optional)

Test the production build locally:
npm run preview
This starts a local server serving the production build.

Deployment Options

Option 1: Node.js Process Manager (PM2)

Recommended for traditional VPS/dedicated server hosting.
1

Install PM2

npm install -g pm2
2

Create PM2 ecosystem file

Create ecosystem.config.js in project root:
module.exports = {
  apps: [{
    name: 'odontologyapp',
    script: 'build/index.js',
    instances: 'max',
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    }
  }]
}
3

Start the application

pm2 start ecosystem.config.js
pm2 save
pm2 startup  # Configure auto-start on system boot
4

Monitor the application

pm2 status      # View status
pm2 logs        # View logs
pm2 monit       # Real-time monitoring
pm2 restart odontologyapp  # Restart application

Option 2: Docker Deployment

1

Create Dockerfile

Create Dockerfile in project root:
FROM node:20-alpine

WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production

# Copy application files
COPY . .

# Build application
RUN npm run build

# Expose port
EXPOSE 3000

# Set environment
ENV NODE_ENV=production
ENV PORT=3000

# Start application
CMD ["node", "build/index.js"]
2

Create docker-compose.yml

version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - DB_USER=odontology_user
      - DB_PASS=secure_password
      - DB_NAME=ontology_db
    depends_on:
      - db
    restart: unless-stopped
  
  db:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=root_password
      - MYSQL_DATABASE=ontology_db
      - MYSQL_USER=odontology_user
      - MYSQL_PASSWORD=secure_password
    volumes:
      - mysql_data:/var/lib/mysql
      - ./database.sql:/docker-entrypoint-initdb.d/database.sql
    restart: unless-stopped

volumes:
  mysql_data:
3

Deploy with Docker Compose

# Build and start containers
docker-compose up -d

# View logs
docker-compose logs -f

# Stop containers
docker-compose down

Option 3: Nginx Reverse Proxy

Recommended for production to handle SSL and static assets.
1

Install Nginx

sudo apt install nginx
2

Configure Nginx

Create /etc/nginx/sites-available/odontologyapp:
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    
    # Redirect HTTP to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com www.yourdomain.com;
    
    # SSL certificates (use Let's Encrypt)
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    
    # Proxy to Node.js application
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
    
    # Static assets caching
    location /_app/immutable {
        proxy_pass http://localhost:3000;
        proxy_cache_valid 200 1y;
        add_header Cache-Control "public, immutable";
    }
}
3

Enable site and restart Nginx

sudo ln -s /etc/nginx/sites-available/odontologyapp /etc/nginx/sites-enabled/
sudo nginx -t  # Test configuration
sudo systemctl restart nginx
4

Install SSL certificate with Let's Encrypt

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Environment Variables Reference

Complete list of environment variables used by OdontologyApp:
# Database Configuration (Required)
DB_HOST=localhost           # MySQL host
DB_USER=odontology_user     # Database user
DB_PASS=secure_password     # Database password
DB_NAME=ontology_db         # Database name

# Application Settings
NODE_ENV=production         # development | production
PORT=3000                   # Server port (default: 5173 dev, 3000 prod)

# Optional: Future features
# EMAIL_HOST=smtp.gmail.com
# EMAIL_PORT=587
# [email protected]
# EMAIL_PASS=your-app-password
# WHATSAPP_API_KEY=your-whatsapp-api-key

Database Configuration

Connection Pool Settings

The MySQL connection pool in src/lib/server/db.js uses these settings:
{
  host: DB_HOST,              // Database host
  user: DB_USER,              // Database user
  password: DB_PASS,          // Database password
  database: DB_NAME,          // Database name
  waitForConnections: true,   // Queue requests when limit reached
  connectionLimit: 10,        // Maximum concurrent connections
  queueLimit: 0              // Unlimited queue size
}
Performance Tip: For high-traffic production environments, consider increasing connectionLimit to 20-50 depending on your database server capacity.

Stored Procedures

The database uses stored procedures for critical operations:
  • sp_authenticate_user(username) - User authentication
  • sp_create_log(user_id, action, module, description, ip) - Audit logging
These procedures are defined in database.sql and provide:
  • Better performance through compiled execution plans
  • Enhanced security by limiting direct table access
  • Consistent business logic enforcement

Security Considerations

Production Security Checklist:
  • Change all default passwords (admin, doctor, secretary)
  • Use strong database passwords (16+ characters)
  • Enable SSL/TLS for MySQL connections in production
  • Set secure: true for session cookies in production
  • Configure CORS properly in svelte.config.js
  • Enable firewall rules to restrict database access
  • Regular database backups (automated daily)
  • Keep Node.js and dependencies updated
  • Use environment variables for all secrets
  • Enable CSRF protection (already configured in svelte.config.js)

Session Security

Session cookies are configured in src/routes/api/auth/login/+server.js:
cookies.set('session', JSON.stringify(sessionData), {
  path: '/',
  httpOnly: true,        // Prevents JavaScript access
  sameSite: 'lax',       // CSRF protection
  secure: false,         // Set to true in production with HTTPS
  maxAge: 60 * 60 * 24   // 24 hours
});
Important: Set secure: true in production when using HTTPS to prevent session hijacking.

Troubleshooting

Database Connection Errors

Error: Error: connect ECONNREFUSED 127.0.0.1:3306 Solution:
# Check if MySQL is running
sudo systemctl status mysql

# Start MySQL if stopped
sudo systemctl start mysql

# Verify MySQL is listening on correct port
sudo netstat -tlnp | grep 3306

Permission Denied Errors

Error: Access denied for user 'odontology_user'@'localhost' Solution:
# Login as root
sudo mysql -u root -p

# Grant privileges
GRANT ALL PRIVILEGES ON ontology_db.* TO 'odontology_user'@'localhost';
FLUSH PRIVILEGES;

Build Errors

Error: Cannot find module '$env/static/private' Solution:
# Ensure .env file exists
# Run SvelteKit sync
npm run prepare

Port Already in Use

Error: Port 5173 is already in use Solution:
# Find process using the port
lsof -i :5173

# Kill the process
kill -9 <PID>

# Or use a different port
PORT=5174 npm run dev

Performance Optimization

Database Indexing

Ensure proper indexes exist for frequently queried fields:
-- Check existing indexes
SHOW INDEX FROM patients;
SHOW INDEX FROM appointments;

-- Add indexes if needed
CREATE INDEX idx_patient_cedula ON patients(cedula);
CREATE INDEX idx_appointment_date ON appointments(appointment_date, appointment_time);
CREATE INDEX idx_user_username ON users(username);

Caching Strategy

  • Static assets are automatically cached by Vite
  • API responses can be cached using SvelteKit’s setHeaders
  • Consider Redis for session storage in high-traffic scenarios

Production Build Optimization

The build process automatically:
  • Minifies JavaScript and CSS
  • Optimizes images and assets
  • Tree-shakes unused code
  • Generates source maps (disable in production with vite.config.js)

Backup Strategy

Automated Database Backups

Create a backup script:
#!/bin/bash
# backup-db.sh

BACKUP_DIR="/var/backups/odontologyapp"
DATE=$(date +%Y%m%d_%H%M%S)
FILENAME="ontology_db_$DATE.sql.gz"

mkdir -p $BACKUP_DIR

# Create backup
mysqldump -u odontology_user -p'password' ontology_db | gzip > "$BACKUP_DIR/$FILENAME"

# Keep only last 30 days of backups
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete

echo "Backup completed: $FILENAME"
Schedule with cron:
# Run daily at 2 AM
0 2 * * * /path/to/backup-db.sh

Next Steps

Quickstart Guide

Learn how to use OdontologyApp with the quickstart guide

API Reference

Explore the complete API documentation

User Management

Learn how to manage users and permissions

Configuration

Advanced configuration options and customization

Build docs developers (and LLMs) love