npv2k1 commited on
Commit
0c01d1e
·
1 Parent(s): f8136bb

Refactor Dockerfile and update screenshot capture: streamline Chrome and ChromeDriver installation, enhance memory settings, and improve cleanup process in the capture function.

Browse files
Files changed (3) hide show
  1. Dockerfile +38 -8
  2. pyproject.toml +1 -0
  3. src/modules/apps/__init__.py +26 -6
Dockerfile CHANGED
@@ -1,19 +1,49 @@
1
  # Use a Python image with uv pre-installed
2
  FROM ghcr.io/astral-sh/uv:python3.11-bookworm
3
 
4
- # Install Chrome and dependencies
 
5
  RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
6
  RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
7
- RUN apt-get -y update
8
- RUN apt-get install -y google-chrome-stable
9
-
10
- # install chromedriver
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  RUN apt-get install -yqq unzip
12
- RUN wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip
13
- RUN unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/
 
 
 
14
 
15
- # set display port to avoid crash
16
  ENV DISPLAY=:99
 
 
 
 
17
 
18
  # Create a non-root user
19
  RUN useradd -m -u 1000 appuser
 
1
  # Use a Python image with uv pre-installed
2
  FROM ghcr.io/astral-sh/uv:python3.11-bookworm
3
 
4
+ # Install Chrome and its dependencies
5
+ RUN apt-get -y update && apt-get install -y wget gnupg2
6
  RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
7
  RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
8
+ RUN apt-get -y update && apt-get install -y \
9
+ google-chrome-stable \
10
+ fonts-ipafont-gothic \
11
+ fonts-wqy-zenhei \
12
+ fonts-thai-tlwg \
13
+ fonts-kacst \
14
+ fonts-symbola \
15
+ fonts-noto \
16
+ fonts-freefont-ttf \
17
+ libxss1 \
18
+ libx11-xcb1 \
19
+ libxcomposite1 \
20
+ libxcursor1 \
21
+ libxdamage1 \
22
+ libxi6 \
23
+ libxtst6 \
24
+ libnss3 \
25
+ libcups2 \
26
+ libxrandr2 \
27
+ libasound2 \
28
+ libatk1.0-0 \
29
+ libatk-bridge2.0-0 \
30
+ libgtk-3-0 \
31
+ libgbm1
32
+
33
+ # Install chromedriver
34
  RUN apt-get install -yqq unzip
35
+ RUN CHROMEDRIVER_VERSION=$(curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE) && \
36
+ wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip && \
37
+ unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/ && \
38
+ chmod +x /usr/local/bin/chromedriver && \
39
+ rm /tmp/chromedriver.zip
40
 
41
+ # Set display port and shared memory settings
42
  ENV DISPLAY=:99
43
+ ENV DBUS_SESSION_BUS_ADDRESS=/dev/null
44
+
45
+ # Create a shared memory volume
46
+ VOLUME /dev/shm
47
 
48
  # Create a non-root user
49
  RUN useradd -m -u 1000 appuser
pyproject.toml CHANGED
@@ -11,6 +11,7 @@ dependencies = [
11
  "numpy>=2.2.3",
12
  "pytest>=8.3.4",
13
  "selenium>=4.29.0",
 
14
  ]
15
 
16
  [tool.black]
 
11
  "numpy>=2.2.3",
12
  "pytest>=8.3.4",
13
  "selenium>=4.29.0",
14
+ "psutil>=5.9.0",
15
  ]
16
 
17
  [tool.black]
src/modules/apps/__init__.py CHANGED
@@ -19,8 +19,9 @@ def capture_page(url: str, output_file: str = "screenshot.png"):
19
  :param output_file: The filename to save the screenshot.
20
  """
21
  options = Options()
 
22
  # Basic options
23
- options.add_argument('--headless')
24
  options.add_argument('--no-sandbox') # Required in Docker
25
  options.add_argument('--disable-dev-shm-usage') # Required in Docker
26
 
@@ -32,16 +33,24 @@ def capture_page(url: str, output_file: str = "screenshot.png"):
32
 
33
  # Resource configuration
34
  options.add_argument('--window-size=1920,1080')
35
- options.add_argument('--remote-debugging-port=9222') # Fix DevTools port issue
36
- options.add_argument('--disable-features=site-per-process') # Reduce memory usage
37
- options.add_argument('--memory-pressure-off') # Prevent memory-related crashes
 
 
 
 
 
38
 
39
  # Additional stability options
40
  options.add_argument('--ignore-certificate-errors')
41
- options.add_argument('--allow-insecure-localhost')
42
  options.add_argument('--disable-setuid-sandbox')
43
  options.add_argument('--disable-web-security')
44
 
 
 
 
 
45
  # Set up Chrome service with explicit path to chromedriver and logging
46
  service = Service(
47
  executable_path='/usr/local/bin/chromedriver',
@@ -83,7 +92,18 @@ def capture_page(url: str, output_file: str = "screenshot.png"):
83
  raise
84
  finally:
85
  print("Closing Chrome...")
86
- driver.quit()
 
 
 
 
 
 
 
 
 
 
 
87
 
88
  except Exception as e:
89
  print(f"Error initializing Chrome: {str(e)}")
 
19
  :param output_file: The filename to save the screenshot.
20
  """
21
  options = Options()
22
+
23
  # Basic options
24
+ options.add_argument('--headless=new') # New headless mode
25
  options.add_argument('--no-sandbox') # Required in Docker
26
  options.add_argument('--disable-dev-shm-usage') # Required in Docker
27
 
 
33
 
34
  # Resource configuration
35
  options.add_argument('--window-size=1920,1080')
36
+ options.add_argument('--disable-features=NetworkService,NetworkServiceInProcess')
37
+ options.add_argument('--disable-features=site-per-process')
38
+
39
+ # Memory and process settings
40
+ options.add_argument('--single-process') # Run in single process mode
41
+ options.add_argument('--memory-pressure-off')
42
+ options.add_argument('--disable-crash-reporter')
43
+ options.add_argument('--disable-breakpad') # Disable crash reporting
44
 
45
  # Additional stability options
46
  options.add_argument('--ignore-certificate-errors')
 
47
  options.add_argument('--disable-setuid-sandbox')
48
  options.add_argument('--disable-web-security')
49
 
50
+ # Set specific shared memory /dev/shm size (if needed)
51
+ options.add_argument('--disable-dev-shm-usage')
52
+ options.add_argument('--shm-size=2g')
53
+
54
  # Set up Chrome service with explicit path to chromedriver and logging
55
  service = Service(
56
  executable_path='/usr/local/bin/chromedriver',
 
92
  raise
93
  finally:
94
  print("Closing Chrome...")
95
+ try:
96
+ driver.close() # Close current window
97
+ driver.quit() # Quit browser completely
98
+ import psutil # For process cleanup
99
+ current_pid = os.getpid()
100
+ current_process = psutil.Process(current_pid)
101
+ children = current_process.children(recursive=True)
102
+ for child in children:
103
+ if 'chrome' in child.name().lower():
104
+ child.terminate()
105
+ except Exception as cleanup_error:
106
+ print(f"Error during cleanup: {cleanup_error}")
107
 
108
  except Exception as e:
109
  print(f"Error initializing Chrome: {str(e)}")