Fix: Handle .env directory issue in bind mount and use relative API paths for single container
This commit is contained in:
@@ -31,6 +31,8 @@ services:
|
|||||||
- oltalama-logs:/app/backend/logs
|
- oltalama-logs:/app/backend/logs
|
||||||
# .env file (optional bind mount - host'tan container'a)
|
# .env file (optional bind mount - host'tan container'a)
|
||||||
# Eğer host'ta .env yoksa, entrypoint script container içinde oluşturur
|
# Eğer host'ta .env yoksa, entrypoint script container içinde oluşturur
|
||||||
|
# NOT: Host'ta .env dosyası yoksa, Docker onu dizin olarak oluşturabilir
|
||||||
|
# Entrypoint script bunu otomatik düzeltir
|
||||||
- ./backend/.env:/app/backend/.env:rw
|
- ./backend/.env:/app/backend/.env:rw
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
|
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
|
||||||
|
|||||||
@@ -27,18 +27,29 @@ if [ -z "$SESSION_SECRET" ] || [ "$SESSION_SECRET" = "change-this-to-a-very-stro
|
|||||||
SESSION_SECRET=$(node -e "console.log(require('crypto').randomBytes(64).toString('hex'))")
|
SESSION_SECRET=$(node -e "console.log(require('crypto').randomBytes(64).toString('hex'))")
|
||||||
export SESSION_SECRET
|
export SESSION_SECRET
|
||||||
|
|
||||||
|
# .env dosyası yolu
|
||||||
|
ENV_FILE="/app/backend/.env"
|
||||||
|
|
||||||
|
# Eğer .env bir dizin ise (bind mount sorunu), sil ve dosya olarak oluştur
|
||||||
|
if [ -d "$ENV_FILE" ]; then
|
||||||
|
echo "⚠️ .env bir dizin olarak tespit edildi, düzeltiliyor..."
|
||||||
|
rm -rf "$ENV_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# .env dizinini oluştur (yoksa)
|
||||||
|
mkdir -p "$(dirname "$ENV_FILE")"
|
||||||
|
|
||||||
# Session secret'ı .env dosyasına kaydet (persist)
|
# Session secret'ı .env dosyasına kaydet (persist)
|
||||||
if [ ! -f "/app/backend/.env" ]; then
|
if [ ! -f "$ENV_FILE" ]; then
|
||||||
mkdir -p /app/backend
|
echo "SESSION_SECRET=$SESSION_SECRET" > "$ENV_FILE"
|
||||||
echo "SESSION_SECRET=$SESSION_SECRET" > /app/backend/.env
|
|
||||||
echo "✅ Yeni SESSION_SECRET oluşturuldu ve .env dosyasına kaydedildi"
|
echo "✅ Yeni SESSION_SECRET oluşturuldu ve .env dosyasına kaydedildi"
|
||||||
echo "📝 SESSION_SECRET: ${SESSION_SECRET:0:20}... (ilk 20 karakter)"
|
echo "📝 SESSION_SECRET: ${SESSION_SECRET:0:20}... (ilk 20 karakter)"
|
||||||
else
|
else
|
||||||
# Mevcut .env dosyasını güncelle
|
# Mevcut .env dosyasını güncelle
|
||||||
if grep -q "^SESSION_SECRET=" /app/backend/.env; then
|
if grep -q "^SESSION_SECRET=" "$ENV_FILE"; then
|
||||||
sed -i "s|^SESSION_SECRET=.*|SESSION_SECRET=$SESSION_SECRET|" /app/backend/.env
|
sed -i "s|^SESSION_SECRET=.*|SESSION_SECRET=$SESSION_SECRET|" "$ENV_FILE"
|
||||||
else
|
else
|
||||||
echo "SESSION_SECRET=$SESSION_SECRET" >> /app/backend/.env
|
echo "SESSION_SECRET=$SESSION_SECRET" >> "$ENV_FILE"
|
||||||
fi
|
fi
|
||||||
echo "✅ SESSION_SECRET güncellendi ve .env dosyasına kaydedildi"
|
echo "✅ SESSION_SECRET güncellendi ve .env dosyasına kaydedildi"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -13,9 +13,7 @@ import {
|
|||||||
Grid,
|
Grid,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { Save, Send } from '@mui/icons-material';
|
import { Save, Send } from '@mui/icons-material';
|
||||||
import axios from 'axios';
|
import api from '../services/api';
|
||||||
|
|
||||||
const API_URL = import.meta.env.VITE_API_URL;
|
|
||||||
|
|
||||||
function Settings() {
|
function Settings() {
|
||||||
const [settings, setSettings] = useState({
|
const [settings, setSettings] = useState({
|
||||||
@@ -49,9 +47,7 @@ function Settings() {
|
|||||||
|
|
||||||
const loadSettings = async () => {
|
const loadSettings = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`${API_URL}/api/settings`, {
|
const response = await api.get('/api/settings');
|
||||||
withCredentials: true,
|
|
||||||
});
|
|
||||||
const data = response.data.data || {};
|
const data = response.data.data || {};
|
||||||
|
|
||||||
// Convert array to object
|
// Convert array to object
|
||||||
@@ -83,9 +79,7 @@ function Settings() {
|
|||||||
|
|
||||||
const loadAdminInfo = async () => {
|
const loadAdminInfo = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`${API_URL}/api/settings/admin`, {
|
const response = await api.get('/api/settings/admin');
|
||||||
withCredentials: true,
|
|
||||||
});
|
|
||||||
if (response.data.success && response.data.data) {
|
if (response.data.success && response.data.data) {
|
||||||
setAdminInfo({
|
setAdminInfo({
|
||||||
username: response.data.data.username || '',
|
username: response.data.data.username || '',
|
||||||
@@ -102,21 +96,21 @@ function Settings() {
|
|||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
try {
|
try {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
axios.put(`${API_URL}/api/settings/system`, {
|
api.put('/api/settings/system', {
|
||||||
base_url: settings.base_url,
|
base_url: settings.base_url,
|
||||||
frontend_url: settings.frontend_url,
|
frontend_url: settings.frontend_url,
|
||||||
cors_enabled: settings.cors_enabled,
|
cors_enabled: settings.cors_enabled,
|
||||||
}, { withCredentials: true }),
|
}, { withCredentials: true }),
|
||||||
axios.put(`${API_URL}/api/settings/gmail`, {
|
api.put('/api/settings/gmail', {
|
||||||
gmail_user: settings.gmail_user,
|
gmail_user: settings.gmail_user,
|
||||||
gmail_app_password: settings.gmail_app_password,
|
gmail_app_password: settings.gmail_app_password,
|
||||||
gmail_from_name: settings.gmail_from_name,
|
gmail_from_name: settings.gmail_from_name,
|
||||||
}, { withCredentials: true }),
|
}, { withCredentials: true }),
|
||||||
axios.put(`${API_URL}/api/settings/telegram`, {
|
api.put('/api/settings/telegram', {
|
||||||
telegram_bot_token: settings.telegram_bot_token,
|
telegram_bot_token: settings.telegram_bot_token,
|
||||||
telegram_chat_id: settings.telegram_chat_id,
|
telegram_chat_id: settings.telegram_chat_id,
|
||||||
}, { withCredentials: true }),
|
}, { withCredentials: true }),
|
||||||
axios.put(`${API_URL}/api/ollama/settings`, {
|
api.put('/api/ollama/settings', {
|
||||||
ollama_server_url: settings.ollama_server_url,
|
ollama_server_url: settings.ollama_server_url,
|
||||||
ollama_model: settings.ollama_model,
|
ollama_model: settings.ollama_model,
|
||||||
}, { withCredentials: true }),
|
}, { withCredentials: true }),
|
||||||
@@ -131,11 +125,7 @@ function Settings() {
|
|||||||
const handleTestMail = async () => {
|
const handleTestMail = async () => {
|
||||||
setTestLoading({ ...testLoading, mail: true });
|
setTestLoading({ ...testLoading, mail: true });
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(
|
const response = await api.post('/api/settings/test-gmail', {});
|
||||||
`${API_URL}/api/settings/test-gmail`,
|
|
||||||
{},
|
|
||||||
{ withCredentials: true }
|
|
||||||
);
|
|
||||||
setAlerts({ ...alerts, mail: { severity: 'success', message: response.data.message } });
|
setAlerts({ ...alerts, mail: { severity: 'success', message: response.data.message } });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setAlerts({
|
setAlerts({
|
||||||
@@ -150,11 +140,7 @@ function Settings() {
|
|||||||
const handleTestTelegram = async () => {
|
const handleTestTelegram = async () => {
|
||||||
setTestLoading({ ...testLoading, telegram: true });
|
setTestLoading({ ...testLoading, telegram: true });
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(
|
const response = await api.post('/api/settings/test-telegram', {});
|
||||||
`${API_URL}/api/settings/test-telegram`,
|
|
||||||
{},
|
|
||||||
{ withCredentials: true }
|
|
||||||
);
|
|
||||||
setAlerts({ ...alerts, telegram: { severity: 'success', message: response.data.message } });
|
setAlerts({ ...alerts, telegram: { severity: 'success', message: response.data.message } });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setAlerts({
|
setAlerts({
|
||||||
@@ -182,10 +168,7 @@ function Settings() {
|
|||||||
}, { withCredentials: true });
|
}, { withCredentials: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await axios.get(
|
const response = await api.get('/api/ollama/test');
|
||||||
`${API_URL}/api/ollama/test`,
|
|
||||||
{ withCredentials: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.data.success) {
|
if (response.data.success) {
|
||||||
setOllamaModels(response.data.data.models || []);
|
setOllamaModels(response.data.data.models || []);
|
||||||
@@ -233,11 +216,7 @@ function Settings() {
|
|||||||
updateData.current_password = adminInfo.current_password;
|
updateData.current_password = adminInfo.current_password;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await axios.put(
|
const response = await api.put('/api/settings/admin', updateData);
|
||||||
`${API_URL}/api/settings/admin`,
|
|
||||||
updateData,
|
|
||||||
{ withCredentials: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.data.success) {
|
if (response.data.success) {
|
||||||
setAlerts({
|
setAlerts({
|
||||||
|
|||||||
@@ -1,6 +1,26 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3000';
|
// Single container setup: Use relative path (same origin)
|
||||||
|
// Multi-container setup: Use VITE_API_URL or default to localhost:3000
|
||||||
|
const getApiUrl = () => {
|
||||||
|
const envUrl = import.meta.env.VITE_API_URL;
|
||||||
|
|
||||||
|
// If VITE_API_URL is set, use it
|
||||||
|
if (envUrl) {
|
||||||
|
return envUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Single container: same origin, use relative path
|
||||||
|
// This works because frontend and backend are served from the same port
|
||||||
|
if (import.meta.env.PROD) {
|
||||||
|
return ''; // Relative path - same origin
|
||||||
|
}
|
||||||
|
|
||||||
|
// Development: default to localhost:3000
|
||||||
|
return 'http://localhost:3000';
|
||||||
|
};
|
||||||
|
|
||||||
|
const API_URL = getApiUrl();
|
||||||
|
|
||||||
const api = axios.create({
|
const api = axios.create({
|
||||||
baseURL: API_URL,
|
baseURL: API_URL,
|
||||||
|
|||||||
Reference in New Issue
Block a user