Deep-sea commited on
Commit
3529a52
·
verified ·
1 Parent(s): 6791030

我承认豆包就是个猴子

Browse files
Files changed (1) hide show
  1. Dockerfile +157 -294
Dockerfile CHANGED
@@ -1,351 +1,214 @@
1
- FROM gitlab/gitlab-ce:17.6.0-ce.0
 
2
 
3
- # 以 root 用户执行系统级操作
4
  USER root
5
 
6
- # 安装 Python、pip 及所需依赖库
7
  RUN apt-get update && \
8
- apt-get install -y python3 python3-pip git && \
9
- pip3 install --break-system-packages --upgrade pip
10
-
11
- # 安装 Python
12
- RUN pip3 install --break-system-packages watchdog huggingface_hub aiohttp pytz
13
-
14
- # 创建数据目录并设置权限(适配 GitLab 目录规范)
15
- RUN mkdir -p /data/gitlab /data/hf_sync && \
16
  chown -R git:git /data && \
17
  chmod -R 770 /data
18
 
19
- # 复制拉取 Hugging Face 数据集的脚本移除 Gitea 专属的跳过初始化逻辑
20
  COPY --chown=root:root <<'EOF' /pullhf.py
21
  import os
22
  import shutil
23
- from huggingface_hub import snapshot_download
24
- import logging
25
  import base64
 
26
  from datetime import datetime
27
  import pytz
 
28
 
29
- # 配置日志,使用北京时间
30
  beijing_tz = pytz.timezone('Asia/Shanghai')
31
  logging.basicConfig(
32
  level=logging.INFO,
33
- format='%(asctime)s - %(levelname)s - %(message)s',
34
- datefmt='%Y-%m-%d %H:%M:%S %Z'
35
  )
36
  logger = logging.getLogger(__name__)
37
 
38
- # 自定义日志格式化器以使用北京时间
39
- class BeijingTimeFormatter(logging.Formatter):
40
  def formatTime(self, record, datefmt=None):
41
  dt = datetime.fromtimestamp(record.created, tz=beijing_tz)
42
- if datefmt:
43
- return dt.strftime(datefmt)
44
- return dt.strftime("%Y-%m-%d %H:%M:%S %Z")
45
-
46
- # 应用自定义格式化器
47
- for handler in logging.getLogger().handlers:
48
- handler.setFormatter(BeijingTimeFormatter(
49
- fmt='%(asctime)s - %(levelname)s - %(message)s',
50
- datefmt='%Y-%m-%d %H:%M:%S %Z'
51
- ))
52
-
53
- def pull_from_hf_hub(repo_id, data_directory="/data/gitlab"):
54
- """从 Hugging Face Hub 数据集仓库拉取数据到 GitLab 数据目录"""
55
- # 硬编码的 base64 编码的 HF_TOKEN
56
- hf_token_encoded = "aGZfcXllTEJnUUtPb2FUbHBMZ0FuTGFGTmJPV2xjUUtJT0VycQ=="
57
- hf_token = base64.b64decode(hf_token_encoded).decode('utf-8')
58
-
59
- try:
60
- logger.info(f"HF_TOKEN value: {hf_token}")
61
- # 临时目录用于下载
62
- temp_dir = "/tmp/hf_download"
63
- if os.path.exists(temp_dir):
64
- shutil.rmtree(temp_dir, ignore_errors=True)
65
-
66
- # 下载 Hugging Face 数据集
67
- logger.info(f"正在从 Hugging Face Hub 拉取数据集: {repo_id}")
68
- snapshot_download(
69
- repo_id=repo_id,
70
- repo_type="dataset",
71
- local_dir=temp_dir,
72
- token=hf_token,
73
- ignore_patterns=["*.tmp", "*.log", "*.temp", ".git/*"]
74
- )
75
-
76
- # 清空现有的目标目录
77
- if os.path.exists(data_directory):
78
- logger.info(f"正在清空现有目录: {data_directory}")
79
- shutil.rmtree(data_directory, ignore_errors=True)
80
-
81
- # 创建目录并移动下载的内容
82
- os.makedirs(data_directory, exist_ok=True)
83
- for item in os.listdir(temp_dir):
84
- src = os.path.join(temp_dir, item)
85
- dst = os.path.join(data_directory, item)
86
- shutil.move(src, dst)
87
-
88
- # 清理临时目录
89
  shutil.rmtree(temp_dir, ignore_errors=True)
90
-
91
- # 修复权限:确保目录为 git:git 所有
92
- logger.info("修复数据目录权限")
93
- os.system("chown -R git:git /data")
94
- os.system("chmod -R 770 /data")
95
-
96
- # 调试:列出目录结构
97
- logger.info("调试:列出 /data 目录结构和权限")
98
- os.system("ls -la /data")
99
- os.system("ls -la /data/gitlab 2>/dev/null || echo '/data/gitlab 不存在'")
100
-
101
- logger.info(f"成功从 Hugging Face Hub 拉取数据到 {data_directory}")
102
- return True
103
-
104
- except Exception as e:
105
- logger.error(f"拉取 Hugging Face 数据集失败: {e}")
106
- return False
 
 
 
 
 
 
107
 
108
  if __name__ == "__main__":
109
- repo_id = os.getenv("REPO_ID", "02engine/02gitea")
110
- if not pull_from_hf_hub(repo_id):
111
- logger.error("拉取数据集失败,退出")
112
- exit(1)
113
  EOF
114
 
115
- # 复制目录监控及上传 Hugging Face 的脚本移除 Gitea 相关逻辑
116
  COPY --chown=git:git <<'EOF' /uploadhf.py
117
  import os
118
  import time
 
119
  import logging
 
120
  import threading
121
  import subprocess
122
- import asyncio
123
- import aiohttp
124
  from pathlib import Path
125
  from watchdog.observers import Observer
126
  from watchdog.events import FileSystemEventHandler
127
- from huggingface_hub import HfApi
128
- from huggingface_hub import utils
129
- import base64
130
- from datetime import datetime
131
  import pytz
 
132
 
133
- # 全局禁用所有 Hugging Face 进度条
134
  utils.disable_progress_bars()
135
 
136
- # 配置日志,使用北京时间
137
  beijing_tz = pytz.timezone('Asia/Shanghai')
138
- logging.basicConfig(
139
- level=logging.INFO,
140
- format='%(asctime)s - %(levelname)s - %(message)s',
141
- datefmt='%Y-%m-%d %H:%M:%S %Z'
142
- )
143
  logger = logging.getLogger(__name__)
144
 
145
- # 自定义日志格式化器
146
- class BeijingTimeFormatter(logging.Formatter):
147
  def formatTime(self, record, datefmt=None):
148
  dt = datetime.fromtimestamp(record.created, tz=beijing_tz)
149
- if datefmt:
150
- return dt.strftime(datefmt)
151
- return dt.strftime("%Y-%m-%d %H:%M:%S %Z")
152
-
153
- for handler in logging.getLogger().handlers:
154
- handler.setFormatter(BeijingTimeFormatter(
155
- fmt='%(asctime)s - %(levelname)s - %(message)s',
156
- datefmt='%Y-%m-%d %H:%M:%S %Z'
157
- ))
158
-
159
- class DataDirectoryHandler(FileSystemEventHandler):
160
- def __init__(self, repo_id, hf_token, data_directory="/data/gitlab"):
161
  self.repo_id = repo_id
162
- self.hf_token = hf_token
163
- self.data_directory = data_directory
164
- self.api = HfApi(token=hf_token)
165
- self.last_commit_time = 0
166
- self.commit_delay = 1
167
- self.pending_changes = []
168
- logger.info(f"初始化监控器,监控目录: {data_directory},目标仓库: {repo_id}")
169
-
170
  def on_any_event(self, event):
171
- if event.is_directory:
172
  return
173
- self.pending_changes.append((event.event_type, event.src_path))
174
- self.schedule_commit(f"文件{event.event_type}")
175
-
176
- def schedule_commit(self, change_type):
177
- current_time = time.time()
178
- if current_time - self.last_commit_time > self.commit_delay:
179
- self.last_commit_time = current_time
180
- asyncio.run(self.commit_changes(change_type))
181
-
182
- async def commit_changes(self, change_type):
183
- max_retries = 3
184
- retry_delay = 5
185
- change_summary = f"{change_type} ({len(self.pending_changes)} 文件)"
186
- self.pending_changes = []
187
-
188
- for attempt in range(max_retries):
189
- try:
190
- commit_message = f"自动提交: {change_summary} - {time.strftime('%Y-%m-%d %H:%M:%S')}"
191
- logger.info(f"开始上传: {commit_message}")
192
-
193
- await asyncio.to_thread(
194
- self.api.upload_folder,
195
- folder_path=self.data_directory,
196
- repo_id=self.repo_id,
197
- repo_type="dataset",
198
- commit_message=commit_message,
199
- ignore_patterns=["*.tmp", "*.log", "*.temp", ".git/*"]
200
- )
201
-
202
- logger.info(f"成功提交变更到 Hugging Face Hub: {commit_message}")
203
- return
204
-
205
- except Exception as e:
206
- logger.error(f"提交失败 (尝试 {attempt + 1}/{max_retries}): {e}")
207
- if attempt < max_retries - 1:
208
- logger.info(f"将在 {retry_delay} 秒后重试...")
209
- await asyncio.sleep(retry_delay)
210
-
211
- logger.error(f"达到最大重试次数,上传失败")
212
-
213
- def start_directory_monitoring(data_directory="/data/gitlab", repo_id=None, hf_token=None):
214
- if not hf_token:
215
- hf_token_encoded = "aGZfcXllTEJnUUtPb2FUbHBMZ0FuTGFGTmJPV2xjUUtJT0VycQ=="
216
- hf_token = base64.b64decode(hf_token_encoded).decode('utf-8')
217
- logger.info(f"HF_TOKEN 已解码(长度: {len(hf_token)})")
218
-
219
- if not repo_id:
220
- raise ValueError("必须提供 repo_id 参数")
221
-
222
- if not os.path.exists(data_directory):
223
- logger.warning(f"监控目录 {data_directory} 不存在,正在创建...")
224
- os.makedirs(data_directory, exist_ok=True)
225
-
226
- event_handler = DataDirectoryHandler(
227
- repo_id=repo_id,
228
- hf_token=hf_token,
229
- data_directory=data_directory
230
- )
231
-
232
- observer = Observer()
233
- observer.schedule(event_handler, data_directory, recursive=True)
234
- observer.start()
235
- logger.info(f"目录监控服务已启动: {data_directory}")
236
-
237
- return observer
238
 
239
- def start_gitlab_server():
240
- def run_gitlab():
241
- try:
242
- gitlab_process = subprocess.Popen(
243
- ['/assets/wrapper'],
244
- stdout=subprocess.PIPE,
245
- stderr=subprocess.PIPE,
246
- universal_newlines=True
247
- )
248
- logger.info("GitLab 服务已启动")
249
-
250
- while True:
251
- output = gitlab_process.stdout.readline()
252
- if output == '' and gitlab_process.poll() is not None:
253
- break
254
- if output:
255
- logger.info(f"GitLab: {output.strip()}")
256
-
257
- return_code = gitlab_process.poll()
258
- if return_code != 0:
259
- error_output = gitlab_process.stderr.read()
260
- logger.error(f"GitLab 服务器异常退出,返回码: {return_code}")
261
- logger.error(f"错误信息: {error_output}")
262
- else:
263
- logger.info("GitLab 服务器正常退出")
264
-
265
- except Exception as e:
266
- logger.error(f"启动 GitLab 服务器时发生错误: {e}")
267
-
268
- gitlab_thread = threading.Thread(target=run_gitlab)
269
- gitlab_thread.daemon = True
270
- gitlab_thread.start()
271
-
272
- return gitlab_thread
273
-
274
- async def main():
275
- CONFIG = {
276
- "data_directory": "/data/gitlab",
277
- "repo_id": os.getenv("REPO_ID", "02engine/02gitea"),
278
- "hf_token": os.getenv('HF_TOKEN'),
279
- }
280
-
281
- max_retries = 5
282
- retry_count = 0
283
-
284
- while retry_count < max_retries:
285
  try:
286
- logger.info(f"启动集成服务 (尝试 {retry_count + 1}/{max_retries})...")
287
-
288
- logger.info("运行 pullhf.py 拉取最新数据集")
289
- pull_result = subprocess.run(["python3", "/pullhf.py"], check=True)
290
- if pull_result.returncode != 0:
291
- logger.error("pullhf.py 执行失败,退出")
292
- exit(1)
293
-
294
- gitlab_thread = start_gitlab_server()
295
- observer = start_directory_monitoring(
296
- data_directory=CONFIG["data_directory"],
297
- repo_id=CONFIG["repo_id"],
298
- hf_token=CONFIG["hf_token"]
299
  )
300
-
301
- logger.info("所有服务已启动完成!")
302
- logger.info("目录监控: /data/gitlab to Hugging Face Hub")
303
- logger.info("GitLab 服务已启动,可通过对应端口访问")
304
- logger.info("按 Ctrl+C 停止所有服务")
305
-
306
- try:
307
- while True:
308
- await asyncio.sleep(1)
309
- except KeyboardInterrupt:
310
- logger.info("正在停止服务...")
311
- break
312
-
313
  except Exception as e:
314
- retry_count += 1
315
- logger.error(f"服务崩溃 (尝试 {retry_count}/{max_retries}): {e}")
316
- if retry_count < max_retries:
317
- logger.info(f"将在 5 秒后尝试重启...")
318
- await asyncio.sleep(5)
319
- else:
320
- logger.error(f"达到最大重试次数 ({max_retries}),退出")
321
- exit(1)
322
- finally:
323
- if 'observer' in locals():
324
- observer.stop()
325
- observer.join()
326
- logger.info("所有服务已停止")
 
 
 
 
 
 
327
 
328
  if __name__ == "__main__":
329
- asyncio.run(main())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  EOF
331
 
332
- # 配置 GitLab 环境变量(基础必要配置)
333
- ENV GITLAB_OMNIBUS_CONFIG="external_url 'https://deep-sea-02gitlab.hf.space'; \
334
- gitlab_rails['time_zone'] = 'Asia/Shanghai'; \
335
- gitlab_rails['db_adapter'] = 'postgresql'; \
336
- gitlab_rails['db_database'] = 'gitlabhq_production'; \
337
- gitlab_rails['db_username'] = 'gitlab'; \
338
- gitlab_rails['db_password'] = 'gitlabdbpass'; \
339
- gitlab_rails['db_host'] = 'localhost'; \
340
- gitlab_rails['db_port'] = 5432; \
341
- unicorn['port'] = 8080; \
342
- nginx['listen_port'] = 7860;"
343
-
344
- # 暴露 GitLab 服务端口(适配 Spaces 默认端口)
345
- EXPOSE 7860 22 8080
346
-
347
- # 切换到 git 用户
348
- USER git
349
-
350
- # 启动同步脚本并托管 GitLab 服务
351
  CMD ["python3", "/uploadhf.py"]
 
1
+ # ================ GitLab CE + HF 双向同步 + 调试清空模式 ================
2
+ FROM gitlab/gitlab-ce:17.5.2-ce.0
3
 
4
+ # ---------- 以 root 安装依赖 ----------
5
  USER root
6
 
 
7
  RUN apt-get update && \
8
+ apt-get install -y --no-install-recommends \
9
+ python3 python3-pip python3-venv git ca-certificates tzdata && \
10
+ pip3 install --break-system-packages --upgrade pip && \
11
+ pip3 install --break-system-packages watchdog huggingface_hub aiohttp pytz && \
12
+ rm -rf /var/lib/apt/lists/*
13
+
14
+ # ---------- 创建持久化目录 ----------
15
+ RUN mkdir -p /data/gitlab/config /data/gitlab/logs /data/gitlab/data && \
16
  chown -R git:git /data && \
17
  chmod -R 770 /data
18
 
19
+ # ===================== pullhf.py支持 CLEAR_DATA_ON_START 调试模式=====================
20
  COPY --chown=root:root <<'EOF' /pullhf.py
21
  import os
22
  import shutil
 
 
23
  import base64
24
+ import logging
25
  from datetime import datetime
26
  import pytz
27
+ from huggingface_hub import snapshot_download
28
 
 
29
  beijing_tz = pytz.timezone('Asia/Shanghai')
30
  logging.basicConfig(
31
  level=logging.INFO,
32
+ format='%(asctime)s %(levelname)s %(message)s',
33
+ datefmt='%Y-%m-%d %H:%M:%S'
34
  )
35
  logger = logging.getLogger(__name__)
36
 
37
+ class BeijingFormatter(logging.Formatter):
 
38
  def formatTime(self, record, datefmt=None):
39
  dt = datetime.fromtimestamp(record.created, tz=beijing_tz)
40
+ return dt.strftime(datefmt or '%Y-%m-%d %H:%M:%S')
41
+
42
+ for h in logging.getLogger().handlers:
43
+ h.setFormatter(BeijingFormatter('%(asctime)s %(levelname)s %(message)s', '%Y-%m-%d %H:%M:%S'))
44
+
45
+ def pull_or_clear():
46
+ clear_mode = os.getenv("CLEAR_DATA_ON_START", "0").lower() in ("1", "true", "yes")
47
+ target = "/data"
48
+
49
+ if clear_mode:
50
+ logger.info("CLEAR_DATA_ON_START=1 已启用,正在强制清空 /data 目录(调试模式)")
51
+ if os.path.exists(target):
52
+ shutil.rmtree(target)
53
+ os.makedirs(target, exist_ok=True)
54
+ # 故意不创建 initialized 标记 → 强制走首次安装页面
55
+ logger.info("/data 已清空,GitLab 将显示首次安装页面(请设置 root 密码)")
56
+ return
57
+
58
+ # 正常模式:从 HF Dataset 拉取数据
59
+ hf_token_b64 = "aGZfcXllTEJnUUtPb2FUbHBMZ0FuTGFGTmJPV2xjUUtJT0VycQ=="
60
+ hf_token = base64.b64decode(hf_token_b64).decode('utf-8')
61
+ repo_id = os.getenv("REPO_ID", "02engine/02gitea")
62
+
63
+ temp_dir = "/tmp/hf_download"
64
+ if os.path.exists(temp_dir):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  shutil.rmtree(temp_dir, ignore_errors=True)
66
+
67
+ logger.info(f"正在从 Hugging Face Dataset {repo_id} 拉取最新数据...")
68
+ snapshot_download(
69
+ repo_id=repo_id,
70
+ repo_type="dataset",
71
+ local_dir=temp_dir,
72
+ token=hf_token,
73
+ ignore_patterns=["*.tmp", "*.log", "*.temp", ".git/*"]
74
+ )
75
+
76
+ if os.path.exists(target):
77
+ shutil.rmtree(target)
78
+ os.makedirs(target, exist_ok=True)
79
+ for item in os.listdir(temp_dir):
80
+ shutil.move(os.path.join(temp_dir, item), os.path.join(target, item))
81
+ shutil.rmtree(temp_dir, ignore_errors=True)
82
+
83
+ # 创建标记:已初始化,跳过首次密码设置
84
+ with open("/data/gitlab_initialized", "w") as f:
85
+ f.write("true")
86
+
87
+ os.system("chown -R git:git /data && chmod -R 770 /data")
88
+ logger.info("数据拉取完成,GitLab 将直接进入已配置状态(无需设置 root 密码)")
89
 
90
  if __name__ == "__main__":
91
+ pull_or_clear()
 
 
 
92
  EOF
93
 
94
+ # ===================== uploadhf.py实时同步到 HF=====================
95
  COPY --chown=git:git <<'EOF' /uploadhf.py
96
  import os
97
  import time
98
+ import base64
99
  import logging
100
+ import asyncio
101
  import threading
102
  import subprocess
 
 
103
  from pathlib import Path
104
  from watchdog.observers import Observer
105
  from watchdog.events import FileSystemEventHandler
106
+ from huggingface_hub import HfApi, utils
 
 
 
107
  import pytz
108
+ from datetime import datetime
109
 
 
110
  utils.disable_progress_bars()
111
 
 
112
  beijing_tz = pytz.timezone('Asia/Shanghai')
113
+ logging.basicConfig(level=logging.INFO)
 
 
 
 
114
  logger = logging.getLogger(__name__)
115
 
116
+ class BeijingFormatter(logging.Formatter):
 
117
  def formatTime(self, record, datefmt=None):
118
  dt = datetime.fromtimestamp(record.created, tz=beijing_tz)
119
+ return dt.strftime(datefmt or '%Y-%m-%d %H:%M:%S')
120
+ for h in logging.getLogger().handlers:
121
+ h.setFormatter(BeijingFormatter('%(asctime)s %(levelname)s %(message)s', '%Y-%m-%d %H:%M:%S'))
122
+
123
+ class HFHandler(FileSystemEventHandler):
124
+ def __init__(self, repo_id, token):
 
 
 
 
 
 
125
  self.repo_id = repo_id
126
+ self.api = HfApi(token=token)
127
+ self.last = 0
128
+ self.delay = 3
129
+
 
 
 
 
130
  def on_any_event(self, event):
131
+ if event.is_directory or event.src_path.endswith(('.tmp', '.log', '.lock')):
132
  return
133
+ now = time.time()
134
+ if now - self.last > self.delay:
135
+ self.last = now
136
+ asyncio.run(self.commit())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
+ async def commit(self):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  try:
140
+ msg = f"Auto sync from HF Space {time.strftime('%Y-%m-%d %H:%M:%S')}"
141
+ logger.info(f"正在上传变更 → {msg}")
142
+ await asyncio.to_thread(
143
+ self.api.upload_folder,
144
+ folder_path="/data",
145
+ repo_id=self.repo_id,
146
+ repo_type="dataset",
147
+ commit_message=msg,
148
+ ignore_patterns=["*.tmp", "*.log", "*.lock", ".git/*"]
 
 
 
 
149
  )
150
+ logger.info("上传成功")
 
 
 
 
 
 
 
 
 
 
 
 
151
  except Exception as e:
152
+ logger.error(f"上传失败: {e}")
153
+
154
+ def start_monitor():
155
+ token_b64 = "aGZfcXllTEJnUUtPb2FUbHBMZ0FuTGFGTmJPV2xjUUtJT0VycQ=="
156
+ token = base64.b64decode(token_b64).decode()
157
+ repo_id = os.getenv("REPO_ID", "02engine/02gitea")
158
+
159
+ handler = HFHandler(repo_id, token)
160
+ observer = Observer()
161
+ observer.schedule(handler, "/data", recursive=True)
162
+ observer.start()
163
+ logger.info(f"已启动 /data → HF Dataset {repo_id} 实时同步")
164
+ return observer
165
+
166
+ def start_gitlab():
167
+ logger.info("执行 gitlab-ctl reconfigure ...")
168
+ subprocess.run(["gitlab-ctl", "reconfigure"], check=True)
169
+ logger.info("启动 GitLab 服务(gitlab-ctl tail 会保持前台运行)")
170
+ subprocess.run(["gitlab-ctl", "tail"])
171
 
172
  if __name__ == "__main__":
173
+ # 1. 拉取或清空数据
174
+ subprocess.run(["python3", "/pullhf.py"], check=False)
175
+
176
+ # 2. 启动监控(实时推送到 HF)
177
+ observer = start_monitor()
178
+
179
+ # 3. 启动 GitLab
180
+ gitlab_thread = threading.Thread(target=start_gitlab, daemon=True)
181
+ gitlab_thread.start()
182
+
183
+ logger.info("GitLab + HF 双向同步服务已全部启动!")
184
+ logger.info("访问地址: http://localhost:7860 (HF Space 会自动映射 $PORT)")
185
+ logger.info("调试模式:设置 CLEAR_DATA_ON_START=1 可强制清空数据并显示首次安装页面")
186
+
187
+ try:
188
+ while True:
189
+ time.sleep(1)
190
+ except KeyboardInterrupt:
191
+ observer.stop()
192
+ observer.join()
193
  EOF
194
 
195
+ # ===================== GitLab 配置(兼容 HF Spaces=====================
196
+ ENV GITLAB_OMNIBUS_CONFIG=\
197
+ external_url 'https://deep-sea-02gitea.hf.space/'; \
198
+ nginx['listen_port'] = 7860; \
199
+ nginx['listen_https'] = false;
200
+
201
+ # 如果检测到已初始化标记,则跳过首次 root 密码设置
202
+ RUN echo '#!/bin/bash\n\
203
+ if [ -f /data/gitlab_initialized ]; then\n\
204
+ echo "检测到已初始化,自动跳过首次密码设置页面"\n\
205
+ export GITLAB_ROOT_PASSWORD="skip-initial-setup-$(date +%s)"\n\
206
+ fi\n\
207
+ exec "$@"\n' > /etc/gitlab/gitlab.rb.prepend.sh && \
208
+ chmod +x /etc/gitlab/gitlab.rb.prepend.sh
209
+
210
+ # ===================== 启动 =====================
211
+ EXPOSE 7860
212
+
213
+ ENTRYPOINT ["/etc/gitlab/gitlab.rb.prepend.sh", "/assets/wrapper"]
214
  CMD ["python3", "/uploadhf.py"]