mirror of
https://github.com/R0m1k3/podcastic.git
synced 2026-10-11 17:26:20 +02:00
fix: single container without nginx — Express serves frontend
- Remove separate backend/ and frontend/ Dockerfiles - Add root Dockerfile (3-stage: frontend build → backend build → runtime) - Frontend static files served by Express from /public - Simplify docker-compose to 3 services: mongodb, redis, app (port 3579) - Fix vite proxy not to strip /api prefix from paths - Default API URL to relative /api instead of hardcoded localhost Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a8787857b5
commit
1822ab1afe
9 files changed
+157
-480
No files matched your search
+3
-2
@@ -22,5 +22,6 @@ JWT_REFRESH_EXPIRES_IN=30d
|
||||
PODCAST_INDEX_API_KEY=
|
||||
PODCAST_INDEX_API_SECRET=
|
||||
|
||||
# Frontend Configuration
|
||||
VITE_API_URL=http://localhost:5000/api
|
||||
# Frontend Configuration (only needed for local dev without Docker)
|
||||
# In Docker, the frontend is served by the backend itself — no VITE_API_URL needed
|
||||
VITE_API_URL=/api
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
# Stage 1: Build frontend
|
||||
FROM node:20-alpine AS frontend-builder
|
||||
|
||||
WORKDIR /frontend
|
||||
|
||||
COPY frontend/package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY frontend/ ./
|
||||
|
||||
# Build with /api as the API base URL (served by Express on same host)
|
||||
ENV VITE_API_URL=/api
|
||||
RUN npm run build
|
||||
|
||||
# Stage 2: Build backend
|
||||
FROM node:20-alpine AS backend-builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY backend/package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY backend/tsconfig.json ./
|
||||
COPY backend/src ./src
|
||||
|
||||
RUN npm run build
|
||||
|
||||
# Stage 3: Production image
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy backend production deps
|
||||
COPY backend/package*.json ./
|
||||
RUN npm ci --omit=dev
|
||||
|
||||
# Copy compiled backend
|
||||
COPY --from=backend-builder /app/dist ./dist
|
||||
|
||||
# Copy frontend build into public/ (backend will serve it as static files)
|
||||
COPY --from=frontend-builder /frontend/dist ./public
|
||||
|
||||
EXPOSE 3579
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=3579
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
+81
-406
@@ -1,458 +1,133 @@
|
||||
# 🐳 Podcastic - Unraid Installation Guide
|
||||
# Podcastic - Unraid Installation Guide
|
||||
|
||||
Complete guide to install Podcastic on Unraid as a **single all-in-one container**.
|
||||
Single container on port **3579** — includes backend, frontend, and serves everything via Express.
|
||||
|
||||
## 📋 What's Included
|
||||
## What's Included
|
||||
|
||||
This single Docker container includes:
|
||||
- ✅ **Backend**: Node.js + Express.js API
|
||||
- ✅ **Frontend**: React web interface
|
||||
- ✅ **Database**: MongoDB (embedded)
|
||||
- ✅ **Cache**: Redis (embedded)
|
||||
- ✅ **Web Server**: Nginx reverse proxy
|
||||
- ✅ **Process Manager**: Supervisor (manages all 5 services)
|
||||
|
||||
All in **ONE container** on port **3579**
|
||||
- **Backend**: Node.js + Express.js API
|
||||
- **Frontend**: React web interface (served by Express as static files)
|
||||
- **Database**: MongoDB (separate container, managed by Compose)
|
||||
- **Cache**: Redis (separate container, managed by Compose)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Unraid server with Docker support
|
||||
- ~2GB RAM available
|
||||
- ~20GB storage for database/media
|
||||
- Internet connection
|
||||
- Docker Compose (or Unraid's Compose Manager plugin)
|
||||
|
||||
## Installation Steps
|
||||
## Installation
|
||||
|
||||
### Step 1: Clone Repository
|
||||
|
||||
```bash
|
||||
# Via terminal on Unraid
|
||||
cd /mnt/user/appdata # or your preferred path
|
||||
cd /mnt/user/appdata
|
||||
git clone https://github.com/R0m1k3/podcastic.git
|
||||
cd podcastic
|
||||
```
|
||||
|
||||
Or download as ZIP from GitHub and extract.
|
||||
|
||||
### Step 2: Configure Environment
|
||||
|
||||
```bash
|
||||
# Copy template
|
||||
cp .env.example .env
|
||||
|
||||
# Edit with your settings
|
||||
nano .env
|
||||
```
|
||||
|
||||
**Key settings**:
|
||||
**Change at minimum:**
|
||||
```env
|
||||
NODE_ENV=production
|
||||
|
||||
# JWT Secret - CHANGE THIS!
|
||||
JWT_SECRET=your-super-secret-key-change-me-in-production
|
||||
|
||||
# Optional: PodcastIndex API for podcast search
|
||||
PODCAST_INDEX_API_KEY=
|
||||
PODCAST_INDEX_API_SECRET=
|
||||
JWT_SECRET=your-random-secret-here
|
||||
```
|
||||
|
||||
### Step 3: Build Docker Image
|
||||
### Step 3: Build and Start
|
||||
|
||||
Option A: Build locally (takes ~5-10 minutes)
|
||||
```bash
|
||||
docker-compose -f docker-compose.unraid.yml build --no-cache
|
||||
docker-compose build --no-cache
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
Option B: Use pre-built image (faster)
|
||||
```bash
|
||||
# Will be available after first push to Docker Hub
|
||||
# docker pull r0m1k3/podcastic:latest
|
||||
### Step 4: Access
|
||||
|
||||
Open: `http://your-unraid-ip:3579`
|
||||
|
||||
---
|
||||
|
||||
## Container Architecture
|
||||
|
||||
```
|
||||
docker-compose services:
|
||||
├── podcastic (port 3579)
|
||||
│ ├── Express.js API → /api/*
|
||||
│ └── React frontend → /* (static files)
|
||||
├── podcastic-mongodb → internal :27017
|
||||
└── podcastic-redis → internal :6379
|
||||
```
|
||||
|
||||
### Step 4: Start Container
|
||||
Only port **3579** is exposed externally.
|
||||
|
||||
---
|
||||
|
||||
## Data Persistence
|
||||
|
||||
Add volume mounts to `docker-compose.yml` for persistence:
|
||||
|
||||
```yaml
|
||||
mongodb:
|
||||
volumes:
|
||||
- /mnt/user/appdata/podcastic/db:/data/db
|
||||
|
||||
redis:
|
||||
volumes:
|
||||
- /mnt/user/appdata/podcastic/redis:/data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Management Commands
|
||||
|
||||
```bash
|
||||
# Start
|
||||
docker-compose -f docker-compose.unraid.yml up -d
|
||||
|
||||
# View logs
|
||||
docker-compose -f docker-compose.unraid.yml logs -f podcastic
|
||||
docker-compose logs -f app
|
||||
|
||||
# Check status
|
||||
docker ps | grep podcastic
|
||||
```
|
||||
# Restart
|
||||
docker-compose restart app
|
||||
|
||||
### Step 5: Access Application
|
||||
# Stop all
|
||||
docker-compose down
|
||||
|
||||
Open browser:
|
||||
```
|
||||
http://your-unraid-ip:3579
|
||||
```
|
||||
|
||||
**First Time Setup**:
|
||||
1. Click "Create Account"
|
||||
2. Register with email/password
|
||||
3. Log in
|
||||
4. Go to "Discover" to search podcasts
|
||||
5. Subscribe and listen!
|
||||
|
||||
---
|
||||
|
||||
## 📊 Container Architecture
|
||||
|
||||
```
|
||||
Single Container (podcastic)
|
||||
├── Nginx (port 3579)
|
||||
│ ├── Serves static frontend
|
||||
│ └── Proxies /api to backend
|
||||
├── Node.js Backend (internal port 5000)
|
||||
│ ├── API routes
|
||||
│ ├── Authentication
|
||||
│ └── Database management
|
||||
├── MongoDB (internal port 27017)
|
||||
│ └── Podcast data storage
|
||||
└── Redis (internal port 6379)
|
||||
└── Cache & sessions
|
||||
```
|
||||
|
||||
All services communicate **internally** - only port 3579 exposed.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Unraid Integration
|
||||
|
||||
### Add to Unraid via WebUI
|
||||
|
||||
1. **Settings → Docker** → Enable Docker
|
||||
2. **Docker** tab
|
||||
3. Add custom template:
|
||||
```xml
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Container version="2">
|
||||
<Name>podcastic</Name>
|
||||
<Repository>r0m1k3/podcastic:latest</Repository>
|
||||
<Registry>https://hub.docker.com/</Registry>
|
||||
<Network>bridge</Network>
|
||||
<MyIP/>
|
||||
<Shell>sh</Shell>
|
||||
<Privileged>false</Privileged>
|
||||
<Support/>
|
||||
<Project/>
|
||||
<Overview/>
|
||||
<Category/>
|
||||
<WebUI>http://[IP]:[PORT:3579]</WebUI>
|
||||
<TemplateURL/>
|
||||
<Icon/>
|
||||
<ExtraParams/>
|
||||
<PostArgs/>
|
||||
<StaticNetwork>false</StaticNetwork>
|
||||
<DonateText/>
|
||||
<DonateLink/>
|
||||
<Description>Podcastic - Multi-user podcast streaming application</Description>
|
||||
<Networking>
|
||||
<Mode>bridge</Mode>
|
||||
<Publish>
|
||||
<Port>
|
||||
<HostPort>3579</HostPort>
|
||||
<ContainerPort>3579</ContainerPort>
|
||||
<Protocol>tcp</Protocol>
|
||||
</Port>
|
||||
</Publish>
|
||||
</Networking>
|
||||
<Data>
|
||||
<Volume>
|
||||
<HostDir>/mnt/user/appdata/podcastic/db</HostDir>
|
||||
<ContainerDir>/data/db</ContainerDir>
|
||||
<Mode>rw</Mode>
|
||||
</Volume>
|
||||
<Volume>
|
||||
<HostDir>/mnt/user/appdata/podcastic/redis</HostDir>
|
||||
<ContainerDir>/data/redis</ContainerDir>
|
||||
<Mode>rw</Mode>
|
||||
</Volume>
|
||||
<Volume>
|
||||
<HostDir>/mnt/user/appdata/podcastic/logs</HostDir>
|
||||
<ContainerDir>/var/log/supervisor</ContainerDir>
|
||||
<Mode>rw</Mode>
|
||||
</Volume>
|
||||
</Data>
|
||||
<Environment>
|
||||
<Variable>
|
||||
<Name>JWT_SECRET</Name>
|
||||
<Value>change-me-in-production</Value>
|
||||
</Variable>
|
||||
<Variable>
|
||||
<Name>PODCAST_INDEX_API_KEY</Name>
|
||||
<Value/>
|
||||
</Variable>
|
||||
<Variable>
|
||||
<Name>PODCAST_INDEX_API_SECRET</Name>
|
||||
<Value/>
|
||||
</Variable>
|
||||
</Environment>
|
||||
</Container>
|
||||
```
|
||||
|
||||
Or use Docker Compose tab with `docker-compose.unraid.yml`
|
||||
|
||||
---
|
||||
|
||||
## 📂 Data Persistence
|
||||
|
||||
Data is saved to Unraid shares:
|
||||
|
||||
```
|
||||
/mnt/user/appdata/podcastic/
|
||||
├── db/ # MongoDB data (podcasts, users, episodes)
|
||||
├── redis/ # Redis cache data
|
||||
└── logs/ # Application logs
|
||||
```
|
||||
|
||||
### Backup
|
||||
|
||||
```bash
|
||||
# Backup database
|
||||
docker exec podcastic mongodump --out /backup/mongodb
|
||||
|
||||
# Copy to safe location
|
||||
cp -r /mnt/user/appdata/podcastic /mnt/backup/podcastic-backup
|
||||
```
|
||||
|
||||
### Restore
|
||||
|
||||
```bash
|
||||
docker exec podcastic mongorestore /backup/mongodb
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Management Commands
|
||||
|
||||
### View Logs
|
||||
|
||||
```bash
|
||||
# All logs
|
||||
docker logs -f podcastic
|
||||
|
||||
# Specific service
|
||||
docker exec podcastic tail -f /var/log/supervisor/backend.out.log
|
||||
docker exec podcastic tail -f /var/log/supervisor/mongodb.out.log
|
||||
docker exec podcastic tail -f /var/log/supervisor/redis.out.log
|
||||
docker exec podcastic tail -f /var/log/supervisor/nginx.out.log
|
||||
```
|
||||
|
||||
### Restart Container
|
||||
|
||||
```bash
|
||||
docker-compose -f docker-compose.unraid.yml restart podcastic
|
||||
```
|
||||
|
||||
### Stop Container
|
||||
|
||||
```bash
|
||||
docker-compose -f docker-compose.unraid.yml down
|
||||
|
||||
# Keep volumes (data persists)
|
||||
# Data in /mnt/user/appdata/podcastic/ is preserved
|
||||
```
|
||||
|
||||
### Update to Latest
|
||||
|
||||
```bash
|
||||
# Pull latest code
|
||||
cd /path/to/podcastic
|
||||
# Update
|
||||
git pull
|
||||
|
||||
# Rebuild and restart
|
||||
docker-compose -f docker-compose.unraid.yml build --no-cache
|
||||
docker-compose -f docker-compose.unraid.yml up -d
|
||||
docker-compose build --no-cache
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
## Unraid WebUI Template
|
||||
|
||||
### Container won't start
|
||||
Add via Docker > Add Container:
|
||||
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| Repository | (build from compose) |
|
||||
| Port | 3579:3579 |
|
||||
| Variable: JWT_SECRET | your-secret |
|
||||
| Variable: MONGODB_URI | mongodb://podcastic-mongodb:27017/podcastic |
|
||||
| Variable: REDIS_URL | redis://podcastic-redis:6379 |
|
||||
|
||||
Or use **Compose Manager plugin** with the `docker-compose.yml` from this repo.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
```bash
|
||||
# Check logs
|
||||
docker logs podcastic
|
||||
# Check container status
|
||||
docker-compose ps
|
||||
|
||||
# Common issues:
|
||||
# - Port 3579 in use: Change in docker-compose.unraid.yml
|
||||
# - Insufficient RAM: Free up memory
|
||||
# - Permission issues: Check volume permissions
|
||||
```
|
||||
|
||||
### MongoDB not starting
|
||||
|
||||
```bash
|
||||
# Check mongo logs
|
||||
docker exec podcastic tail -f /var/log/supervisor/mongodb.out.log
|
||||
|
||||
# Repair database
|
||||
docker exec podcastic mongod --repair --dbpath /data/db
|
||||
```
|
||||
|
||||
### Can't access on port 3579
|
||||
|
||||
```bash
|
||||
# Check if container is running
|
||||
docker ps | grep podcastic
|
||||
|
||||
# Check if port is open
|
||||
netstat -tulpn | grep 3579
|
||||
|
||||
# Test connection
|
||||
# Check health endpoint
|
||||
curl http://localhost:3579/health
|
||||
|
||||
# Check API
|
||||
curl http://localhost:3579/api/health
|
||||
```
|
||||
|
||||
### Out of disk space
|
||||
|
||||
MongoDB can grow large. Check:
|
||||
```bash
|
||||
docker exec podcastic du -sh /data/db
|
||||
|
||||
# Clean old data (backup first!)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Performance Optimization
|
||||
|
||||
### For Limited Resources
|
||||
|
||||
Edit `docker-compose.unraid.yml`:
|
||||
```yaml
|
||||
# Limit memory usage
|
||||
mem_limit: 1g
|
||||
cpus: '0.5'
|
||||
```
|
||||
|
||||
### For High Performance
|
||||
|
||||
Increase limits:
|
||||
```yaml
|
||||
mem_limit: 4g
|
||||
cpus: '2'
|
||||
```
|
||||
|
||||
### Disable Unneeded Features
|
||||
|
||||
If only streaming (no search):
|
||||
```env
|
||||
PODCAST_INDEX_API_KEY= # Leave empty
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔒 Security Notes
|
||||
|
||||
### Change Default Secrets
|
||||
|
||||
```env
|
||||
# MUST change in production!
|
||||
JWT_SECRET=your-unique-secret-key-here
|
||||
|
||||
# Use strong password for first admin account
|
||||
```
|
||||
|
||||
### Firewall Rules
|
||||
|
||||
Allow only trusted IPs:
|
||||
```bash
|
||||
# On Unraid, set firewall rules in UI
|
||||
# Or use nginx config to restrict access
|
||||
```
|
||||
|
||||
### SSL/HTTPS Setup
|
||||
|
||||
If exposing to internet, use reverse proxy with SSL:
|
||||
- Nginx Proxy Manager (separate container)
|
||||
- Traefik (with Let's Encrypt)
|
||||
- Unraid built-in reverse proxy
|
||||
|
||||
---
|
||||
|
||||
## 📊 Monitoring
|
||||
|
||||
### Check Container Health
|
||||
|
||||
```bash
|
||||
# Real-time stats
|
||||
docker stats podcastic
|
||||
|
||||
# Service status
|
||||
docker exec podcastic supervisorctl status
|
||||
|
||||
# Expected output:
|
||||
# mongodb RUNNING pid 123, uptime 0:00:45
|
||||
# redis RUNNING pid 124, uptime 0:00:45
|
||||
# backend RUNNING pid 125, uptime 0:00:45
|
||||
# nginx RUNNING pid 126, uptime 0:00:45
|
||||
```
|
||||
|
||||
### Resource Usage
|
||||
|
||||
```bash
|
||||
# Disk usage
|
||||
du -sh /mnt/user/appdata/podcastic/
|
||||
|
||||
# Memory usage
|
||||
docker exec podcastic free -h
|
||||
|
||||
# CPU usage
|
||||
docker stats --no-stream podcastic
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🆘 Support
|
||||
|
||||
If issues occur:
|
||||
|
||||
1. **Check logs**:
|
||||
```bash
|
||||
docker logs podcastic
|
||||
```
|
||||
|
||||
2. **Check service status**:
|
||||
```bash
|
||||
docker exec podcastic supervisorctl status
|
||||
```
|
||||
|
||||
3. **Rebuild container**:
|
||||
```bash
|
||||
docker-compose -f docker-compose.unraid.yml build --no-cache
|
||||
docker-compose -f docker-compose.unraid.yml up -d
|
||||
```
|
||||
|
||||
4. **Factory reset** (loses all data!):
|
||||
```bash
|
||||
docker-compose -f docker-compose.unraid.yml down -v
|
||||
rm -rf /mnt/user/appdata/podcastic
|
||||
# Start fresh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Next Steps
|
||||
|
||||
1. **First Run**: Create account, set JWT_SECRET properly
|
||||
2. **Configure PodcastIndex**: Optional, enables podcast search
|
||||
3. **Add Podcasts**: Via Discover or RSS URLs
|
||||
4. **Enjoy**: Start listening!
|
||||
|
||||
---
|
||||
|
||||
## 📚 Additional Resources
|
||||
|
||||
- **Main README**: See README.md
|
||||
- **Getting Started**: See GETTING_STARTED.md
|
||||
- **PodcastIndex Setup**: See PODCAST_INDEX_SETUP.md
|
||||
- **GitHub**: https://github.com/R0m1k3/podcastic
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2026-04-16
|
||||
**Tested on**: Unraid 6.12+
|
||||
@@ -1,15 +0,0 @@
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY tsconfig.json ./
|
||||
COPY src ./src
|
||||
|
||||
RUN npm run build
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
+19
-4
@@ -1,14 +1,18 @@
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import 'dotenv/config';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { connectDB } from './config/database';
|
||||
import { initRedis, closeRedis } from './config/redis';
|
||||
import { authenticate, optional } from './middleware/auth';
|
||||
import { errorHandler, notFoundHandler } from './middleware/errorHandler';
|
||||
import { errorHandler } from './middleware/errorHandler';
|
||||
import authRoutes from './routes/authRoutes';
|
||||
import podcastRoutes from './routes/podcastRoutes';
|
||||
import episodeRoutes from './routes/episodeRoutes';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 5000;
|
||||
|
||||
@@ -48,8 +52,19 @@ app.use('/api/auth', authRoutes);
|
||||
app.use('/api/podcasts', podcastRoutes);
|
||||
app.use('/api/episodes', episodeRoutes);
|
||||
|
||||
// 404 handler
|
||||
app.use(notFoundHandler);
|
||||
// Serve frontend static files in production
|
||||
const frontendDist = path.join(__dirname, '..', 'public');
|
||||
app.use(express.static(frontendDist));
|
||||
|
||||
// SPA fallback — return index.html for any non-API route
|
||||
app.get('*', (req, res) => {
|
||||
const indexFile = path.join(frontendDist, 'index.html');
|
||||
res.sendFile(indexFile, (err) => {
|
||||
if (err) {
|
||||
res.status(404).json({ success: false, message: 'Not found' });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Error handler (must be last)
|
||||
app.use(errorHandler);
|
||||
|
||||
+5
-17
@@ -19,16 +19,17 @@ services:
|
||||
networks:
|
||||
- podcastic
|
||||
|
||||
backend:
|
||||
app:
|
||||
build:
|
||||
context: ./backend
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: podcastic-backend
|
||||
container_name: podcastic
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "5000:5000"
|
||||
- "3579:3579"
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
PORT: 3579
|
||||
MONGODB_URI: mongodb://mongodb:27017/podcastic
|
||||
REDIS_URL: redis://redis:6379
|
||||
JWT_SECRET: ${JWT_SECRET:-change_me_in_production}
|
||||
@@ -42,19 +43,6 @@ services:
|
||||
networks:
|
||||
- podcastic
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile
|
||||
container_name: podcastic-frontend
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3579:3579"
|
||||
depends_on:
|
||||
- backend
|
||||
networks:
|
||||
- podcastic
|
||||
|
||||
volumes:
|
||||
mongodb_data:
|
||||
redis_data:
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
COPY <<'EOF' /etc/nginx/conf.d/default.conf
|
||||
server {
|
||||
listen 3579;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_pass http://backend:5000;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
EXPOSE 3579
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
@@ -1,6 +1,6 @@
|
||||
import axios from 'axios';
|
||||
|
||||
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:5000/api';
|
||||
const API_URL = import.meta.env.VITE_API_URL || '/api';
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: API_URL,
|
||||
|
||||
@@ -10,7 +10,6 @@ export default defineConfig({
|
||||
'/api': {
|
||||
target: 'http://localhost:5000',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, '')
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user