mirror of
https://github.com/jaypyles/Scraperr.git
synced 2025-12-15 20:26:02 +00:00
wip: separate frontend from backend
This commit is contained in:
20
.github/workflows/docker-image.yml
vendored
20
.github/workflows/docker-image.yml
vendored
@@ -2,25 +2,35 @@ name: ci
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ["master"]
|
branches: ["master"]
|
||||||
# pull_request:
|
|
||||||
# branches: ["master"]
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Build and push
|
|
||||||
|
- name: Build and push frontend
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./docker/frontend/Dockerfile
|
||||||
push: true
|
push: true
|
||||||
tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{secrets.DOCKERHUB_REPO}}:latest
|
tags: ${{ secrets.DOCKERHUB_USERNAME }}/{{ DOCKERHUB_REPO }}:latest # Tag for the first image
|
||||||
|
|
||||||
|
- name: Build and push api
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./docker/api/Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: ${{ secrets.DOCKERHUB_USERNAME }}/scraperr_api:latest # Tag for the second image
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -185,3 +185,4 @@ cython_debug/
|
|||||||
.pdm-python
|
.pdm-python
|
||||||
.next
|
.next
|
||||||
postgres_data
|
postgres_data
|
||||||
|
.vscode
|
||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"python.languageServer": "None"
|
|
||||||
}
|
|
||||||
@@ -186,7 +186,7 @@ async def delete(delete_scrape_jobs: DeleteScrapeJobs):
|
|||||||
|
|
||||||
@app.get("/api/logs")
|
@app.get("/api/logs")
|
||||||
async def get_own_logs():
|
async def get_own_logs():
|
||||||
container_id = "scraperr"
|
container_id = "scraperr_api"
|
||||||
try:
|
try:
|
||||||
container = client.containers.get(container_id)
|
container = client.containers.get(container_id)
|
||||||
log_stream = container.logs(stream=True, follow=True)
|
log_stream = container.logs(stream=True, follow=True)
|
||||||
|
|||||||
@@ -69,8 +69,7 @@ def create_driver():
|
|||||||
chrome_options.add_argument("--disable-dev-shm-usage")
|
chrome_options.add_argument("--disable-dev-shm-usage")
|
||||||
chrome_options.add_argument(f"user-agent={ua.random}")
|
chrome_options.add_argument(f"user-agent={ua.random}")
|
||||||
|
|
||||||
service = Service(ChromeDriverManager().install())
|
return webdriver.Chrome(options=chrome_options)
|
||||||
return webdriver.Chrome(options=chrome_options, service=service)
|
|
||||||
|
|
||||||
|
|
||||||
async def make_site_request(
|
async def make_site_request(
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ services:
|
|||||||
scraperr:
|
scraperr:
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
- "traefik.http.routers.frontend.rule=Host(`${HOSTNAME_DEV}`)"
|
- "traefik.http.routers.scraperr.rule=Host(`${HOSTNAME_DEV}`)"
|
||||||
- "traefik.http.routers.frontend.entrypoints=web"
|
- "traefik.http.routers.scraperr.entrypoints=web"
|
||||||
- "traefik.http.services.frontend.loadbalancer.server.port=8000"
|
- "traefik.http.services.scraperr.loadbalancer.server.port=3000"
|
||||||
- "traefik.http.routers.frontend.tls=false"
|
- "traefik.http.routers.scraperr.tls=false"
|
||||||
volumes:
|
volumes:
|
||||||
- "$PWD/dist:/project/dist"
|
- "$PWD/dist:/project/dist"
|
||||||
|
- "$PWD/src:/project/src"
|
||||||
- "$PWD/api/backend:/project/api/backend"
|
- "$PWD/api/backend:/project/api/backend"
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "3000:3000"
|
||||||
|
|||||||
@@ -1,24 +1,39 @@
|
|||||||
services:
|
services:
|
||||||
scraperr:
|
scraperr:
|
||||||
image: jpyles0524/scraperr:latest
|
image: jpyles0524/scraperr:latest
|
||||||
init: True
|
|
||||||
build:
|
build:
|
||||||
context: ./
|
context: .
|
||||||
|
dockerfile: docker/frontend/Dockerfile
|
||||||
container_name: scraperr
|
container_name: scraperr
|
||||||
ports:
|
env_file:
|
||||||
- 9000:8000
|
- ./.env
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.scraperr.rule=Host(`${HOSTNAME}`)"
|
||||||
|
- "traefik.http.routers.scraperr.entrypoints=web" # websecure if using https
|
||||||
|
- "traefik.http.services.scraperr.loadbalancer.server.port=3000"
|
||||||
|
networks:
|
||||||
|
- web
|
||||||
|
|
||||||
|
scraperr_api:
|
||||||
|
init: True
|
||||||
|
image: jpyles0524/scraperr_api:latest
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/api/Dockerfile
|
||||||
|
container_name: scraperr_api
|
||||||
env_file:
|
env_file:
|
||||||
- ./.env
|
- ./.env
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
- "traefik.http.routers.frontend.rule=Host(`${HOSTNAME}`)"
|
- "traefik.http.routers.scraperr_api.rule=Host(`scraperr_api.${HOSTNAME}`)"
|
||||||
- "traefik.http.routers.frontend.entrypoints=web" # websecure if using https
|
- "traefik.http.routers.scraperr_api.entrypoints=web" # websecure if using https
|
||||||
- "traefik.http.services.frontend.loadbalancer.server.port=8000"
|
- "traefik.http.services.scraperr_api.loadbalancer.server.port=8000"
|
||||||
# - "traefik.http.routers.frontend.tls=true"
|
|
||||||
networks:
|
networks:
|
||||||
- web
|
- web
|
||||||
|
|
||||||
traefik:
|
traefik:
|
||||||
image: traefik:latest
|
image: traefik:latest
|
||||||
container_name: traefik
|
container_name: traefik
|
||||||
@@ -26,15 +41,11 @@ services:
|
|||||||
- "--providers.docker=true"
|
- "--providers.docker=true"
|
||||||
- "--entrypoints.web.address=:80"
|
- "--entrypoints.web.address=:80"
|
||||||
- "--entrypoints.websecure.address=:443"
|
- "--entrypoints.websecure.address=:443"
|
||||||
# - "--providers.file.filename=/etc/traefik/dynamic_conf.yaml"
|
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 80:80
|
||||||
- 443:443
|
- 443:443
|
||||||
volumes:
|
volumes:
|
||||||
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
- /var/run/docker.sock:/var/run/docker.sock:ro"
|
||||||
# - "./dynamic_conf.yaml:/etc/traefik/dynamic_conf.yaml"
|
|
||||||
# - "/etc/letsencrypt/live/domain/fullchain.pem:/etc/certs/ssl-cert.pem"
|
|
||||||
# - "/etc/letsencrypt/live/domain/privkey.pem:/etc/certs/ssl-cert.key"
|
|
||||||
networks:
|
networks:
|
||||||
- web
|
- web
|
||||||
mongo:
|
mongo:
|
||||||
@@ -46,5 +57,6 @@ services:
|
|||||||
MONGO_INITDB_ROOT_PASSWORD: example
|
MONGO_INITDB_ROOT_PASSWORD: example
|
||||||
networks:
|
networks:
|
||||||
- web
|
- web
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
web:
|
web:
|
||||||
|
|||||||
@@ -51,4 +51,3 @@ EXPOSE 8000
|
|||||||
WORKDIR /project/
|
WORKDIR /project/
|
||||||
|
|
||||||
CMD [ "supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf" ]
|
CMD [ "supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf" ]
|
||||||
|
|
||||||
19
docker/frontend/Dockerfile
Normal file
19
docker/frontend/Dockerfile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Build next dependencies
|
||||||
|
FROM node:latest
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY public /app/public
|
||||||
|
COPY src /app/src
|
||||||
|
COPY tsconfig.json /app/tsconfig.json
|
||||||
|
COPY tailwind.config.js /app/tailwind.config.js
|
||||||
|
COPY next.config.mjs /app/next.config.mjs
|
||||||
|
COPY postcss.config.js /app/postcss.config.js
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
CMD [ "npm", "run", "start" ]
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
|
import dotenv from "dotenv";
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
// output: "export",
|
|
||||||
distDir: "./dist",
|
distDir: "./dist",
|
||||||
images: { unoptimized: true },
|
images: { unoptimized: true },
|
||||||
env: {
|
env: {
|
||||||
DOMAIN: "http://localhost:8000",
|
DOMAIN: `${process.env.NEXT_PUBLIC_API_PATH}`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export const Constants = {
|
export const Constants = {
|
||||||
DOMAIN: process.env.DOMAIN,
|
// DOMAIN: process.env.NEXT_PUBLIC_API_PATH,
|
||||||
|
DOMAIN: "http://scraperr_api.localhost",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { Container, IconButton } from "@mui/material";
|
import { Container, IconButton } from "@mui/material";
|
||||||
import { ArrowUpward, ArrowDownward } from "@mui/icons-material";
|
import { ArrowUpward, ArrowDownward } from "@mui/icons-material";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import { Constants } from "../lib";
|
||||||
|
|
||||||
const Logs = () => {
|
const Logs = () => {
|
||||||
const [logs, setLogs] = useState("");
|
const [logs, setLogs] = useState("");
|
||||||
const logsContainerRef = useRef<HTMLDivElement>(null);
|
const logsContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const eventSource = new EventSource("/api/logs");
|
const eventSource = new EventSource(`${Constants.DOMAIN}/api/logs`);
|
||||||
|
|
||||||
eventSource.onmessage = (event) => {
|
eventSource.onmessage = (event) => {
|
||||||
setLogs((prevLogs) => prevLogs + event.data + "\n");
|
setLogs((prevLogs) => prevLogs + event.data + "\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user