俾Docker容器中的应用访问宿主机上的数据库服务

在Docker Compose中,默认情况下,服务之间会在一个自定义的网络中通信。因此,容器会通过这个网络进行互相通信,而无法直接访问宿主机的 IP 地址。

这便是为何当服务尝试连接宿主机上的数据库服务器地址(兹以PostgreSQL这一数据库服务以及192.168.1.1:5432这一服务器位址为例)时,会出现连接超时的问题。

为了解决这个问题,可以有几种方案来让Docker容器中的应用访问宿主机上的数据库,而无需使用Docker自己创建的网络。

方案 1: 使用 host.docker.internal

在Docker for Linux中,可以使用host.docker.internal来指向宿主机的IP地址。这是Docker提供的一个内置DNS名称,允许容器访问宿主机的网络资源。可以将数据库的HOST设置为host.docker.internal,这样容器内部会自动解析到宿主机的IP。

  • 修改 settings.py.env 文件中的数据库配置,将 HOST 设置为 host.docker.internal

    DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'database', # 改成自己的 'USER': 'database', # 改成自己的 'PASSWORD': 'your_password', # 改成自己的 'HOST': 'host.docker.internal', # 使用 host.docker.internal 而不是 192.168.1.1 'PORT': '5432', }}
  • 运行docker compose命令,尝试把容器架起来;容器会自动解析这个特殊的DNS名称,并连接到宿主机的PostgreSQL服务。

  • 方案 2: 使用 network_mode: "host"

    如果不想让Docker为容器创建单独的网络,可以使用network_mode: "host"配置项。这会让容器直接使用宿主机的网络堆栈,而不是通过Docker创建的网络。这意味着容器可以直接访问宿主机的网络接口。

  • 修改 docker-compose.yml 文件,在 web 服务中添加 network_mode: "host"

    services: web: (从略) network_mode: "host" # 添加这个选项 (从略) ports: - "(所期望的容器外端口):8000"
  • 重新运行docker compose up,此时Docker容器将直接使用宿主机的网络,因此它可以直接访问192.168.1.1:5432上的PostgreSQL。

  • 方案 3: 自定义网络配置,桥接到宿主机网络

    如果仍然想使用Docker自定义网络,但让容器能够访问宿主机的网络,可以使用extra_hosts来为容器提供宿主机 IP 的映射。

  • docker-compose.yml中,使用extra_hosts指定宿主机的IP:

    services: web: (从略) ports: - "(所期望的容器外端口):8000" extra_hosts: - "host.docker.internal:192.168.1.1" # 手动映射宿主机的 IP
  • 运行docker-compose,这会将host.docker.internal映射到宿主机IP地址。

  • 总结

    • 使用host.docker.internal是最简便的方法,这个DNS名会自动解析到宿主机的IP地址。
    • 如若希望容器直接使用宿主机网络,可以使用network_mode: "host",让容器与宿主机共享网络堆栈。
    • 如若欲继续使用Docker自定义的网络,但仍然访问宿主机服务,可以使用extra_hosts来手动指定宿主机 IP。

    根据需求选择合适的方案,修改配置后应该可以解决Docker容器无法连接宿主机上数据库服务的问题。

    #Bookwyrm #Docker #PostgreSQL #自託管

    127.0.0.1与0.0.0.0之区别

    127.0.0.10.0.0.0这两个IP地址在网络中有不同的含义和用途:

    • 127.0.0.1是一个环回地址(loopback address),并不表示“本机”。它用于在本地计算机上运行服务的场景。所有发往该类地址的数据包都应该被loop back,即在主机上发送给127开头的IP地址的数据包会被发送的主机自己接收,根本传不出去,外部设备也无法通过回环地址访问到本机。例如,通过使用ping 127.0.0.1可以测试某台机器上的网络设备,操作系统或者TCP/IP实现是否工作正常。
    • 0.0.0.0才是真正表示“本网络中的本机”。在服务器中,0.0.0.0指的是本机上的所有IPV4地址。如果一个主机有两个IP地址,192.168.1.1和10.1.1.1,并且该主机上的一个服务监听的地址是0.0.0.0,那么通过两个ip地址都能够访问该服务。在实际应用中,一般我们在服务端绑定端口的时候可以选择绑定到0.0.0.0,这样我的服务访问方就可以通过我的多个ip地址访问我的服务。

    总的来说,127.0.0.1主要用于本地测试和调试,而0.0.0.0则用于在开发环境中监听所有可用的网络接口。

    在安全性方面,如果绑定0.0.0.0,也有一定安全隐患,对于只需要内网访问的服务,可以只绑定内网地址。

    #互聯網 #自託管

    Bookwyrm由0.7.5升级至Production (e217a17) 完整过程及疑难解答

    引言

    本教程旨在帮助Bookwyrm用户如何将其部署从v0.7.5升级到(笔者执笔时)最新的production分支(具体到e217a17版本)。截至该版本提交(commit)的诸多代码带来了许多改进,例如对搜索词汇权重的优化设计(能更精准地根据标题、作者、系列等信息进行排序),以及数据导出功能的增强(排除已删除内容)等,这些都会提升用户体验和系统稳定性。

    然而,本次升级过程中,笔者遇到了一些特殊情况,这些情况并非普遍存在,但对于拥有类似部署环境的用户来说至关重要。如果您是——

    使用外部(包括宿主机上的)数据库服务,并依赖Docker的host网络模式进行通信;同时,

    通过容器外的服务进行HTTPS管理(而非在容器内部自签)

    ——那么本教程中的“特殊情况”部分将为您提供经验与解决方案。

    如果您没有这些特殊需求,通常可以直接遵循Bookwyrm官方的升级指南,那将是更简便的路径。

    特殊情况概述:为何我的升级之路如此“曲折”?

    在本次升级案例中,笔者面临的主要挑战源于以下几个相互关联的部署选择:

  • 外部数据库与host网络模式: 为了与宿主机上运行的外部PostgreSQL数据库服务进行通信,笔者的Docker Compose配置中将db服务注释掉了,并将webcelery等服务设置为 network_mode: "host"

    • 影响:host网络模式下,Docker容器直接共享宿主机的网络堆栈,容器之间无法通过服务名称进行内部解析。它们必须通过宿主机的IP地址(通常宿主机实际的局域网IP;或者都是host了,干脆127.0.0.1亦可)进行通信。这直接影响了nginx与Web服务之间的通信配置。
  • Cloudflare Zero Trust与HTTPS管理: 笔者用 Cloudflare Zero Trust来处理HTTPS加密。这意味着服务器端无需强制进行HTTPS,而是由Cloudflare在边缘网络提供SSL/TLS保护。

    • 影响: 如果在服务器端启用自签名或其他免费的HTTPS证书,并与Cloudflare的“严格”HTTPS策略冲突,可能导致Cloudflare阻止流量,认为存在不安全的端到端连接。因此,我们的nginx配置必须避免在服务器端强制HTTPS,而是通过HTTP监听,并由Cloudflare Zero Trust负责转发和加密。这与Bookwyrm官方版本(无论是截至v0.7.5抑是截至本文所提之“最新”版)中可能集成的Certbot自动化HTTPS方案有所冲突,需要进行定制化。
  • nginx端口冲突: 由于采用host网络模式,nginx容器会尝试直接监听宿主机的端口。在升级过程中,我们发现宿主机的80端口已被一个别的(就诸如nginx这样的)Web服务器占用,导致nginx无法启动。这需要沉下心诊断并解决端口冲突问题。

  • 这些特殊因素叠加,使得简单的拉取(pull)或者复制粘贴新版本docker-compose.yml配置变得不可行,需要对网络、nginx代理和端口管理进行精细调整。

    升级教程:从0.7.5到Production (e217a17)

    本教程假设您已经有了一个运行正常的Bookwyrm 0.7.5部署,并且熟悉基本的Git和Docker Compose命令。

    步骤1:备份数据和配置

    这是最关键的第一步!在进行任何重大升级之前,务必备份所有重要数据。

  • 备份数据库:如果数据库运行在Docker容器内(假设容器名为bookwyrm-db-1),可以使用docker exec命令进行备份:

    docker exec -t bookwyrm-db-1 pg_dump -U your_db_user your_db_name > db_backup.sql

    如果数据库是外部服务,则使用其提供的备份机制。

  • 备份 Docker Compose 文件和自定义配置:复制当前的docker-compose.yml文件和所有自定义的配置文件(例如.env文件、nginx配置目录 nginx/ 等)。

    cp docker-compose.yml docker-compose.yml.bakcp .env .env.bakcp -r nginx/ nginx.bak/# 确保备份所有可能包含定制化信息的目录和文件
  • 步骤2:更新Bookwyrm代码库

  • 停止当前运行的Bookwyrm服务:

    docker compose down
  • 拉取最新的production分支代码并回滚:

    (请确保您明白本节在说什么之后,再继续操作!如于不熟悉Git之情况下贸然照搬,会导致可怕后果😱)

    由于过去站点的运行可能会生成很多不需要的变更甚至提交(例如,nginx静态文件目录的权限变更,或者是Windows/Linux之间的换行符差异,皆会被Git一一记录);故此,先回滚到干净的远程production状态,然后只应用您所需的修改。

    git fetch origin # 获取远程仓库的最新状态git reset --hard origin/production # 强制重置本地分支到远程 production 的最新提交

    这将清除您本地所有未推送到origin/production的修改。(或者可能是upstream/production,根据实际情况来。)

  • 步骤3:应用有价值的修改

    (本节同样也是,希望您明白下述文字在说什么以后,再考虑要否采纳。)

    现在,在干净的origin/production基础上,重新应用希望保留修改:

  • 重命名docker-compose.ymldocker-compose.example.yml如果origin/production包含docker-compose.yml文件,执行:

    mv docker-compose.yml docker-compose.example.yml

    兹解释一下笔者为什么会需要这么做。笔者以为官方Git库直接提供docker-compose.yml并于每回释出新版本时累次将变更付诸此文件是不优雅的。这样做没有考虑到(包括笔者在内)魔改docker-compose.yml以取消掉部分原生服务(例如容器内的db)的可能性——每次拉取官方更新,若不备份好自己的docker-compose.yml,就会被官方发布的.yml一整个覆盖掉。

    笔者以为,较为优雅的实践,是官方提供一个docker-compose.example.yml,并指导用户去:

    cp docker-compose.example.yml docker-compose.yml

    岂不美哉?不过,反馈给官方后,项目的积极维护者所分享的考量也不无道理——

    对于像BookWyrm这样(笔者瞎按:由于处于内测阶段所以会急遽更迭)的项目来说,使用标准并有助于保持一致的环境是非常典型的。一般来说,自定义应该是环境变量。

    (笔者中译)

    官方倒也有提供docker-compose.override.yml这样的维护方式。记入在docker-compose.override.yml的配置如与docker-compose.yml冲突,优先执行的是override的。且override.yml也在.gitignore内,就不会在每次更新时被覆盖了。但是,笔者这种需要注释掉部分服务的做法,override支持不到了

    所以,截至本文执笔时,还是只能自行重命名。可以考虑fork一份Git库,然后把重命名操作应用过去。在这种情况下,我们就可以将upstream指定为官方Git库,origin指定为自己的Git库。

  • .gitignore中增加临时文件的忽略规则:打开本地的.gitignore文件,并在文件末尾或其他合适位置添加增加临时文件的忽略规则(笔者例)。如果您像笔者一样,宿主机用的是魔改版的Linux系统,而该系统恰会以自己的方式为一些图片文件生成临时缩略图的话,就需要忽略之。否则,nginx静态文件目录(./static)下面会出现很多临时缩略图待提交——或者在哪次直接不慎提交掉了。

  • 提交这些更改:

    git add docker-compose.example.yml .gitignore # 根据实际重命名情况调整git commit -m "Rename docker-compose.yml to docker-compose.example.yml and add temp files ignore to .gitignore"
  • 步骤4:调整docker-compose.yml和nginx配置以适应特殊情况

    这是本次升级教程的核心和关键,将根据特殊需求定制docker-compose.yml和nginx配置。

  • 手动更新 docker-compose.yml基于docker-compose.example.ymlproduction提供的docker-compose.yml文件,进行以下修改:

    • nginx, web, celery_worker, celery_beat等实际有启用的服务设置 network_mode: "host"

      services: nginx: # ... network_mode: "host" # ... web: # ... network_mode: "host" # ... celery_worker: # ... network_mode: "host" # ... celery_beat: # ... network_mode: "host" # ...
    • nginx服务volumes调整 (核心):笔者将放弃官方的default.conf.template模板机制,而是直接挂载一个包含所有自定义nginx配置的文件,并让它直接覆盖容器内nginx的默认配置。

      首先,在本地./nginx/目录中,准备一个名为my-bookwyrm-nginx.conf的文件(或者选择用https.conf也可以),将所有自定的nginx配置内容都放入其中。

      nginx服务volumes部分应类似于:

      volumes: # 直接将你的主Nginx配置文件挂载到容器的 /etc/nginx/conf.d/default.conf # 确保这个文件包含了所有你需要的Nginx指令,并且是最终版本 - ./nginx/my-bookwyrm-nginx.conf:/etc/nginx/conf.d/default.conf # 如果你的 server_config, server_name, locations 是独立的Nginx include文件 # 并且你希望它们继续被加载,你仍然可以挂载它们。但要确保它们不包含监听指令, # 而是被 my-bookwyrm-nginx.conf 文件通过 `include` 指令引用。 # 示例: # - ./nginx/locations:/etc/nginx/conf.d/locations # - ./nginx/server_config:/etc/nginx/conf.d/server_config # - ./nginx/server_name:/etc/nginx/conf.d/server_name # 99-autoreload.sh 脚本的挂载 - ./nginx/99-autoreload.sh:/docker-entrypoint.d/99-autoreload.sh # 静态文件和媒体文件卷 (改为直接挂载本地目录) - ./static:/app/static - ./images:/app/images - ./exports:/app/exports # 用于导出数据

      重要: 在你的docker-compose.yml中,如果Nginx服务仍然有ports部分,请确保它被移除或注释掉,因为network_mode: "host"会让Nginx直接监听宿主机端口,ports映射将是多余的。

    • 按需添加redis_activityredis_brokerflower(用于监控Celery)服务。(笔者用了外部的服务,就没开这些个。)

    • web服务的depends_on调整:

      web: # ... depends_on: celery_worker: condition: service_started redis_activity: condition: service_started # 以及其他你实际有开启的
    • 定义具名卷 (volumes) 在docker-compose.yml底部:所有在服务中使用的具名卷(例如 redis_activity_dataredis_broker_datapgdatabackups)都需要在这里定义。

      volumes: pgdata: backups: static_volume: # 如果你用具名卷而不是直接挂载目录 media_volume: # 如果你用具名卷而不是直接挂载目录 exports_volume: redis_broker_data: redis_activity_data:

      重要: 如果你的webcelerynginx已经使用network_mode: "host"并直接挂载本地目录static, images, exports,那么static_volume, media_volume等具名卷就不需要了。保持一致性,如果挂载本地目录,就不要定义具名卷,反之亦然。

  • 创建或更新nginx主配置文件 (./nginx/my-bookwyrm-nginx.conf):这个文件将是nginx容器实际加载的/etc/nginx/conf.d/default.conf

    • 确保upstream web指向127.0.0.1:8000

      upstream web { server 127.0.0.1:8000; # 因为web容器在宿主机上也监听这个地址}
    • 配置nginx监听的端口 (关键步骤):由于Apache占用80端口,且打算通过Cloudflare Zero Trust处理HTTPS,Nginx应该监听一个未被占用的端口(例如8001),并只提供HTTP服务。

      # 定义一个 Nginx 缓存区域 (可选,但推荐)proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=bookwyrm_cache:10m inactive=60m;server { listen [::]:8001; # Nginx 监听宿主机的 8001 端口 listen 8001; server_name sanguok.com; # 示例。换成你的域名。下同 # 最大请求体大小,根据需要调整 client_max_body_size 10M; # 确保只通过主域名访问 if ($host != "sanguok.com") { return 301 $scheme://sanguok.com$request_uri; } # 主要的反向代理到 web 服务 location / { proxy_pass http://web; # upstream web 已经指向了 127.0.0.1:8000 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_redirect off; # 缓存设置 (与上面 proxy_cache_path 配合使用) proxy_cache bookwyrm_cache; proxy_cache_valid any 1m; add_header X-Cache-Status $upstream_cache_status; proxy_ignore_headers Cache-Control Set-Cookie Expires; proxy_cache_methods GET HEAD; proxy_no_cache $cookie_sessionid; proxy_cache_bypass $cookie_sessionid; } # 专门处理登录、密码重置等,通常有限制请求 location ~ ^/(login[^-/]|password-reset|resend-link|2fa-check) { # limit_req zone=loginlimit; # 如果定义了限速区域 proxy_pass http://web; } # 静态文件服务 location /static/ { root /app; # 对应 docker-compose.yml 中的 ./static:/app/static try_files $uri =404; add_header X-Cache-Status STATIC; access_log off; } # 图像文件服务 location /images/ { location ~ \.(bmp|ico|jpg|jpeg|png|svg|tif|tiff|webp)$ { root /app; # 对应 docker-compose.yml 中的 ./images:/app/images try_files $uri =404; add_header X-Cache-Status STATIC; access_log off; } return 403; # 阻止非图片文件访问 } # favicon.ico 处理 location /favicon.ico { root /app/images/logos; # 假设你的 favicon 在这个路径 try_files /IMG_5682.ico =404; # 确保指向实际的图标文件 } # Flower 监控界面 (如果启用了 flower 服务) location /flower/ { proxy_pass http://127.0.0.1:8888; # 如果flower也在host模式下监听,并且监听8888端口 proxy_cache_bypass 1; } # 其他常用的 Nginx 优化设置 sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; gzip on; gzip_disable "msie6"; proxy_read_timeout 1800s; chunked_transfer_encoding on; # 错误日志 error_log /var/log/nginx/error.log debug; access_log /var/log/nginx/access.log; # 可以改为 cache_log}# 如果有其他 Nginx 配置 include,确保其内容正确且不会监听 80 端口# 例如:# include /etc/nginx/conf.d/server_config;# include /etc/nginx/conf.d/server_name;# include /etc/nginx/conf.d/locations;
    • 关于99-autoreload.sh的权限: 再次确认nginx/99-autoreload.sh文件具有执行权限 (chmod +x ./nginx/99-autoreload.sh)。

  • 步骤5:更新.env文件

    Bookwyrm和Redis服务会引入新的环境变量。打开.env文件并更新:

    • 数据库连接信息: 确保与你的外部数据库服务匹配。
    • Redis密码和端口:redis_activityredis_broker设置强密码和端口(与你在docker-compose.yml中定义的Redis命令相符)。# Redis for Celery BrokerREDIS_BROKER_PASSWORD=your_broker_redis_passwordREDIS_BROKER_PORT=6379 # 或者你指定的端口# Redis for Activity Stream/CacheREDIS_ACTIVITY_PASSWORD=your_activity_redis_passwordREDIS_ACTIVITY_PORT=6380 # 或者你指定的端口# Flower (Celery 监控) 用户名和密码FLOWER_USER=your_flower_usernameFLOWER_PASSWORD=your_flower_password# Nginx 相关的环境变量 (如果你的Nginx配置依赖它们)DOMAIN=sanguok.com# NGINX_SETUP=https # 如果你打算用我的my-bookwyrm-nginx.conf,这一行可以不设置或删除

      根据实际的docker-compose.ymlREDIS_BROKER_PORTREDIS_ACTIVITY_PORT的配置来填写端口。

    步骤6:构建和启动服务

  • 构建Docker镜像:

    docker compose build

    这会根据更新的Dockerfiledocker-compose.yml来构建所有服务的镜像。

  • 启动所有服务:

    docker compose up -d

    这将以后台模式启动所有容器。

  • 检查日志以确认服务是否正常运行:

    docker compose logs -f

    密切关注nginx、Web和Celery服务的日志,确保它们没有错误并且正常监听。

  • 步骤7:执行数据库迁移和初始化

    首次启动新版本时,可能需要执行数据库迁移。

  • 执行数据库迁移:

    docker compose exec web python manage.py migrate
  • 创建超级用户 (如果还没有):

    docker compose exec web python manage.py createsuperuser
  • 收集静态文件:

    docker compose exec web python manage.py collectstatic --noinput
  • 步骤8:配置nginx和Cloudflare Zero Trust

  • 确保宿主机上没有其他服务占用nginx计划监听的端口。检查你的宿主机,确保其他服务没有占用8001端口 (如果你按照本教程将其配置为nginx的监听端口)。

    sudo lsof -i :8001 # 检查 8001 端口是否被占用

    如果被占用,需要停止占用8001端口的服务,或者将nginx配置为监听另一个空闲端口。

  • Cloudflare Zero Trust配置:在Cloudflare Zero Trust控制台,为域名(按前面的示例就是sanguok.com)配置应用程序,使其通过HTTP转发到你的服务器IP地址的8001端口。Cloudflare将负责从客户端到Cloudflare的HTTPS连接。

  • 恭喜!

    经过这些详细的步骤和针对特殊情况的调整,您的Bookwyrm实例应该能够成功从0.7.5升级到production分支的e217a17版本,并且在特定的Docker Host网络模式和Cloudflare Zero Trust环境下正常运行。

    如果在过程中遇到任何问题,请再次查看日志输出,并对照本教程中的排查步骤。祝君顺利!

    #Bookwyrm #自託管

    Release v0.7.5 · bookwyrm-social/bookwyrm

    What's Changed Updated Dependencies 🧸 Bump aiohttp from 3.10.2 to 3.10.11 by @dependabot in #3473 Bump django from 4.2.18 to 4.2.20 by @dependabot in #3520 Other Changes possible fix for #3372 -...

    GitHub

    批量处理ArchiveBox所有未成功抓取的链接

    使用archivebox update --status unarchived命令,可以批量处理所有未成功抓取的链接。

    工序

  • 进入Docker容器
  • docker exec -it archivebox /bin/bash
  • 切换到数据目录
  • cd /data

    切换到非管理员操作:

    su archivebox

    否则会有安全性报错:

    [!] ArchiveBox should never be run as root! For more information, see the security overview documentation: https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#do-not-run-as-root
  • 执行命令
  • 使用以下命令重新抓取所有未成功抓取的链接:

    archivebox update --status unarchived
  • 退出容器
  • exit

    示例

    以下是能在终端中看到的示例输出:

    root@b4444bfff46f:~# cd /dataroot@b4444bfff46f:/data# archivebox update --status unarchived[i] [2024-06-23 08:00:00] ArchiveBox v0.6.2: archivebox update --status unarchived > /data[i] [2024-06-23 08:00:00] Updating all snapshots with status: unarchived...[i] [2024-06-23 08:00:01] Snapshot URL: http://example.com (1/1)[i] [2024-06-23 08:00:02] Archiving snapshot using wget......

    其他选项

    • 指定时间段:可以使用--before--after选项来指定一个时间段,例如:
    archivebox update --status unarchived --after "2023-01-01"
    • 特定的抓取工具:可以使用--extract选项来指定特定的抓取工具,例如:
    archivebox update --status unarchived --extract wget

    这些选项可以根据需求进行组合使用。

    补充:倘遇到TypeError

    有时执行本文所介绍之命令,会遇到中断的情况,并返回日志如下(以鄙站为例):

    [+] [2025-07-06 04:31:51] "sanguok.com"(中略)archive_methods.save_readability(Link(url=https://sanguok.com))Traceback (most recent call last): File "/app/archivebox/extractors/__init__.py", line 114, in archive_link log_archive_method_finished(result) File "/app/archivebox/logging_util.py", line 435, in log_archive_method_finished hints = hints if isinstance(hints, (list, tuple)) else hints.split('\n')TypeError: a bytes-like object is required, not 'str'The above exception was the direct cause of the following exception:Traceback (most recent call last): File "/usr/local/bin/archivebox", line 33, in <module> sys.exit(load_entry_point('archivebox', 'console_scripts', 'archivebox')()) File "/app/archivebox/cli/__init__.py", line 140, in main run_subcommand( File "/app/archivebox/cli/__init__.py", line 80, in run_subcommand module.main(args=subcommand_args, stdin=stdin, pwd=pwd) # type: ignore File "/app/archivebox/cli/archivebox_update.py", line 119, in main update( File "/app/archivebox/util.py", line 114, in typechecked_function return func(*args, **kwargs) File "/app/archivebox/main.py", line 783, in update archive_links(to_archive, overwrite=overwrite, **archive_kwargs) File "/app/archivebox/util.py", line 114, in typechecked_function return func(*args, **kwargs) File "/app/archivebox/extractors/__init__.py", line 181, in archive_links archive_link(to_archive, overwrite=overwrite, methods=methods, out_dir=Path(link.link_dir)) File "/app/archivebox/util.py", line 114, in typechecked_function return func(*args, **kwargs) File "/app/archivebox/extractors/__init__.py", line 130, in archive_link raise Exception('Exception in archive_methods.save_{}(Link(url={}))'.format(Exception: Exception in archive_methods.save_readability(Link(url=https://sanguok.com))

    笔者是在ArchiveBox v0.6.2遇到的此情况。这个错误信息TypeError: a bytes-like object is required, not 'str'表明在archivebox/logging_util.py文件的log_archive_method_finished函数中,有一个预期的字节类型对象被传递了一个字符串类型对象。

    这个错误通常发生在Python 3环境中处理字节和字符串混合的情况。ArchiveBox在尝试记录归档方法的完成状态时,可能某个内部函数或外部工具返回了字符串,而它期望的是字节数据,或者反之。从堆栈跟踪来看,错误发生在archive_methods.save_readability(Link(url=https://sanguok.com))这一行,这暗示问题可能与readability提取器在处理特定链接时有关。readability提取器负责将网页内容转换为更易读的格式。

    为此,一个值得期待的解决方案是更新至新版本,看看该bug有无被解决掉。抑或者就是跳过有问题的链接(下述方法1.)或提取器(下述方法2.,笔者推荐这条)。

  • 跳过特定链接(如果只影响少数链接):目前ArchiveBox没有直接的“跳过”特定URL的功能。但可以尝试在更新时排除这个链接。不过,对于update --status unarchived这种全局操作,这不太可行。

  • 暂时禁用 readability 提取器:那么,可以尝试在update命令中排除readability提取器,看看是否能绕过这个问题。首先,需要知道当前启用了哪些提取器。可以在ArchiveBox的配置中查看,或者查看默认启用的提取器列表。假设默认启用了wget, readability, dom, screenshot, git, media, favicon,可以尝试这样:

    archivebox update --status unarchived --extract wget,dom,screenshot,git,media,favicon

    这将指示ArchiveBox在归档时跳过readability模块。

  • 辨析

    还有一种俾ArichiveBox重新抓取的方法,是使用--resume参数;但这需要一个时间戳作为其值,指定从哪个时间点开始恢复。

    倘是希望重新抓取所有未成功的链接,就可以使用本文介绍的--status unarchived选项,这个选项会处理所有未成功(即状态为unarchived)的链接。

    #Docker #自託管

    山月 – 左海逐月,雙峰遺夢

    🌕 RomM - 一個精美、強大、可自託管的 ROM 管理器與播放器
    ➤ 打造你的個人遊戲中心
    https://github.com/rommapp/romm
    RomM 是一個允許使用者掃描、豐富、瀏覽及遊玩遊戲收藏的自託管應用程式。它支援多個平臺、各種命名方案和自訂標籤,並提供使用者介面以管理遊戲檔案,包含元數據、封面圖片和成就,甚至可以直接在瀏覽器中遊玩遊戲。它也提供社羣支援、技術支援,並鼓勵使用者貢獻程式碼。
    + 終於找到一個方便整理我大量 ROM 的工具了,而且還能直接在瀏覽器上玩遊戲,太方便了!
    + 自託管的設計讓我很安心,不用擔心隱私問題,而且功能也相當齊全,很推薦給喜歡懷舊遊戲的玩家。
    #軟體 #遊戲 #自託管 #ROM 管理
    GitHub - rommapp/romm: A beautiful, powerful, self-hosted rom manager and player.

    A beautiful, powerful, self-hosted rom manager and player. - rommapp/romm

    GitHub

    [自託管]

    Elest.io 提供多種託管服務,包括資料庫、應用程式、開發、以及主機和基礎設施服務。

    https://elest.io

    #自託管

    Elestio: Fully Managed Open source

    Deploy 350+ open-source software on a dedicated instance in <3 mins. We handle setup, config, encryption, backups, updates, monitoring & more!

    🌗 如何為您的新創公司建立自託管的 Wiki
    ➤ 為新創公司建立自託管的 Wiki:一個成本效益高且容易設置的選擇
    https://themythicalengineer.com/how-to-setup-self-hosted-wiki-for-your-startup.html
    在建立新創公司的 Wiki 時,自託管方案可能比付費軟體更具吸引力,成本更低且固定。作者分享了運行自託管 Wiki.js 的經驗,建議 Wiki.js 是一個優秀的替代方案,容易設置並成本效益高。
    + 這篇文章提供了相當具體且實用的自託管 Wiki 建立指南,對於剛起步的新創公司來說很有幫助。
    + 自託管的方案確實能幫助新創公司節省成本,同時保持了不錯的功能性,推薦給有需要的創業者。
    #新創公司 #自託管 #Wiki
    How to setup self hosted wiki for your startup

    Blog about Software Engineering

    The Mythical Engineer

    在这篇博文中,笔?

    (山月)想记录自己如何解决BookWyrm部署过程中遇到的数据库问题,特别是在远程用户搜索时遇到的 “function similarity(character varying, unknown) does not exist” 错误。

    背景

    背景是笔?

    (山月)从YunoHost搬迁到现有环境,使用Docker […]

    #Bookwyrm #PostgreSQL #自託管

    https://sanguok.com/blog/self-built-bookwyrm-not-querying-remote-users-enable-database-extension/

    🌗 GitHub - wasi-master/13ft: 我自己的自訂12ft.io替代方案
    ➤ 使用Docker方法或Python腳本方法來部署和使用這個替代方案
    https://github.com/wasi-master/13ft
    這是一個可以替代12ft.io的自託管伺服器,可以用於繞過付費文章和廣告的網站。
    + 這個替代方案真是太方便了,不用為了看一篇付費文章而浪費錢。
    + 好棒的解決方案,可以省下不少訂閱付費內容的費用。
    #網站代理 #自託管 #繞過付費牆 #資源
    GitHub - wasi-master/13ft: My own custom 12ft.io replacement

    My own custom 12ft.io replacement. Contribute to wasi-master/13ft development by creating an account on GitHub.

    GitHub