From 529a590cce2fb2675b99ca23d52d3f46e4452a8d Mon Sep 17 00:00:00 2001 From: astria Date: Wed, 3 Sep 2025 19:53:05 +0200 Subject: [PATCH] Fix docker issues --- backend/Dockerfile | 18 +++------- backend/logs/access.log | 3 ++ docker-compose.yaml | 33 +++++++---------- frontend/Dockerfile | 14 ++++++-- frontend/default.conf | 68 +++++++++++++++++++++++++++++++++++ frontend/nginx-selfsigned.crt | 23 ++++++++++++ frontend/nginx-selfsigned.key | 28 +++++++++++++++ frontend/package.json | 3 +- 8 files changed, 152 insertions(+), 38 deletions(-) create mode 100644 frontend/default.conf create mode 100644 frontend/nginx-selfsigned.crt create mode 100644 frontend/nginx-selfsigned.key diff --git a/backend/Dockerfile b/backend/Dockerfile index 1470f39..ea47ba6 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,22 +1,14 @@ -FROM node:20-alpine -# Set the working directory +FROM node:22-alpine + WORKDIR /app -# Copy package.json and package-lock.json + COPY package*.json ./ -# Install dependencies RUN npm install --production -# Copy the rest of the application code -COPY . . -# Expose the port the app runs on -EXPOSE 8000 -# Install netcat for health checks -RUN apk add --no-cache netcat-openbsd +COPY . . -# Install the cli tools -RUN chmod +x ./freetube.sh -RUN cp ./freetube.sh /usr/local/bin/freetube +EXPOSE 8000 # Start the application CMD ["npm", "start"] \ No newline at end of file diff --git a/backend/logs/access.log b/backend/logs/access.log index fd02723..4264c87 100644 --- a/backend/logs/access.log +++ b/backend/logs/access.log @@ -11484,3 +11484,6 @@ [2025-09-03 17:34:32.741] [undefined] GET(/see-later): 'See Later' playlist retrieved for user with id 1 with status 200 [2025-09-03 17:34:41.091] [undefined] GET(/see-later): 'See Later' playlist retrieved for user with id 1 with status 200 [2025-09-03 17:35:57.790] [undefined] GET(/see-later): 'See Later' playlist retrieved for user with id 1 with status 200 +[2025-09-03 17:44:19.296] [undefined] GET(/see-later): 'See Later' playlist retrieved for user with id 1 with status 200 +[2025-09-03 17:44:20.911] [undefined] GET(/see-later): 'See Later' playlist retrieved for user with id 1 with status 200 +[2025-09-03 17:50:33.774] [undefined] GET(/see-later): 'See Later' playlist retrieved for user with id 1 with status 200 diff --git a/docker-compose.yaml b/docker-compose.yaml index 9daba49..d75b89e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -24,7 +24,8 @@ services: - ./backend/logs:/var/log/freetube - ./backend:/app depends_on: - - db + db: + condition: service_healthy db: image: postgres:latest @@ -36,34 +37,24 @@ services: POSTGRES_DB: ${POSTGRES_DB} volumes: - db_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s frontend: - image: nginx:latest + build: + context: ./frontend + dockerfile: Dockerfile + container_name: resit_frontend ports: - "80:80" - "443:443" - volumes: - - ./frontend/dist:/usr/share/nginx/html - - ./nginx/default.conf:/etc/nginx/conf.d/default.conf - - ./nginx/nginx-selfsigned.crt:/etc/nginx/ssl/nginx-selfsigned.crt - - ./nginx/nginx-selfsigned.key:/etc/nginx/ssl/nginx-selfsigned.key depends_on: - resit_backend - - mailpit: - image: axllent/mailpit:latest - ports: - - "8025:8025" # Web UI - - "1025:1025" # SMTP - volumes: - - mailpit-data:/data - environment: - # set where to store the database - MP_DATABASE: /data/mailpit.db - restart: unless-stopped volumes: db_data: - driver: local - mailpit-data: driver: local \ No newline at end of file diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 5b114a4..e0a2a74 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,9 +1,17 @@ -FROM node:21-alpine3.20 +# Build stage +FROM node:22-alpine3.20 as build-stage WORKDIR /app COPY package*.json ./ RUN npm install COPY . . -EXPOSE 5173 -CMD ["npm", "run", "dev"] +RUN npm run build +# Production stage +FROM nginx:alpine +RUN mkdir -p /etc/nginx/ssl +COPY --from=build-stage /app/dist /usr/share/nginx/html +COPY default.conf /etc/nginx/conf.d/default.conf +COPY nginx-selfsigned.crt nginx-selfsigned.key /etc/nginx/ssl/ +EXPOSE 80 443 +CMD ["nginx", "-g", "daemon off;"] diff --git a/frontend/default.conf b/frontend/default.conf new file mode 100644 index 0000000..314181e --- /dev/null +++ b/frontend/default.conf @@ -0,0 +1,68 @@ +server { + server_name localhost; + listen 80; + + return 301 https://$host$request_uri; +} + +server { + server_name localhost; + listen 443 ssl; + + root /usr/share/nginx/html; + index index.html index.htm; + + # Allow large file uploads for videos (up to 500MB) + client_max_body_size 500M; + + ssl_certificate /etc/nginx/ssl/nginx-selfsigned.crt; + ssl_certificate_key /etc/nginx/ssl/nginx-selfsigned.key; + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + + # API routes - proxy to backend (MUST come before static file rules) + location /api/ { + # Handle preflight OPTIONS requests + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' '$http_origin' always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always; + add_header 'Access-Control-Allow-Credentials' 'true' always; + add_header 'Access-Control-Max-Age' 1728000 always; + add_header 'Content-Type' 'text/plain; charset=utf-8' always; + add_header 'Content-Length' 0 always; + return 204; + } + + proxy_pass http://resit_backend:8000; + 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_set_header Origin $http_origin; + proxy_buffering off; + + # CORS headers for actual requests + add_header 'Access-Control-Allow-Origin' '$http_origin' always; + add_header 'Access-Control-Allow-Credentials' 'true' always; + + # Also set timeout for large uploads + proxy_read_timeout 300s; + proxy_send_timeout 300s; + } + + # Static assets - NO CACHING for development + location ~* ^/(?!api/).*\.(js|css|png|jpg|jpeg|gif|ico|svg)$ { + add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"; + add_header Pragma "no-cache"; + add_header Expires "0"; + try_files $uri =404; + } + + # Handle React Router - all other routes should serve index.html + location / { + add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"; + try_files $uri $uri/ /index.html; + } +} \ No newline at end of file diff --git a/frontend/nginx-selfsigned.crt b/frontend/nginx-selfsigned.crt new file mode 100644 index 0000000..29fac8a --- /dev/null +++ b/frontend/nginx-selfsigned.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID5zCCAs+gAwIBAgIUXzNzqa/12lyIcoxXf+v371J3fWkwDQYJKoZIhvcNAQEL +BQAwgYIxCzAJBgNVBAYTAkZSMREwDwYDVQQIDAhOb3JtYW5keTENMAsGA1UEBwwE +Q2FlbjERMA8GA1UECgwIRnJhbWluZm8xFTATBgNVBAMMDFNhY2hhIEdVRVJJTjEn +MCUGCSqGSIb3DQEJARYYc2FjaGEuZ3VlcmluQHN1cGluZm8uY29tMB4XDTI1MDcy +MTEzMzgwMVoXDTI2MDcyMTEzMzgwMVowgYIxCzAJBgNVBAYTAkZSMREwDwYDVQQI +DAhOb3JtYW5keTENMAsGA1UEBwwEQ2FlbjERMA8GA1UECgwIRnJhbWluZm8xFTAT +BgNVBAMMDFNhY2hhIEdVRVJJTjEnMCUGCSqGSIb3DQEJARYYc2FjaGEuZ3Vlcmlu +QHN1cGluZm8uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvLg7 +nR0UqRZ7UadhI8jrUjRMV1SZj+ljxEnV6tDOVMsvafsym1MhDZHb+cyv8769yqPv +CKtIOQKhMH0PkSqau8szNlF1Tg/1UzT+Mkd4zvLvGE5+aW/oDMg7E2LMJZuCyO4X +9SzWDVA5+b1QFIw6vvb3mCkUOtVDkOFreBBwryZKcWJ0b8o1hT60oB2wr18P14j0 +0C2/TmHMtim0o4r3gKGvpatqt1fXJo0UlYOwTvfMrYhu2VHqsQ2qP7ocazXEWt5u +Alf1vNPkAenF0ZV/2UiaL41Q8GMoV1enDP7k7/qfgXvta/hOeYnLtmv5Qpi4XiWz +xKjSukTUD2sRtSX+YQIDAQABo1MwUTAdBgNVHQ4EFgQUVj9KtmjLFy4xWzkNI9Kq +NAxNsfUwHwYDVR0jBBgwFoAUVj9KtmjLFy4xWzkNI9KqNAxNsfUwDwYDVR0TAQH/ +BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAGpUPMoF/ASIqOOfX5anDtaPvnslj +DuEVbU7Uoyc4EuSD343DPV7iMUKoFvVLPxJJqMLhSo3aEGJyqOF6q3fvq/vX2VE7 +9MhwS1t2DBGb5foWRosnT1EuqFU1/S0RJ/Y+GNcoY1PrUES4+r7zqqJJjwKOzneV +ktUVCdKl0C1gtw6W4Ajxse3fm9DNLxnZZXbyNqn+KbI8QdO0xSEl+gyiycvPu/NT ++EesdlFoYjO7gdA8dXkmu+Z7R61MYhE9Zvyop5KVMqgU8/Ym04UUWjWQYWWLMyuu +bxngE4XNEI5fhg+0e/I25xJJ9wVV/ZNAF4+XOylHz/CmU8V/SPKuGXBGHg== +-----END CERTIFICATE----- diff --git a/frontend/nginx-selfsigned.key b/frontend/nginx-selfsigned.key new file mode 100644 index 0000000..0ac5345 --- /dev/null +++ b/frontend/nginx-selfsigned.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC8uDudHRSpFntR +p2EjyOtSNExXVJmP6WPESdXq0M5Uyy9p+zKbUyENkdv5zK/zvr3Ko+8Iq0g5AqEw +fQ+RKpq7yzM2UXVOD/VTNP4yR3jO8u8YTn5pb+gMyDsTYswlm4LI7hf1LNYNUDn5 +vVAUjDq+9veYKRQ61UOQ4Wt4EHCvJkpxYnRvyjWFPrSgHbCvXw/XiPTQLb9OYcy2 +KbSjiveAoa+lq2q3V9cmjRSVg7BO98ytiG7ZUeqxDao/uhxrNcRa3m4CV/W80+QB +6cXRlX/ZSJovjVDwYyhXV6cM/uTv+p+Be+1r+E55icu2a/lCmLheJbPEqNK6RNQP +axG1Jf5hAgMBAAECggEAAj+hmDRx6jafAAf67sqi3ZgEGEmBkXNeeLGBTPc/qhxd +ip6krTELnz8TE26RG5LYXzslasUNrn42nIImvBT5ZkcjcosKpWfEqQEAjc1PQovC +9eyKnKfw4TpUvvmiveT4T98vCYEOOqHE0/WTdlOoaBY/f+sZKQYu+1NMtAjFcg2r +vVqwsZb5vGyh7CKmIHZnz3UP8P+7G5digiNRne18pGnE2oTnSoQ3/QIqUWBs69DS +k5ew+CSyTLiUFFnMnE4adwyg6wAud5fBlzowF6UF2agToX7pxEaGxGvpBGG034kk +1UXaB/d5YwcsBeH+x5cNMLKZy4zqjoxEEW31Q466NQKBgQDtKk1R/slpTpRqvtBT +NC7InvjcCBXkXttylQHJRN9glqhmflEOe8iMW1/qRwBPlQgK1wq/sXySanVv2+gO +JGq8XNRLbHyG3YRyshdnJHP1HoWQE0uedD/rfqgkNaW5S1IvHrD7Q7tOvCrF+KbS +612pmIgNVzn+inafDXPhMZc4pQKBgQDLtQGAu2eK58ewndyL8+7+VHZSTEtKpt+h +G/U/ccv+6NGqdxI5YUkrJ7k6vV81VeRMvmN9uUS/i8znORFQmm6noRVkhXytwW5B +HXq2co4WRvv9b/XqcqS0GSYVPJ1u4YNH6lvtDZ4UWPyBzYl700GdHrGa+erT44yL +tnibHx9GDQKBgFW1J+Qt85O+9hvtgVPQU+fkq4K42VCCh0PNXavi2+cICyufEqPt +T/iJPQxpRE9+SD3CoPvNpHs1ReN60U3rEzenRIFNX2NNwoPAoHyBy/YVZac/keBd +mov8Zb9QM+fWtIiaytLDE3nMvph017T5ogucN+66SxcV6vBn6CzFwySRAoGAcUf2 +Tv1ohkGAtgIDrLx5cmvL5NZSpHAKOpDOoHqLA/W66v4OX2RviRUtF7JJ6OIb9GWH +9Fl8Fr0KtKbyrw1CbevRdrYY8JN52bIoFJ+9zjupVHXXnookd5boq7SqpAe6ttpo +RnplJ1GZEiIXy4lemp6AC/vhD/YhqWxOw4zaGl0CgYBslhqVt5F0EHf94p7NrCuY +hNHKHaNaULYP0VXKefQamt/ssDuktqb6DNSIvx2rbbB5+33nTlLTya67gimY1lKt +WeNB33/yBkCjfSP/J5UDD9mE/oPLt3vAOkOUgMCfp2IpC2Wez1QGqLHS260zpotP +VpgalHuSWtn8D4nO2pk1hg== +-----END PRIVATE KEY----- diff --git a/frontend/package.json b/frontend/package.json index adc5c94..2af0127 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,7 +5,8 @@ "type": "module", "scripts": { "dev": "vite --host", - "build": "vite build --watch", + "build": "vite build", + "build:watch": "vite build --watch", "lint": "eslint .", "preview": "vite preview" },