Skip to content

Commit 03913b3

Browse files
committed
2 parents 2250dba + c368d61 commit 03913b3

File tree

83 files changed

+10525
-1281
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+10525
-1281
lines changed

.github/workflows/docker-push.yml

Lines changed: 418 additions & 0 deletions
Large diffs are not rendered by default.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,5 @@ server_log.txt
5050

5151
#Cursor Rules
5252
.cursorrules
53-
CURSOR_RULES.md
53+
CURSOR_RULES.md
54+
/.history

Dockerfile

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
# Stage 1: Browser and build tools installation
2+
#FROM python:3.13.3-slim-bookworm AS install-browser
23
FROM python:3.11.4-slim-bullseye AS install-browser
34

45
# Install Chromium, Chromedriver, Firefox, Geckodriver, and build tools in one layer
56
RUN apt-get update \
67
&& apt-get install -y gnupg wget ca-certificates --no-install-recommends \
8+
&& ARCH=$(dpkg --print-architecture) \
79
&& wget -qO - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \
8-
&& echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list \
10+
&& echo "deb [arch=${ARCH}] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list \
911
&& apt-get update \
10-
&& apt-get install -y google-chrome-stable chromium-driver \
11-
&& google-chrome --version && chromedriver --version \
12+
&& apt-get install -y chromium chromium-driver \
13+
&& chromium --version && chromedriver --version \
1214
&& apt-get install -y --no-install-recommends firefox-esr build-essential \
13-
&& wget https://github.com/mozilla/geckodriver/releases/download/v0.33.0/geckodriver-v0.33.0-linux64.tar.gz \
14-
&& tar -xvzf geckodriver-v0.33.0-linux64.tar.gz \
15+
&& GECKO_ARCH=$(case ${ARCH} in amd64) echo "linux64" ;; arm64) echo "linux-aarch64" ;; *) echo "linux64" ;; esac) \
16+
&& wget https://github.com/mozilla/geckodriver/releases/download/v0.36.0/geckodriver-v0.36.0-${GECKO_ARCH}.tar.gz \
17+
&& tar -xvzf geckodriver-v0.36.0-${GECKO_ARCH}.tar.gz \
1518
&& chmod +x geckodriver \
1619
&& mv geckodriver /usr/local/bin/ \
17-
&& rm geckodriver-v0.33.0-linux64.tar.gz \
20+
&& rm geckodriver-v0.36.0-${GECKO_ARCH}.tar.gz \
1821
&& rm -rf /var/lib/apt/lists/* # Clean up apt lists to reduce image size
1922

2023
# Stage 2: Python dependencies installation
@@ -27,28 +30,35 @@ WORKDIR /usr/src/app
2730
COPY ./requirements.txt ./requirements.txt
2831
COPY ./multi_agents/requirements.txt ./multi_agents/requirements.txt
2932

30-
RUN pip install --no-cache-dir -r requirements.txt && \
31-
pip install --no-cache-dir -r multi_agents/requirements.txt
33+
RUN pip install --upgrade pip && \
34+
pip install --no-cache-dir -r requirements.txt --upgrade --prefer-binary && \
35+
pip install --no-cache-dir -r multi_agents/requirements.txt --upgrade --prefer-binary
3236

3337
# Stage 3: Final stage with non-root user and app
3438
FROM gpt-researcher-install AS gpt-researcher
3539

40+
# Basic server configuration
41+
ARG HOST=0.0.0.0
42+
ENV HOST=${HOST}
43+
ARG PORT=8000
44+
ENV PORT=${PORT}
45+
EXPOSE ${PORT}
46+
47+
# Uvicorn parameters used in CMD
48+
ARG WORKERS=1
49+
ENV WORKERS=${WORKERS}
50+
3651
# Create a non-root user for security
52+
# NOTE: Don't use this if you are relying on `_check_pkg` to pip install packages dynamically.
3753
RUN useradd -ms /bin/bash gpt-researcher && \
3854
chown -R gpt-researcher:gpt-researcher /usr/src/app && \
3955
# Add these lines to create and set permissions for outputs directory
4056
mkdir -p /usr/src/app/outputs && \
4157
chown -R gpt-researcher:gpt-researcher /usr/src/app/outputs && \
4258
chmod 777 /usr/src/app/outputs
43-
4459
USER gpt-researcher
4560
WORKDIR /usr/src/app
4661

4762
# Copy the rest of the application files with proper ownership
4863
COPY --chown=gpt-researcher:gpt-researcher ./ ./
49-
50-
# Expose the application's port
51-
EXPOSE 8000
52-
53-
# Define the default command to run the application
54-
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
64+
CMD uvicorn main:app --host ${HOST} --port ${PORT} --workers ${WORKERS}

Dockerfile.fullstack

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
########################################################################
2+
# Stage 1: Frontend build
3+
########################################################################
4+
FROM node:slim AS frontend-builder
5+
WORKDIR /app/frontend/nextjs
6+
7+
# Copy package files and install dependencies
8+
COPY frontend/nextjs/package.json frontend/nextjs/package-lock.json* ./
9+
RUN npm install --legacy-peer-deps
10+
11+
# Copy the rest of the frontend application and build it
12+
COPY frontend/nextjs/ ./
13+
RUN npm run build
14+
15+
########################################################################
16+
# Stage 2: Browser and backend build tools installation
17+
########################################################################
18+
FROM python:3.13.3-slim-bookworm AS install-browser
19+
20+
# Install Chromium, Chromedriver, Firefox, Geckodriver, and build tools in one layer
21+
RUN echo 'Acquire::Retries "3";' > /etc/apt/apt.conf.d/80-retries \
22+
&& echo 'Acquire::http::Timeout "60";' >> /etc/apt/apt.conf.d/80-retries \
23+
&& echo 'Acquire::https::Timeout "60";' >> /etc/apt/apt.conf.d/80-retries \
24+
&& echo 'Acquire::ftp::Timeout "60";' >> /etc/apt/apt.conf.d/80-retries \
25+
&& apt-get update \
26+
&& apt-get install -y gnupg wget ca-certificates --no-install-recommends \
27+
&& ARCH=$(dpkg --print-architecture) \
28+
&& if [ "$ARCH" = "arm64" ]; then \
29+
apt-get install -y chromium chromium-driver \
30+
&& chromium --version && chromedriver --version; \
31+
else \
32+
wget -qO - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \
33+
&& echo "deb [arch=${ARCH}] http://dl.google.com/linux/chrome/deb/ stable main" \
34+
> /etc/apt/sources.list.d/google-chrome.list \
35+
&& apt-get update \
36+
&& apt-get install -y google-chrome-stable; \
37+
fi \
38+
&& apt-get install -y --no-install-recommends firefox-esr build-essential \
39+
&& GECKO_ARCH=$(case ${ARCH} in amd64) echo "linux64" ;; arm64) echo "linux-aarch64" ;; *) echo "linux64" ;; esac) \
40+
&& wget https://github.com/mozilla/geckodriver/releases/download/v0.36.0/geckodriver-v0.36.0-${GECKO_ARCH}.tar.gz \
41+
&& tar -xvzf geckodriver-v0.36.0-${GECKO_ARCH}.tar.gz \
42+
&& chmod +x geckodriver \
43+
&& mv geckodriver /usr/local/bin/ \
44+
&& rm geckodriver-v0.36.0-${GECKO_ARCH}.tar.gz \
45+
&& rm -rf /var/lib/apt/lists/*
46+
47+
########################################################################
48+
# Stage 3: Python dependencies installation
49+
########################################################################
50+
FROM install-browser AS backend-builder
51+
WORKDIR /usr/src/app
52+
53+
ENV PIP_ROOT_USER_ACTION=ignore
54+
55+
COPY ./requirements.txt ./requirements.txt
56+
COPY ./multi_agents/requirements.txt ./multi_agents/requirements.txt
57+
58+
# Install Python packages with retry logic and timeout configuration
59+
RUN pip config set global.timeout 60 && \
60+
pip config set global.retries 3 && \
61+
pip install --upgrade pip && \
62+
pip install --no-cache-dir -r requirements.txt --upgrade --prefer-binary && \
63+
pip install --no-cache-dir -r multi_agents/requirements.txt --upgrade --prefer-binary
64+
65+
########################################################################
66+
# Stage 4: Final image with backend, frontend
67+
########################################################################
68+
FROM backend-builder AS final
69+
70+
WORKDIR /usr/src/app
71+
72+
# Install Node.js and supervisord with retry logic
73+
RUN apt-get update && \
74+
apt-get install -y curl supervisor nginx && \
75+
curl -fsSL --retry 3 --retry-delay 10 https://deb.nodesource.com/setup_20.x | bash - && \
76+
apt-get install -y nodejs && \
77+
rm -rf /var/lib/apt/lists/*
78+
79+
# Set backend server configuration
80+
ARG HOST=0.0.0.0
81+
ENV HOST=${HOST}
82+
83+
ARG PORT=8000
84+
ENV PORT=${PORT}
85+
EXPOSE ${PORT}
86+
87+
ARG NEXT_PORT=3000
88+
ENV NEXT_PORT=${NEXT_PORT}
89+
EXPOSE ${NEXT_PORT}
90+
91+
# Internal Next.js port (not exposed)
92+
ARG NEXT_INTERNAL_PORT=3001
93+
ENV NEXT_INTERNAL_PORT=${NEXT_INTERNAL_PORT}
94+
95+
# Copy application files
96+
COPY ./ ./
97+
98+
# Copy built frontend from the frontend-builder stage
99+
COPY --from=frontend-builder /app/frontend/nextjs/.next ./frontend/nextjs/.next
100+
COPY --from=frontend-builder /app/frontend/nextjs/node_modules ./frontend/nextjs/node_modules
101+
COPY --from=frontend-builder /app/frontend/nextjs/public ./frontend/nextjs/public
102+
COPY --from=frontend-builder /app/frontend/nextjs/package.json ./frontend/nextjs/package.json
103+
# Ensure next.config.mjs and other necessary files are present
104+
COPY --from=frontend-builder /app/frontend/nextjs/next.config.mjs ./frontend/nextjs/next.config.mjs
105+
106+
# Create nginx configuration
107+
RUN echo 'events {' > /etc/nginx/nginx.conf && \
108+
echo ' worker_connections 1024;' >> /etc/nginx/nginx.conf && \
109+
echo '}' >> /etc/nginx/nginx.conf && \
110+
echo '' >> /etc/nginx/nginx.conf && \
111+
echo 'http {' >> /etc/nginx/nginx.conf && \
112+
echo ' include /etc/nginx/mime.types;' >> /etc/nginx/nginx.conf && \
113+
echo ' default_type application/octet-stream;' >> /etc/nginx/nginx.conf && \
114+
echo '' >> /etc/nginx/nginx.conf && \
115+
echo ' # Logging' >> /etc/nginx/nginx.conf && \
116+
echo ' access_log /var/log/nginx/access.log;' >> /etc/nginx/nginx.conf && \
117+
echo ' error_log /var/log/nginx/error.log;' >> /etc/nginx/nginx.conf && \
118+
echo '' >> /etc/nginx/nginx.conf && \
119+
echo ' # Gzip compression' >> /etc/nginx/nginx.conf && \
120+
echo ' gzip on;' >> /etc/nginx/nginx.conf && \
121+
echo ' gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;' >> /etc/nginx/nginx.conf && \
122+
echo '' >> /etc/nginx/nginx.conf && \
123+
echo ' # WebSocket support' >> /etc/nginx/nginx.conf && \
124+
echo ' map $http_upgrade $connection_upgrade {' >> /etc/nginx/nginx.conf && \
125+
echo ' default upgrade;' >> /etc/nginx/nginx.conf && \
126+
echo ' '"'"''"'"' close;' >> /etc/nginx/nginx.conf && \
127+
echo ' }' >> /etc/nginx/nginx.conf && \
128+
echo '' >> /etc/nginx/nginx.conf && \
129+
echo ' server {' >> /etc/nginx/nginx.conf && \
130+
echo ' listen 3000;' >> /etc/nginx/nginx.conf && \
131+
echo ' server_name _;' >> /etc/nginx/nginx.conf && \
132+
echo '' >> /etc/nginx/nginx.conf && \
133+
echo ' # Proxy backend routes to FastAPI server' >> /etc/nginx/nginx.conf && \
134+
echo ' location /outputs {' >> /etc/nginx/nginx.conf && \
135+
echo ' proxy_pass http://127.0.0.1:8000;' >> /etc/nginx/nginx.conf && \
136+
echo ' proxy_set_header Host $host;' >> /etc/nginx/nginx.conf && \
137+
echo ' proxy_set_header X-Real-IP $remote_addr;' >> /etc/nginx/nginx.conf && \
138+
echo ' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;' >> /etc/nginx/nginx.conf && \
139+
echo ' proxy_set_header X-Forwarded-Proto $scheme;' >> /etc/nginx/nginx.conf && \
140+
echo ' }' >> /etc/nginx/nginx.conf && \
141+
echo '' >> /etc/nginx/nginx.conf && \
142+
echo ' location /reports {' >> /etc/nginx/nginx.conf && \
143+
echo ' proxy_pass http://127.0.0.1:8000;' >> /etc/nginx/nginx.conf && \
144+
echo ' proxy_set_header Host $host;' >> /etc/nginx/nginx.conf && \
145+
echo ' proxy_set_header X-Real-IP $remote_addr;' >> /etc/nginx/nginx.conf && \
146+
echo ' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;' >> /etc/nginx/nginx.conf && \
147+
echo ' proxy_set_header X-Forwarded-Proto $scheme;' >> /etc/nginx/nginx.conf && \
148+
echo ' }' >> /etc/nginx/nginx.conf && \
149+
echo '' >> /etc/nginx/nginx.conf && \
150+
echo ' location /ws {' >> /etc/nginx/nginx.conf && \
151+
echo ' proxy_pass http://127.0.0.1:8000;' >> /etc/nginx/nginx.conf && \
152+
echo ' proxy_http_version 1.1;' >> /etc/nginx/nginx.conf && \
153+
echo ' proxy_set_header Upgrade $http_upgrade;' >> /etc/nginx/nginx.conf && \
154+
echo ' proxy_set_header Connection $connection_upgrade;' >> /etc/nginx/nginx.conf && \
155+
echo ' proxy_set_header Host $host;' >> /etc/nginx/nginx.conf && \
156+
echo ' proxy_set_header X-Real-IP $remote_addr;' >> /etc/nginx/nginx.conf && \
157+
echo ' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;' >> /etc/nginx/nginx.conf && \
158+
echo ' proxy_set_header X-Forwarded-Proto $scheme;' >> /etc/nginx/nginx.conf && \
159+
echo ' }' >> /etc/nginx/nginx.conf && \
160+
echo '' >> /etc/nginx/nginx.conf && \
161+
echo ' # Proxy all other requests to Next.js' >> /etc/nginx/nginx.conf && \
162+
echo ' location / {' >> /etc/nginx/nginx.conf && \
163+
echo ' proxy_pass http://127.0.0.1:3001;' >> /etc/nginx/nginx.conf && \
164+
echo ' proxy_set_header Host $host;' >> /etc/nginx/nginx.conf && \
165+
echo ' proxy_set_header X-Real-IP $remote_addr;' >> /etc/nginx/nginx.conf && \
166+
echo ' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;' >> /etc/nginx/nginx.conf && \
167+
echo ' proxy_set_header X-Forwarded-Proto $scheme;' >> /etc/nginx/nginx.conf && \
168+
echo ' }' >> /etc/nginx/nginx.conf && \
169+
echo ' }' >> /etc/nginx/nginx.conf && \
170+
echo '}' >> /etc/nginx/nginx.conf
171+
172+
# Create supervisord configuration
173+
# stdout/stderr_maxbytes prevents log file rotation and ensures continuous output
174+
RUN echo '[supervisord]' > /etc/supervisor/conf.d/supervisord.conf && \
175+
echo 'nodaemon=true' >> /etc/supervisor/conf.d/supervisord.conf && \
176+
echo 'user=root' >> /etc/supervisor/conf.d/supervisord.conf && \
177+
echo 'logfile=/dev/stdout' >> /etc/supervisor/conf.d/supervisord.conf && \
178+
echo 'logfile_maxbytes=0' >> /etc/supervisor/conf.d/supervisord.conf && \
179+
echo '' >> /etc/supervisor/conf.d/supervisord.conf && \
180+
echo '[program:backend]' >> /etc/supervisor/conf.d/supervisord.conf && \
181+
echo 'command=uvicorn main:app --host %(ENV_HOST)s --port %(ENV_PORT)s' >> /etc/supervisor/conf.d/supervisord.conf && \
182+
echo 'directory=/usr/src/app' >> /etc/supervisor/conf.d/supervisord.conf && \
183+
echo 'autostart=true' >> /etc/supervisor/conf.d/supervisord.conf && \
184+
echo 'autorestart=true' >> /etc/supervisor/conf.d/supervisord.conf && \
185+
echo 'stdout_logfile=/dev/stdout' >> /etc/supervisor/conf.d/supervisord.conf && \
186+
echo 'stdout_logfile_maxbytes=0' >> /etc/supervisor/conf.d/supervisord.conf && \
187+
echo 'stderr_logfile=/dev/stderr' >> /etc/supervisor/conf.d/supervisord.conf && \
188+
echo 'stderr_logfile_maxbytes=0' >> /etc/supervisor/conf.d/supervisord.conf && \
189+
echo '' >> /etc/supervisor/conf.d/supervisord.conf && \
190+
echo '[program:frontend]' >> /etc/supervisor/conf.d/supervisord.conf && \
191+
echo 'command=npm run start -- -p %(ENV_NEXT_INTERNAL_PORT)s' >> /etc/supervisor/conf.d/supervisord.conf && \
192+
echo 'directory=/usr/src/app/frontend/nextjs' >> /etc/supervisor/conf.d/supervisord.conf && \
193+
echo 'autostart=true' >> /etc/supervisor/conf.d/supervisord.conf && \
194+
echo 'autorestart=true' >> /etc/supervisor/conf.d/supervisord.conf && \
195+
echo 'stdout_logfile=/dev/stdout' >> /etc/supervisor/conf.d/supervisord.conf && \
196+
echo 'stdout_logfile_maxbytes=0' >> /etc/supervisor/conf.d/supervisord.conf && \
197+
echo 'stderr_logfile=/dev/stderr' >> /etc/supervisor/conf.d/supervisord.conf && \
198+
echo 'stderr_logfile_maxbytes=0' >> /etc/supervisor/conf.d/supervisord.conf && \
199+
echo '' >> /etc/supervisor/conf.d/supervisord.conf && \
200+
echo '[program:nginx]' >> /etc/supervisor/conf.d/supervisord.conf && \
201+
echo 'command=nginx -g "daemon off;"' >> /etc/supervisor/conf.d/supervisord.conf && \
202+
echo 'autostart=true' >> /etc/supervisor/conf.d/supervisord.conf && \
203+
echo 'autorestart=true' >> /etc/supervisor/conf.d/supervisord.conf && \
204+
echo 'stdout_logfile=/dev/stdout' >> /etc/supervisor/conf.d/supervisord.conf && \
205+
echo 'stdout_logfile_maxbytes=0' >> /etc/supervisor/conf.d/supervisord.conf && \
206+
echo 'stderr_logfile=/dev/stderr' >> /etc/supervisor/conf.d/supervisord.conf && \
207+
echo 'stderr_logfile_maxbytes=0' >> /etc/supervisor/conf.d/supervisord.conf
208+
209+
# Start supervisord to manage both services
210+
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

0 commit comments

Comments
 (0)