Browse Source

Fix docker issues

pull/11/head
astria 3 months ago
parent
commit
529a590cce
  1. 18
      backend/Dockerfile
  2. 3
      backend/logs/access.log
  3. 33
      docker-compose.yaml
  4. 14
      frontend/Dockerfile
  5. 68
      frontend/default.conf
  6. 23
      frontend/nginx-selfsigned.crt
  7. 28
      frontend/nginx-selfsigned.key
  8. 3
      frontend/package.json

18
backend/Dockerfile

@ -1,22 +1,14 @@
FROM node:20-alpine FROM node:22-alpine
# Set the working directory
WORKDIR /app WORKDIR /app
# Copy package.json and package-lock.json
COPY package*.json ./ COPY package*.json ./
# Install dependencies
RUN npm install --production 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 COPY . .
RUN apk add --no-cache netcat-openbsd
# Install the cli tools EXPOSE 8000
RUN chmod +x ./freetube.sh
RUN cp ./freetube.sh /usr/local/bin/freetube
# Start the application # Start the application
CMD ["npm", "start"] CMD ["npm", "start"]

3
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: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: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: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

33
docker-compose.yaml

@ -24,7 +24,8 @@ services:
- ./backend/logs:/var/log/freetube - ./backend/logs:/var/log/freetube
- ./backend:/app - ./backend:/app
depends_on: depends_on:
- db db:
condition: service_healthy
db: db:
image: postgres:latest image: postgres:latest
@ -36,34 +37,24 @@ services:
POSTGRES_DB: ${POSTGRES_DB} POSTGRES_DB: ${POSTGRES_DB}
volumes: volumes:
- db_data:/var/lib/postgresql/data - 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: frontend:
image: nginx:latest build:
context: ./frontend
dockerfile: Dockerfile
container_name: resit_frontend
ports: ports:
- "80:80" - "80:80"
- "443:443" - "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: depends_on:
- resit_backend - 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: volumes:
db_data: db_data:
driver: local driver: local
mailpit-data:
driver: local

14
frontend/Dockerfile

@ -1,9 +1,17 @@
FROM node:21-alpine3.20 # Build stage
FROM node:22-alpine3.20 as build-stage
WORKDIR /app WORKDIR /app
COPY package*.json ./ COPY package*.json ./
RUN npm install RUN npm install
COPY . . COPY . .
EXPOSE 5173 RUN npm run build
CMD ["npm", "run", "dev"]
# 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;"]

68
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;
}
}

23
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-----

28
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-----

3
frontend/package.json

@ -5,7 +5,8 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite --host", "dev": "vite --host",
"build": "vite build --watch", "build": "vite build",
"build:watch": "vite build --watch",
"lint": "eslint .", "lint": "eslint .",
"preview": "vite preview" "preview": "vite preview"
}, },

Loading…
Cancel
Save