From cc4798191516da7867cb43a741dd0a237f17467b Mon Sep 17 00:00:00 2001 From: Sergio Nicolas Lavaise Date: Fri, 24 Apr 2026 13:17:31 -0300 Subject: [PATCH] Add Docker with MariaDB support - Dockerfile now includes MariaDB server - Add docker-entrypoint.sh to initialize DB, create user, and set permissions - docker-compose.yml with configurable environment variables - Nginx config proxies API to backend --- Dockerfile | 43 +++++++++++++++++++++++++----------- docker-compose.yml | 13 ++++++----- docker-entrypoint.sh | 52 ++++++++++++++++++++++++++++++++++++++++++++ server/db-mariadb.js | 7 +++--- 4 files changed, 93 insertions(+), 22 deletions(-) create mode 100644 docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 97c5ec8..a6fec4d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,31 +9,48 @@ RUN npm ci COPY . . RUN npm run build -# Stage 2: Backend + Nginx +# Stage 2: Full stack with MariaDB FROM node:20-alpine WORKDIR /app -COPY --from=builder /app/dist dist +# Install MariaDB and nginx +RUN apk add --no-cache mariadb mariadb-client mariadb-server-utils nginx + +# Initialize MariaDB data directory +RUN mkdir -p /run/mysqld && \ + chown -R mysql:mysql /run/mysqld && \ + chown -R mysql:mysql /var/lib/mysql + +# Copy MariaDB config +RUN sed -i 's/\[mysqld\]/[mysqld]\ncharacter-set-server=utf8mb4\ncollation-server=utf8mb4_unicode_ci/' /etc/my.cnf.d/mariadb.cnf || true + +# Copy built frontend +COPY --from=builder /app/dist /usr/share/nginx/html + +# Copy server files COPY server/package*.json server/ RUN cd server && npm ci -COPY server/server.js server/ -COPY server/db.js server/ - -# Install nginx -RUN apk add --no-cache nginx && mkdir -p /usr/share/nginx/html +COPY server/ server/ # Copy nginx config COPY nginx.conf /etc/nginx/http.d/default.conf -# Create nginx directories +# Create directories RUN mkdir -p /run/nginx -# Copy built frontend to nginx html directory -RUN cp -r dist/* /usr/share/nginx/html/ +# Copy entrypoint script +COPY docker-entrypoint.sh /docker-entrypoint.sh +RUN chmod +x /docker-entrypoint.sh -EXPOSE 80 4000 +EXPOSE 80 4000 3306 -# Start both nginx and the backend -CMD nginx && node server/server.js \ No newline at end of file +ENV DB_HOST=localhost +ENV DB_PORT=3306 +ENV DB_USER=root +ENV DB_PASSWORD= +ENV DB_NAME=hospital + +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["nginx.sh", "node", "server/api-mariadb.js"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index f3534ef..155b1ed 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,9 +6,10 @@ services: ports: - "8077:80" - "4000:4000" - volumes: - - hospital-data:/app - restart: unless-stopped - -volumes: - hospital-data: + environment: + - DB_HOST=localhost + - DB_PORT=3306 + - DB_USER=hospital + - DB_PASSWORD=hospital123 + - DB_NAME=hospital + restart: unless-stopped \ No newline at end of file diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..8297f02 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,52 @@ +#!/bin/bash +set -e + +echo "=== Starting MariaDB ===" +# Start MariaDB in background +mysqld --user=mysql & +MYSQL_PID=$! + +# Wait for MariaDB to be ready +echo "Waiting for MariaDB to be ready..." +for i in {1..30}; do + if mysqladmin ping -h localhost --silent 2>/dev/null; then + echo "MariaDB is ready!" + break + fi + sleep 1 +done + +# Create database if it doesn't exist +echo "Creating database if not exists..." +mysql -h localhost -u root -e "CREATE DATABASE IF NOT EXISTS \`${DB_NAME:-hospital}\`;" + +# Create user and grant permissions if DB_PASSWORD is set +if [ -n "$DB_PASSWORD" ] && [ "$DB_PASSWORD" != "" ]; then + echo "Creating user and setting permissions..." + + # Check if user exists + USER_EXISTS=$(mysql -h localhost -u root -N -e "SELECT COUNT(*) FROM mysql.user WHERE User='${DB_USER:-root}' AND Host='%';") + + if [ "$USER_EXISTS" = "0" ]; then + mysql -h localhost -u root -e "CREATE USER '${DB_USER:-root}'@'%' IDENTIFIED BY '${DB_PASSWORD}';" + mysql -h localhost -u root -e "GRANT ALL PRIVILEGES ON ${DB_NAME:-hospital}.* TO '${DB_USER:-root}'@'%';" + mysql -h localhost -u root -e "FLUSH PRIVILEGES;" + else + echo "User already exists, updating password..." + mysql -h localhost -u root -e "ALTER USER '${DB_USER:-root}'@'%' IDENTIFIED BY '${DB_PASSWORD}';" + mysql -h localhost -u root -e "GRANT ALL PRIVILEGES ON ${DB_NAME:-hospital}.* TO '${DB_USER:-root}'@'%';" + mysql -h localhost -u root -e "FLUSH PRIVILEGES;" + fi +fi + +echo "=== MariaDB initialization complete ===" + +# If called with nginx.sh, start nginx +if [ "$1" = "nginx.sh" ]; then + echo "Starting nginx..." + nginx + exec "$@" +fi + +# Otherwise wait for the process +wait \ No newline at end of file diff --git a/server/db-mariadb.js b/server/db-mariadb.js index 813baeb..3e6237d 100644 --- a/server/db-mariadb.js +++ b/server/db-mariadb.js @@ -1,5 +1,6 @@ import * as mariadb from 'mariadb'; -import * as bcrypt from 'bcryptjs'; +import bcrypt from 'bcryptjs'; +const { compareSync, hashSync } = bcrypt; // UUID generator export function generateUUID() { @@ -279,11 +280,11 @@ export async function deleteUsuario(id) { export async function verifyPassword(dni, password) { const row = await queryOne('SELECT passwordHash FROM usuarios WHERE dni = ?', [dni]); if (!row) return false; - return bcrypt.compareSync(password, row.passwordHash); + return compareSync(password, row.passwordHash); } export function hashPassword(password) { - return bcrypt.hashSync(password, 10); + return hashSync(password, 10); } // ========== PACIENTES ==========