feat: update service ports from 3000/3001 to 3300/3301
Some checks are pending
Deploy to Production / deploy (push) Waiting to run

- Changed admin frontend port from 3000 to 3300 across all configuration files
- Changed API backend port from 3001 to 3301 across all configuration files
- Updated health check endpoints to use new ports in CI/CD workflow
- Modified documentation and deployment guides to reflect new port numbers
- Updated Caddy and Nginx reverse proxy configurations to use new ports
This commit is contained in:
Ender 2025-10-26 00:25:40 +02:00
parent d8c41cc206
commit f160b26564
18 changed files with 90 additions and 90 deletions

View File

@ -50,7 +50,7 @@ jobs:
- name: Health check API
run: |
for i in {1..10}; do
if curl -f http://localhost:3001/health; then
if curl -f http://localhost:3301/api/health; then
echo "API is healthy"
exit 0
fi
@ -63,7 +63,7 @@ jobs:
- name: Health check Admin
run: |
if curl -f http://localhost:3000; then
if curl -f http://localhost:3300; then
echo "Admin is healthy"
else
echo "Admin health check failed"

View File

@ -30,12 +30,12 @@ Add this configuration (from the `Caddyfile` in this repo):
admin.pusula.blog {
# Frontend
handle / {
reverse_proxy localhost:3000
reverse_proxy localhost:3300
}
# API
handle /api* {
reverse_proxy localhost:3001
reverse_proxy localhost:3301
}
encode gzip
@ -116,10 +116,10 @@ app2.yourdomain.com {
# Add VoxBlog
voxblog.yourdomain.com {
handle / {
reverse_proxy localhost:3000
reverse_proxy localhost:3300
}
handle /api* {
reverse_proxy localhost:3001
reverse_proxy localhost:3301
}
encode gzip
}
@ -153,8 +153,8 @@ sudo systemctl reload caddy
### Check if Ports are Accessible
```bash
# From VPS (should work)
curl http://localhost:3000
curl http://localhost:3001/health
curl http://localhost:3300
curl http://localhost:3301/api/health
# From internet (should work via domain)
curl https://voxblog.yourdomain.com
@ -168,8 +168,8 @@ curl https://voxblog.yourdomain.com/api/health
docker-compose ps
# Check if ports are accessible
curl http://localhost:3000
curl http://localhost:3001/health
curl http://localhost:3300
curl http://localhost:3301/api/health
# Check Caddy logs
sudo journalctl -u caddy -f
@ -197,13 +197,13 @@ If you prefer separate subdomains for frontend and API:
```caddy
# Frontend
voxblog.yourdomain.com {
reverse_proxy localhost:3000
reverse_proxy localhost:3300
encode gzip
}
# API
api.voxblog.yourdomain.com {
reverse_proxy localhost:3001
reverse_proxy localhost:3301
encode gzip
}
```
@ -246,12 +246,12 @@ app2.yourdomain.com {
voxblog.yourdomain.com {
# Frontend
handle / {
reverse_proxy localhost:3000
reverse_proxy localhost:3300
}
# API with long timeout for AI streaming
handle /api* {
reverse_proxy localhost:3001 {
reverse_proxy localhost:3301 {
transport http {
read_timeout 600s
write_timeout 600s

View File

@ -5,12 +5,12 @@
voxblog.yourdomain.com {
# Frontend (React Admin)
handle / {
reverse_proxy localhost:3000
reverse_proxy localhost:3300
}
# API Backend
handle /api* {
reverse_proxy localhost:3001
reverse_proxy localhost:3301
}
# Enable gzip compression
@ -35,7 +35,7 @@ voxblog.yourdomain.com {
# Frontend subdomain
# voxblog.yourdomain.com {
# reverse_proxy localhost:3000
# reverse_proxy localhost:3300
#
# encode gzip
#
@ -52,7 +52,7 @@ voxblog.yourdomain.com {
# API subdomain
# api.voxblog.yourdomain.com {
# reverse_proxy localhost:3001
# reverse_proxy localhost:3301
#
# encode gzip
#

View File

@ -16,8 +16,8 @@ Complete CI/CD pipeline for deploying VoxBlog to your VPS with Gitea using Docke
│ └────────────┘ └──────────────┘ └─────────────┘ │
│ ↓ │
│ ┌────────────────────────┐ │
│ │ voxblog-api:3001 │ │
│ │ voxblog-admin:3000 │ │
│ │ voxblog-api:3301 │ │
│ │ voxblog-admin:3300 │ │
│ │ mysql:3306 │ │
│ └────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
@ -93,7 +93,7 @@ COPY --from=builder /app/packages/config-ts ./packages/config-ts
WORKDIR /app/apps/api
EXPOSE 3001
EXPOSE 3301
CMD ["pnpm", "run", "dev"]
```
@ -202,10 +202,10 @@ services:
container_name: voxblog-api
restart: unless-stopped
ports:
- "3001:3001"
- "3301:3301"
environment:
NODE_ENV: production
PORT: 3001
PORT: 3301
DATABASE_URL: mysql://voxblog:${MYSQL_PASSWORD}@mysql:3306/voxblog
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
OPENAI_API_KEY: ${OPENAI_API_KEY}
@ -228,11 +228,11 @@ services:
context: .
dockerfile: docker/admin.Dockerfile
args:
VITE_API_URL: ${VITE_API_URL:-http://localhost:3001}
VITE_API_URL: ${VITE_API_URL:-http://localhost:3301}
container_name: voxblog-admin
restart: unless-stopped
ports:
- "3000:80"
- "3300:80"
networks:
- voxblog-network
depends_on:
@ -297,8 +297,8 @@ jobs:
- name: Health check
run: |
sleep 10
curl -f http://localhost:3001/health || exit 1
curl -f http://localhost:3000 || exit 1
curl -f http://localhost:3301/api/health || exit 1
curl -f http://localhost:3300 || exit 1
- name: Clean up old images
run: |
@ -349,14 +349,14 @@ docker-compose exec -T api pnpm run drizzle:migrate
# Health check
echo "🏥 Health check..."
if curl -f http://localhost:3001/health; then
if curl -f http://localhost:3301/api/health; then
echo "✅ API is healthy"
else
echo "❌ API health check failed"
exit 1
fi
if curl -f http://localhost:3000; then
if curl -f http://localhost:3300; then
echo "✅ Admin is healthy"
else
echo "❌ Admin health check failed"
@ -491,7 +491,7 @@ server {
# Admin frontend
location / {
proxy_pass http://localhost:3000;
proxy_pass http://localhost:3300;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
@ -501,7 +501,7 @@ server {
# API backend
location /api {
proxy_pass http://localhost:3001;
proxy_pass http://localhost:3301;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
@ -662,7 +662,7 @@ SHOW DATABASES;
### Port already in use
```bash
sudo lsof -i :3001
sudo lsof -i :3301
sudo kill -9 <PID>
```

View File

@ -35,8 +35,8 @@ voxblog/
│ └────────────┘ └──────────────┘ └─────────────┘ │
│ ↓ │
│ ┌────────────────────────┐ │
│ │ voxblog-api:3001 │ │
│ │ voxblog-admin:3000 │ │
│ │ voxblog-api:3301 │ │
│ │ voxblog-admin:3300 │ │
│ │ mysql:3306 │ │
│ └────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
@ -213,8 +213,8 @@ VITE_API_URL=https://api.yourdomain.com
### Without Domain (IP Only)
Access directly:
- Admin: `http://your-vps-ip:3000`
- API: `http://your-vps-ip:3001`
- Admin: `http://your-vps-ip:3300`
- API: `http://your-vps-ip:3301`
## 📊 Monitoring & Maintenance
@ -278,8 +278,8 @@ docker-compose restart
```bash
# Find process
sudo lsof -i :3001
sudo lsof -i :3000
sudo lsof -i :3301
sudo lsof -i :3300
# Kill process
sudo kill -9 <PID>

View File

@ -51,7 +51,7 @@ S3_SECRET_KEY=your-secret-key
S3_ENDPOINT=https://s3.amazonaws.com
# Frontend (for local testing)
VITE_API_URL=http://localhost:3001
VITE_API_URL=http://localhost:3301
```
### 2. Build and Start
@ -77,19 +77,19 @@ This will:
Watch the logs until you see:
```
voxblog-mysql | ready for connections
voxblog-api | Server listening on port 3001
voxblog-api | Server listening on port 3301
voxblog-admin | Configuration complete
```
### 4. Access Your Application
- **Frontend**: http://localhost:3000
- **API**: http://localhost:3001
- **API Health**: http://localhost:3001/health
- **Frontend**: http://localhost:3300
- **API**: http://localhost:3301
- **API Health**: http://localhost:3301/api/health
### 5. Test the Application
1. Open http://localhost:3000 in your browser
1. Open http://localhost:3300 in your browser
2. Login with your ADMIN_PASSWORD
3. Create a post
4. Upload images
@ -189,15 +189,15 @@ If you get "port is already allocated" error:
```bash
# Check what's using the port
sudo lsof -i :3000
sudo lsof -i :3001
sudo lsof -i :3300
sudo lsof -i :3301
# Kill the process
kill -9 <PID>
# Or change ports in docker-compose.yml
ports:
- "3002:80" # Use 3002 instead of 3000
- "3302:80" # Use 3302 instead of 3300
```
### Build Fails
@ -255,14 +255,14 @@ docker-compose logs api
1. Check if container is running: `docker-compose ps`
2. Check logs: `docker-compose logs admin`
3. Try accessing: `curl http://localhost:3000`
4. Check if port 3000 is free: `lsof -i :3000`
3. Try accessing: `curl http://localhost:3300`
4. Check if port 3300 is free: `lsof -i :3300`
### API Returns 502 Error
1. Check if API is running: `docker-compose ps`
2. Check API logs: `docker-compose logs api`
3. Test API directly: `curl http://localhost:3001/health`
3. Test API directly: `curl http://localhost:3301/api/health`
4. Check environment variables: `docker-compose exec api env`
## Development Workflow
@ -314,7 +314,7 @@ SELECT * FROM posts;
- [ ] `.env` file created with all values
- [ ] `docker-compose up --build` successful
- [ ] All 3 containers running (mysql, api, admin)
- [ ] Can access http://localhost:3000
- [ ] Can access http://localhost:3300
- [ ] Can login with ADMIN_PASSWORD
- [ ] Can create a post
- [ ] Can upload images

View File

@ -17,10 +17,10 @@ Internet
Port 80/443 (Nginx)
┌─────────────────────────────────────┐
│ app1.domain.com → localhost:3000 │
│ app1.domain.com → localhost:3300 │
│ app2.domain.com → localhost:4000 │
│ voxblog.domain.com → localhost:3000│ ← VoxBlog
│ voxblog.domain.com/api → :3001 │ ← VoxBlog API
│ voxblog.domain.com → localhost:3300│ ← VoxBlog
│ voxblog.domain.com/api → :3301 │ ← VoxBlog API
└─────────────────────────────────────┘
```
@ -29,8 +29,8 @@ Port 80/443 (Nginx)
**docker-compose.yml** - Ports now bind to localhost only:
```yaml
ports:
- "127.0.0.1:3000:80" # Not exposed to internet
- "127.0.0.1:3001:3001" # Not exposed to internet
- "127.0.0.1:3300:80" # Not exposed to internet
- "127.0.0.1:3301:3301" # Not exposed to internet
```
**Caddyfile** - Caddy configuration (automatic HTTPS!)
@ -60,10 +60,10 @@ Add this block (replace with your domain):
```caddy
voxblog.yourdomain.com {
handle / {
reverse_proxy localhost:3000
reverse_proxy localhost:3300
}
handle /api* {
reverse_proxy localhost:3001
reverse_proxy localhost:3301
}
encode gzip
}
@ -146,7 +146,7 @@ sudo ufw allow 443/tcp
sudo ufw status
```
Application ports (3000, 3001) are NOT exposed to internet - only accessible via Nginx!
Application ports (3300, 3301) are NOT exposed to internet - only accessible via Nginx!
## Benefits
@ -169,8 +169,8 @@ app2.yourdomain.com {
}
voxblog.yourdomain.com {
handle / { reverse_proxy localhost:3000 }
handle /api* { reverse_proxy localhost:3001 }
handle / { reverse_proxy localhost:3300 }
handle /api* { reverse_proxy localhost:3301 }
}
```
@ -206,8 +206,8 @@ All apps coexist peacefully! 🎉
docker-compose ps
# Check if ports are accessible
curl http://localhost:3000
curl http://localhost:3001/health
curl http://localhost:3300
curl http://localhost:3301/api/health
```
## Complete Documentation

View File

@ -50,8 +50,8 @@ chmod +x deploy.sh
```
That's it! Your application is now running:
- **API**: http://your-vps:3001
- **Admin**: http://your-vps:3000
- **API**: http://your-vps:3301
- **Admin**: http://your-vps:3300
### Step 4: Set Up CI/CD (Choose One)
@ -179,7 +179,7 @@ server {
# Admin frontend
location / {
proxy_pass http://localhost:3000;
proxy_pass http://localhost:3300;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
@ -189,7 +189,7 @@ server {
# API backend
location /api {
proxy_pass http://localhost:3001;
proxy_pass http://localhost:3301;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
@ -283,8 +283,8 @@ SHOW DATABASES;
### Port conflicts
```bash
sudo lsof -i :3001
sudo lsof -i :3000
sudo lsof -i :3301
sudo lsof -i :3300
```
### Disk space

View File

@ -32,7 +32,7 @@ export async function generateContentStream(
params: GenerateStreamParams,
callbacks: StreamCallbacks
): Promise<void> {
const response = await fetch('http://localhost:3001/api/ai/generate-stream', {
const response = await fetch('http://localhost:3301/api/ai/generate-stream', {
method: 'POST',
headers: {
'Content-Type': 'application/json',

View File

@ -7,7 +7,7 @@ export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:3001',
target: 'http://localhost:3301',
changeOrigin: true
}
}

View File

@ -131,17 +131,17 @@ cd apps/api
pnpm run dev
# Test content generation
curl -X POST http://localhost:3001/api/ai/generate \
curl -X POST http://localhost:3301/api/ai/generate \
-H "Content-Type: application/json" \
-d '{"prompt": "Write about TypeScript best practices"}'
# Test metadata generation
curl -X POST http://localhost:3001/api/ai/generate-metadata \
curl -X POST http://localhost:3301/api/ai/generate-metadata \
-H "Content-Type: application/json" \
-d '{"contentHtml": "<h1>Test Article</h1><p>Content here</p>"}'
# Test alt text generation
curl -X POST http://localhost:3001/api/ai/generate-alt-text \
curl -X POST http://localhost:3301/api/ai/generate-alt-text \
-H "Content-Type: application/json" \
-d '{"placeholderDescription": "dashboard_screenshot"}'
```

View File

@ -212,7 +212,7 @@ await generateContentStream(
### Test Streaming Endpoint
```bash
curl -N -X POST http://localhost:3001/api/ai/generate-stream \
curl -N -X POST http://localhost:3301/api/ai/generate-stream \
-H "Content-Type: application/json" \
-d '{"prompt": "Write a short article about TypeScript"}'
```

View File

@ -19,7 +19,7 @@ console.log('ENV ADMIN_PASSWORD loaded:', Boolean(process.env.ADMIN_PASSWORD));
// Middleware
app.use(cors({
origin: 'http://localhost:5173',
origin: process.env.CORS_ORIGIN || 'http://localhost:3300',
credentials: true
}));
app.use(morgan('dev'));
@ -49,7 +49,7 @@ app.use((err: any, _req: express.Request, res: express.Response, _next: express.
});
// Start server
const PORT = process.env.PORT || 3001;
const PORT = process.env.PORT || 3301;
app.listen(PORT, () => {
console.log(`API server running on port ${PORT}`);
});

View File

@ -45,7 +45,7 @@ docker-compose exec -T api pnpm run drizzle:migrate || echo "Migration skipped o
# Health check
echo -e "${YELLOW}🏥 Performing health checks...${NC}"
API_HEALTH=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3001/health || echo "000")
API_HEALTH=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3301/api/health || echo "000")
if [ "$API_HEALTH" = "200" ]; then
echo -e "${GREEN}✅ API is healthy${NC}"
else
@ -55,7 +55,7 @@ else
exit 1
fi
ADMIN_HEALTH=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000 || echo "000")
ADMIN_HEALTH=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3300 || echo "000")
if [ "$ADMIN_HEALTH" = "200" ]; then
echo -e "${GREEN}✅ Admin is healthy${NC}"
else
@ -73,8 +73,8 @@ echo ""
echo -e "${GREEN}✅ Deployment complete!${NC}"
echo ""
echo "Services running:"
echo " - API: http://localhost:3001"
echo " - Admin: http://localhost:3000"
echo " - API: http://localhost:3301"
echo " - Admin: http://localhost:3300"
echo ""
echo "To view logs: docker-compose logs -f"
echo "To stop: docker-compose down"

View File

@ -30,10 +30,10 @@ services:
container_name: voxblog-api
restart: unless-stopped
ports:
- "127.0.0.1:3001:3001" # Only localhost, not internet
- "127.0.0.1:3301:3301" # Only localhost, not internet
environment:
NODE_ENV: production
PORT: 3001
PORT: 3301
DATABASE_URL: mysql://voxblog:${MYSQL_PASSWORD}@mysql:3306/voxblog
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
OPENAI_API_KEY: ${OPENAI_API_KEY}
@ -56,12 +56,12 @@ services:
context: .
dockerfile: docker/admin.Dockerfile
args:
VITE_API_URL: ${VITE_API_URL:-http://localhost:3001}
VITE_API_URL: ${VITE_API_URL:-http://localhost:3301}
PNPM_FLAGS: --no-frozen-lockfile
container_name: voxblog-admin
restart: unless-stopped
ports:
- "127.0.0.1:3000:80" # Only localhost, not internet
- "127.0.0.1:3300:80" # Only localhost, not internet
networks:
- voxblog-network
depends_on:

View File

@ -3,7 +3,7 @@ FROM node:18-alpine AS builder
WORKDIR /app
# Build args
ARG VITE_API_URL=http://localhost:3001
ARG VITE_API_URL=http://localhost:3301
ARG PNPM_FLAGS=--frozen-lockfile
# Copy workspace files

View File

@ -40,10 +40,10 @@ WORKDIR /app/apps/api
# Create data directory
RUN mkdir -p /app/data
EXPOSE 3001
EXPOSE 3301
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD node -e "require('http').get('http://localhost:3001/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
CMD node -e "require('http').get('http://localhost:3301/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
CMD ["pnpm", "run", "dev"]

View File

@ -15,7 +15,7 @@ server {
# Frontend (React Admin)
location / {
proxy_pass http://127.0.0.1:3000;
proxy_pass http://127.0.0.1:3300;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
@ -28,7 +28,7 @@ server {
# API Backend
location /api {
proxy_pass http://127.0.0.1:3001;
proxy_pass http://127.0.0.1:3301;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';