added docker setup

This commit is contained in:
Jan Felix Wiebe 2025-07-11 14:33:20 +02:00
parent 57ae9c3320
commit be5ce63add
12 changed files with 509 additions and 20 deletions

12
frontend/.dockerignore Normal file
View file

@ -0,0 +1,12 @@
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.nyc_output
coverage
.DS_Store
.vscode
*.log
dist

31
frontend/Dockerfile Normal file
View file

@ -0,0 +1,31 @@
# Build stage
FROM node:20-alpine as build
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install all dependencies (including devDependencies for build)
RUN npm ci
# Copy source code
COPY . .
# Build the application
RUN npm run build
# Production stage
FROM nginx:alpine
# Copy built files from build stage
COPY --from=build /app/dist /usr/share/nginx/html
# Copy custom nginx configuration for SPA
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Expose port
EXPOSE 80
# Start nginx
CMD ["nginx", "-g", "daemon off;"]

31
frontend/nginx.conf Normal file
View file

@ -0,0 +1,31 @@
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript;
# Handle SPA routing
location / {
try_files $uri $uri/ /index.html;
}
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
}

View file

@ -25,8 +25,10 @@ export const useOrderStore = defineStore('orders', () => {
const connectWebSocket = () => {
try {
connectionStatus.value = 'connecting'
// WebSocket-Verbindung zum Backend
wsConnection.value = new WebSocket('ws://localhost:8000/ws')
// WebSocket-Verbindung zum Backend über relative URL
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
const wsUrl = `${protocol}//${window.location.host}/api/ws`
wsConnection.value = new WebSocket(wsUrl)
wsConnection.value.onopen = () => {
console.log('WebSocket verbunden')
@ -168,7 +170,7 @@ export const useOrderStore = defineStore('orders', () => {
const createOrderHttp = async (orderRequest: CreateOrderRequest) => {
try {
const response = await fetch('http://localhost:8000/orders', {
const response = await fetch('/api/orders', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@ -233,7 +235,7 @@ export const useOrderStore = defineStore('orders', () => {
const deleteOrderHttp = async (orderId: string) => {
try {
const response = await fetch(`http://localhost:8000/orders/${orderId}`, {
const response = await fetch(`/api/orders/${orderId}`, {
method: 'DELETE',
})

View file

@ -79,6 +79,7 @@ import { useRouter } from 'vue-router'
import { useOrderStore } from '@/stores/orderStore'
import { DrinkType, MateType, type Drink } from '@/types/order'
import DrinkCard from '@/components/NewDrinkCard.vue'
import { type Order } from '@/types/order'
const router = useRouter()
const orderStore = useOrderStore()
@ -149,7 +150,7 @@ const submitOrder = async () => {
try {
const newOrder = await orderStore.createOrder({
drinks: validDrinks.value
})
}) as Order
toast.value = {
show: true,
message: `Bestellung erfolgreich! ID: ${newOrder.id}`
@ -167,15 +168,6 @@ const submitOrder = async () => {
// Modal- und createNewOrder-Logik entfernt
const closeSuccessModal = () => {
showSuccessModal.value = false
}
const createNewOrder = () => {
showSuccessModal.value = false
resetForm()
}
const retryConnection = () => {
orderStore.connectWebSocket()
}