deploy : current attempt at backend dockerization
This commit is contained in:
committed by
Antoine Vivies
parent
c1a1e9409d
commit
a3ad635728
@@ -2,3 +2,5 @@ SEARXNG_BASE_URL="http://127.0.0.1:8080"
|
||||
OPENAI_API_KEY='xxxxx'
|
||||
DEEPSEEK_API_KEY='xxxxx'
|
||||
OPENROUTER_API_KEY='xxxxx'
|
||||
BACKEND_PORT=8000
|
||||
WORK_DIR="/tmp/"
|
||||
@@ -19,6 +19,7 @@ agentic_seek_env/*
|
||||
.env
|
||||
*/.env
|
||||
dsk/
|
||||
chrome136/
|
||||
|
||||
### react ###
|
||||
.DS_*
|
||||
|
||||
+65
-24
@@ -1,38 +1,57 @@
|
||||
FROM ubuntu:22.04
|
||||
# Warning: doesn't work yet, backend is run on host machine for now
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update -qq -y && \
|
||||
apt-get install -y \
|
||||
gcc \
|
||||
g++ \
|
||||
gfortran \
|
||||
libportaudio2 \
|
||||
portaudio19-dev \
|
||||
ffmpeg \
|
||||
libavcodec-dev \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
gnupg2 \
|
||||
wget \
|
||||
unzip \
|
||||
python3 \
|
||||
python3-pip \
|
||||
libasound2 \
|
||||
libatk-bridge2.0-0 \
|
||||
libgtk-4-1 \
|
||||
libnss3 \
|
||||
xdg-utils \
|
||||
wget && \
|
||||
# Install essential packages and Chrome dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
wget \
|
||||
unzip \
|
||||
curl \
|
||||
gnupg \
|
||||
python3-dev \
|
||||
python3-pip \
|
||||
python3-wheel \
|
||||
build-essential \
|
||||
# Chrome dependencies - comprehensive list
|
||||
fonts-liberation \
|
||||
libasound2 \
|
||||
libatk-bridge2.0-0 \
|
||||
libdrm2 \
|
||||
libxcomposite1 \
|
||||
libxdamage1 \
|
||||
libxrandr2 \
|
||||
libgbm1 \
|
||||
libxss1 \
|
||||
libnss3 \
|
||||
libnspr4 \
|
||||
libxshmfence1 \
|
||||
libgconf-2-4 \
|
||||
libxfixes3 \
|
||||
libxinerama1 \
|
||||
libgtk-3-0 \
|
||||
libgdk-pixbuf2.0-0 \
|
||||
libatspi2.0-0 \
|
||||
libdrm2 \
|
||||
libxkbcommon0 \
|
||||
libepoxy0 \
|
||||
libgtk-3-0 \
|
||||
libharfbuzz0b \
|
||||
libegl1-mesa \
|
||||
libgles2-mesa \
|
||||
# Virtual display for headless operation
|
||||
xvfb \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN pip3 install --upgrade pip setuptools wheel && \
|
||||
pip3 install selenium
|
||||
|
||||
RUN chmod +x /opt/chrome/chrome
|
||||
# Install dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy application code
|
||||
COPY api.py .
|
||||
COPY chrome_bundle/ ./chrome_bundle/
|
||||
COPY sources/ ./sources/
|
||||
COPY prompts/ ./prompts/
|
||||
COPY crx/ crx/
|
||||
@@ -40,6 +59,28 @@ COPY llm_router/ llm_router/
|
||||
COPY .env .
|
||||
COPY config.ini .
|
||||
|
||||
# Install Chrome and ChromeDriver from chrome-for-testing
|
||||
RUN wget -O chrome-linux64.zip https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/linux64/chrome-linux64.zip && \
|
||||
wget -O chromedriver-linux64.zip https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/linux64/chromedriver-linux64.zip && \
|
||||
unzip chrome-linux64.zip && \
|
||||
unzip chromedriver-linux64.zip && \
|
||||
mkdir -p /opt/google && \
|
||||
ls -la && \
|
||||
mv chrome-linux64 /opt/google/chrome && \
|
||||
mv chromedriver-linux64/chromedriver /usr/local/bin/chromedriver && \
|
||||
chmod +x /opt/google/chrome/chrome && \
|
||||
chmod +x /usr/local/bin/chromedriver
|
||||
|
||||
RUN ln -s /opt/google/chrome/chrome /usr/local/bin/chrome
|
||||
|
||||
# Verify Chrome and ChromeDriver installation
|
||||
RUN google-chrome --version
|
||||
RUN chromedriver --version > /dev/null 2>&1
|
||||
|
||||
ENV CHROME_BIN=/opt/google/chrome/chrome
|
||||
ENV CHROMEDRIVER_PATH=/usr/local/bin/chromedriver
|
||||
ENV DISPLAY=:99
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8000
|
||||
|
||||
|
||||
@@ -559,3 +559,7 @@ We’re looking for developers to improve AgenticSeek! Check out open issues or
|
||||
> [antoineVIVIES](https://github.com/antoineVIVIES) | Taipei Time
|
||||
|
||||
> [steveh8758](https://github.com/steveh8758) | Taipei Time
|
||||
|
||||
## Special Thanks:
|
||||
|
||||
> [tcsenpai](https://github.com/tcsenpai) For dockerization of backend
|
||||
|
||||
@@ -22,6 +22,10 @@ from sources.utility import pretty_print
|
||||
from sources.logger import Logger
|
||||
from sources.schemas import QueryRequest, QueryResponse
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
from celery import Celery
|
||||
|
||||
@@ -247,4 +251,9 @@ async def process_query(request: QueryRequest):
|
||||
interaction.save_session()
|
||||
|
||||
if __name__ == "__main__":
|
||||
envport = os.getenv("BACKEND_PORT")
|
||||
if envport:
|
||||
port = int(envport)
|
||||
else:
|
||||
port = 8000
|
||||
uvicorn.run(api, host="0.0.0.0", port=8000)
|
||||
+18
-3
@@ -31,7 +31,7 @@ services:
|
||||
volumes:
|
||||
- ./searxng:/etc/searxng:rw
|
||||
environment:
|
||||
- SEARXNG_BASE_URL=http://localhost:8080/
|
||||
- SEARXNG_BASE_URL=${SEARXNG_BASE_URL:-http://localhost:8080/}
|
||||
- SEARXNG_SECRET_KEY=$(openssl rand -hex 32)
|
||||
- UWSGI_WORKERS=4
|
||||
- UWSGI_THREADS=4
|
||||
@@ -62,13 +62,28 @@ services:
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- CHOKIDAR_USEPOLLING=true
|
||||
- BACKEND_URL=http://backend:8000
|
||||
- REACT_APP_BACKEND_URL=http://0.0.0.0:${BACKEND_PORT:-8000}
|
||||
networks:
|
||||
- agentic-seek-net
|
||||
|
||||
backend:
|
||||
container_name: backend
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.backend
|
||||
ports:
|
||||
- ${BACKEND_PORT:-8000}:${BACKEND_PORT:-8000}
|
||||
volumes:
|
||||
- ./:/app
|
||||
- ${WORK_DIR}:${WORK_DIR}
|
||||
command: python3 api.py
|
||||
environment:
|
||||
- SEARXNG_URL=http://localhost:8080
|
||||
- WORK_DIR=${WORK_DIR}
|
||||
network_mode: "host"
|
||||
|
||||
# NOTE: backend service is not working yet due to issue with chromedriver on docker.
|
||||
# Therefore backend is run on host machine.
|
||||
# Open to pull requests to fix this.
|
||||
|
||||
#backend:
|
||||
# container_name: backend
|
||||
|
||||
@@ -4,6 +4,8 @@ import axios from 'axios';
|
||||
import './App.css';
|
||||
import { colors } from './colors';
|
||||
|
||||
const BACKEND_URL = process.env.REACT_APP_BACKEND_URL || 'http://0.0.0.0:8000';
|
||||
|
||||
function App() {
|
||||
const [query, setQuery] = useState('');
|
||||
const [messages, setMessages] = useState([]);
|
||||
@@ -27,7 +29,7 @@ function App() {
|
||||
|
||||
const checkHealth = async () => {
|
||||
try {
|
||||
await axios.get('http://127.0.0.1:8000/health');
|
||||
await axios.get(`${BACKEND_URL}/health`);
|
||||
setIsOnline(true);
|
||||
console.log('System is online');
|
||||
} catch {
|
||||
@@ -39,7 +41,7 @@ function App() {
|
||||
const fetchScreenshot = async () => {
|
||||
try {
|
||||
const timestamp = new Date().getTime();
|
||||
const res = await axios.get(`http://127.0.0.1:8000/screenshots/updated_screen.png?timestamp=${timestamp}`, {
|
||||
const res = await axios.get(`${BACKEND_URL}/screenshots/updated_screen.png?timestamp=${timestamp}`, {
|
||||
responseType: 'blob'
|
||||
});
|
||||
console.log('Screenshot fetched successfully');
|
||||
@@ -90,7 +92,7 @@ function App() {
|
||||
|
||||
const fetchLatestAnswer = async () => {
|
||||
try {
|
||||
const res = await axios.get('http://127.0.0.1:8000/latest_answer');
|
||||
const res = await axios.get(`${BACKEND_URL}/latest_answer`);
|
||||
const data = res.data;
|
||||
|
||||
updateData(data);
|
||||
@@ -141,7 +143,7 @@ function App() {
|
||||
setIsLoading(false);
|
||||
setError(null);
|
||||
try {
|
||||
const res = await axios.get('http://127.0.0.1:8000/stop');
|
||||
const res = await axios.get(`${BACKEND_URL}/stop`);
|
||||
setStatus("Requesting stop...");
|
||||
} catch (err) {
|
||||
console.error('Error stopping the agent:', err);
|
||||
@@ -162,7 +164,7 @@ function App() {
|
||||
try {
|
||||
console.log('Sending query:', query);
|
||||
setQuery('waiting for response...');
|
||||
const res = await axios.post('http://127.0.0.1:8000/query', {
|
||||
const res = await axios.post(`${BACKEND_URL}/query`, {
|
||||
query,
|
||||
tts_enabled: false
|
||||
});
|
||||
|
||||
@@ -41,6 +41,7 @@ fake_useragent>=2.1.0
|
||||
selenium_stealth>=1.0.6
|
||||
undetected-chromedriver>=3.5.5
|
||||
sentencepiece>=0.2.0
|
||||
python-dotenv>=1.0.0
|
||||
tqdm>4
|
||||
openai
|
||||
sniffio
|
||||
|
||||
+13
-1
@@ -42,7 +42,14 @@ def get_chrome_path() -> str:
|
||||
paths = ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
||||
"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta"]
|
||||
else: # Linux
|
||||
paths = ["/usr/bin/google-chrome", "/usr/bin/chromium-browser", "/usr/bin/chromium", "/opt/chrome/chrome", "/usr/local/bin/chrome"]
|
||||
paths = ["/usr/bin/google-chrome",
|
||||
"/usr/bin/chromium-browser",
|
||||
"/usr/bin/chromium",
|
||||
"/opt/chrome/chrome",
|
||||
"opt/google/chrome/chrome",
|
||||
"/usr/local/bin/chrome",
|
||||
#"/app/chrome_bundle/chrome136/chrome-linux64"
|
||||
]
|
||||
|
||||
for path in paths:
|
||||
if os.path.exists(path) and os.access(path, os.X_OK):
|
||||
@@ -73,8 +80,13 @@ def install_chromedriver() -> str:
|
||||
Install the ChromeDriver if not already installed. Return the path.
|
||||
"""
|
||||
chromedriver_path = shutil.which("chromedriver")
|
||||
#if not chromedriver_path:
|
||||
# if os.path.exists("/app/chrome_bundle/chrome136/chromedriver"):
|
||||
# print("Using bundled ChromeDriver from /app/chrome_bundle/chrome136/chromedriver")
|
||||
# chromedriver_path = "/app/chrome_bundle/chrome136/chromedriver"
|
||||
if not chromedriver_path:
|
||||
try:
|
||||
print("ChromeDriver not found, attempting to install automatically...")
|
||||
chromedriver_path = chromedriver_autoinstaller.install()
|
||||
except Exception as e:
|
||||
raise FileNotFoundError(
|
||||
|
||||
+49
-1
@@ -1,5 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
source .env
|
||||
|
||||
command_exists() {
|
||||
command -v "$1" &> /dev/null
|
||||
}
|
||||
@@ -60,12 +62,58 @@ if [ ! -f "docker-compose.yml" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# start docker compose for searxng, redis, frontend services
|
||||
# Download and extract Chrome bundle if not present
|
||||
echo "Checking Chrome bundle..."
|
||||
if [ ! -d "chrome_bundle/chrome136" ]; then
|
||||
echo "Chrome bundle not found. Downloading..."
|
||||
mkdir -p chrome_bundle
|
||||
curl -L https://github.com/tcsenpai/agenticSeek/releases/download/utility/chrome136.zip -o /tmp/chrome136.zip
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to download Chrome bundle"
|
||||
exit 1
|
||||
fi
|
||||
unzip -q /tmp/chrome136.zip -d chrome_bundle/
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to extract Chrome bundle"
|
||||
exit 1
|
||||
fi
|
||||
rm /tmp/chrome136.zip
|
||||
echo "Chrome bundle downloaded and extracted successfully"
|
||||
else
|
||||
echo "Chrome bundle already exists"
|
||||
fi
|
||||
|
||||
# Stop all running containers to ensure a clean state
|
||||
echo "Warning: stopping all docker containers (t-4 seconds)..."
|
||||
sleep 4
|
||||
docker stop $(docker ps -a -q)
|
||||
echo "All containers stopped"
|
||||
|
||||
# First start backend and wait for it to be healthy
|
||||
echo "Starting backend service..."
|
||||
if ! $COMPOSE_CMD up -d backend; then
|
||||
echo "Error: Failed to start backend container."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Wait for backend to be healthy (check if it's running and not restarting)
|
||||
echo "Waiting for backend to be ready..."
|
||||
for i in {1..30}; do
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' backend)" = "true" ] && \
|
||||
[ "$(docker inspect -f '{{.State.Restarting}}' backend)" = "false" ]; then
|
||||
echo "backend is ready!"
|
||||
break
|
||||
fi
|
||||
if [ $i -eq 30 ]; then
|
||||
echo "Error: backend failed to start properly after 30 seconds"
|
||||
$COMPOSE_CMD logs backend
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# start remaining services for searxng, redis, frontend services
|
||||
|
||||
if ! $COMPOSE_CMD up; then
|
||||
echo "Error: Failed to start containers. Check Docker logs with '$COMPOSE_CMD logs'."
|
||||
echo "Possible fixes: Run with sudo or ensure port 8080 is free."
|
||||
|
||||
Reference in New Issue
Block a user