feat: dockerization
This commit is contained in:
17
backend/Dockerfile
Normal file
17
backend/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
||||
# Backend Dockerfile
|
||||
FROM node:20
|
||||
|
||||
# Install ffmpeg
|
||||
RUN apt-get update && apt-get install -y ffmpeg
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install dependencies
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm install
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
EXPOSE 5000
|
||||
CMD ["npm", "start"]
|
||||
@@ -19,7 +19,7 @@ const apiRouter = express.Router();
|
||||
apiRouter.get('/', channelController.getChannels);
|
||||
apiRouter.get('/current', channelController.getCurrentChannel);
|
||||
|
||||
app.use('/channels', apiRouter);
|
||||
app.use('/api/channels', apiRouter);
|
||||
|
||||
const PORT = 5000;
|
||||
const server = app.listen(PORT, () => {
|
||||
@@ -51,5 +51,4 @@ io.on('connection', socket => {
|
||||
ChannelSocketHandler(io, socket);
|
||||
|
||||
ChatSocketHandler(io, socket);
|
||||
|
||||
})
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
const { ChatMessage, User } = require('../models/ChatMessage');
|
||||
|
||||
// At the moment, this service is not used! It is only a placeholder for future development for a persistent chat.
|
||||
class ChatService {
|
||||
constructor() {
|
||||
this.messages = [];
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
const fs = require('fs');
|
||||
const path = require("path");
|
||||
|
||||
const STORAGE_PATH = process.env.STORAGE_PATH;
|
||||
|
||||
function clearStorage() {
|
||||
fs.rmSync(STORAGE_PATH, { recursive: true, force: true });
|
||||
fs.mkdirSync(STORAGE_PATH);
|
||||
|
||||
fs.readdir(STORAGE_PATH, (err, files) => {
|
||||
if (err) throw err;
|
||||
|
||||
for (const file of files) {
|
||||
fs.unlink(path.join(STORAGE_PATH, file), (err) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
44
docker-compose.yml
Normal file
44
docker-compose.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
version: "3.9"
|
||||
services:
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
# Set this to the server ip/domain, if your backend is deployed on a different server
|
||||
#VITE_BACKEND_URL: http://123.123.123.123:5000
|
||||
VITE_BACKEND_STREAMS_PATH: /streams/playlist.m3u8
|
||||
VITE_STREAM_DELAY: 20
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
volumes:
|
||||
- streams_data:/streams
|
||||
environment:
|
||||
DEFAULT_CHANNEL_URL: https://mcdn.daserste.de/daserste/de/master.m3u8
|
||||
STORAGE_PATH: /streams
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
# Nginx Reverse Proxy
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf
|
||||
- streams_data:/streams
|
||||
ports:
|
||||
- "80:80"
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
volumes:
|
||||
streams_data:
|
||||
|
||||
# Internal docker network
|
||||
networks:
|
||||
app-network:
|
||||
driver: bridge
|
||||
22
frontend/.dockerignore
Normal file
22
frontend/.dockerignore
Normal file
@@ -0,0 +1,22 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
build
|
||||
dist
|
||||
*.log
|
||||
*.swp
|
||||
*.swo
|
||||
*.DS_Store
|
||||
*.git
|
||||
*.gitignore
|
||||
*.gitattributes
|
||||
.DS_Store
|
||||
.idea
|
||||
.vscode
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.tgz
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
.env.production
|
||||
29
frontend/Dockerfile
Normal file
29
frontend/Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
||||
# Frontend Dockerfile
|
||||
FROM node:20 AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ARG VITE_BACKEND_URL
|
||||
ARG VITE_BACKEND_STREAMS_PATH
|
||||
ARG VITE_STREAM_DELAY
|
||||
|
||||
# Install dependencies
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm install
|
||||
|
||||
# Copy source code and build
|
||||
COPY . .
|
||||
|
||||
ENV VITE_BACKEND_URL=$VITE_BACKEND_URL
|
||||
ENV VITE_BACKEND_STREAMS_PATH=$VITE_BACKEND_STREAMS_PATH
|
||||
ENV VITE_STREAM_DELAY=$VITE_STREAM_DELAY
|
||||
|
||||
RUN npm run build
|
||||
|
||||
# Serve the app using a minimal HTTP server
|
||||
FROM nginx:alpine
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
@@ -10,7 +10,7 @@ const apiService = {
|
||||
* @param body - The request body (e.g. POST)
|
||||
* @returns Ein Promise with the parsed JSON response to class T
|
||||
*/
|
||||
async request<T>(path: string, method: HttpMethod = 'GET', api_url: string = API_BASE_URL, body?: unknown): Promise<T> {
|
||||
async request<T>(path: string, method: HttpMethod = 'GET', api_url: string = API_BASE_URL + '/api', body?: unknown): Promise<T> {
|
||||
try {
|
||||
const options: RequestInit = {
|
||||
method,
|
||||
|
||||
@@ -9,7 +9,8 @@ class SocketService {
|
||||
connect() {
|
||||
if (this.socket?.connected) return;
|
||||
|
||||
console.log('Connecting to WebSocket server');
|
||||
console.log('Connecting to WebSocket server: ');
|
||||
// Default Behavior: If 'VITE_BACKEND_URL' is not set, the app will use the same host name as the frontend
|
||||
this.socket = io(import.meta.env.VITE_BACKEND_URL);
|
||||
|
||||
this.socket.on('connect', () => {
|
||||
|
||||
46
nginx.conf
Normal file
46
nginx.conf
Normal file
@@ -0,0 +1,46 @@
|
||||
worker_processes auto;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
location / {
|
||||
proxy_pass http://frontend:80;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://backend:5000;
|
||||
proxy_http_version 1.1;
|
||||
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;
|
||||
}
|
||||
|
||||
location /socket.io/ {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://backend:5000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
location /streams/ {
|
||||
root /;
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'Range';
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range';
|
||||
|
||||
add_header Cache-Control no-cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user