أستخدم مقبس Unix بين Caddy و Discourse بدلاً من TCP، ولكن من حين لآخر تظهر لي رسالة خطأ 'unix:'

تُظهر السجلات ما يلي:

PG::InvalidTextRepresentation (ERROR: invalid input syntax for type inet: "unix:" LINE 7: client_ip = 'unix:', ^ ) lib/mini_sql_multisite_connection.rb:109:in 'MiniSqlMult

Job exception: ERROR: invalid input syntax for type inet: "unix:" LINE 2: SET ip_address = 'unix:' ^  

عند حدوث ذلك، تظهر صفحة “عذراً - خطأ 500”. في البداية، اعتقدت أن Caddy هو السبب لأنه لم يكن ينقل عنوان IP الخاص بالعميل إلى Discourse، لذلك جربت عدة إعدادات مختلفة، لكن لم تحل أي منها المشكلة.

جدير بالذكر أن هذا لا يحدث بشكل متكرر. يحدث فقط بشكل عرضي، وعندما يحدث، فإن تحديث الصفحة فوراً يعيد استعادة الموقع. ثم يعمل بشكل طبيعي لفترة طويلة قبل أن يحدث الخطأ عشوائياً مرة أخرى.

لستُ خبيراً، ولم أستخدم Caddy بل Nginx على نسختي المستضافة ذاتياً، لكن هل يمكنني طلب إعدادات قوالب Caddy وDiscourse الفعلية لديك في ./app/containers.yml؟

هل يمكنك تذكر ما كنت تفعله عادةً قبل حدوث الخطأ؟ أعني، هل كنت تغير إعدادات المسؤول، أو تنشر منشوراً، أو تستخدم بعض الإضافات؟

أعتذر لعدم تقديم مساعدة محددة لمشكلتك، لكنني أعتقد أن ردودك يمكن أن تضيف قيمة إلى سؤالك للحصول على رد واضح وسريع من المجتمع.

هذا يعني أن طلبًا / مستخدمًا لديه عنوان IP بعيد يشير إلى منفذك (socket)، مما يعني أن هناك خطأ في تكوين سلسلة الوكلاء (proxy chain) الخاصة بك.

@satonotdead @Falco

app.yml

templates:
  - "templates/postgres.18.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  
  - "templates/web.socketed.template.yml"
  
  - "templates/enable-ruby-yjit.yml"


## أي منافذ TCP/IP يجب أن يعرضها هذا الحاوية؟
## إذا كنت تريد أن يشارك Discourse منفذًا مع خادم ويب آخر مثل Apache أو nginx،
## انظر https://meta.discourse.org/t/17247 للحصول على التفاصيل
expose:
  # - "66:80"   # http
  # - "66:443" # https

params:
  ## أي نسخة Git يجب أن يستخدمها هذا الحاوية؟ (الافتراضي: latest)
  version: latest
  ## الحد الأقصى لحجم التحميل (الافتراضي: 10m)
  upload_size: 150m
  
  db_default_text_search_config: "pg_catalog.english"

  ## تعيين db_shared_buffers إلى حد أقصى 25% من إجمالي الذاكرة.
  ## سيتم تعيينه تلقائيًا بواسطة bootstrap بناءً على ذاكرة الوصول العشوائي المكتشفة، أو يمكنك تجاوز ذلك
  db_shared_buffers: "2048MB"

  ## يمكن تحسين أداء الفرز، لكنه يضيف استخدامًا للذاكرة لكل اتصال
  #db_work_mem: "40MB"

  ## أي نسخة Git يجب أن يستخدمها هذا الحاوية؟ (الافتراضي: tests-passed)
  #version: tests-passed

env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## https://meta.discourse.org/t/rescaling-the-server-which-configs-need-to-be-changed-unicorn-workers-memory-etc/252788
  ## كم عدد طلبات الويب المتزامنة المدعومة؟ يعتمد على الذاكرة ونوى وحدة المعالجة المركزية.
  ## سيتم تعيينه تلقائيًا بواسطة bootstrap بناءً على وحدات المعالجة المركزية المكتشفة، أو يمكنك تجاوز ذلك
  UNICORN_WORKERS: 8

  ## TODO: اسم النطاق الذي سيستجيب له هذا مثيل Discourse
  ## مطلوب. لن يعمل Discourse مع رقم IP عاري.
  DISCOURSE_HOSTNAME: example.com

  ## قم بإلغاء التعليق إذا كنت تريد بدء الحاوية بنفس
  ## اسم المضيف (خيار -h) كما هو محدد أعلاه (الافتراضي "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: قائمة من عناوين البريد الإلكتروني مفصولة بفواصل التي سيتم تعيينها كمسؤول ومطور
  ## عند التسجيل الأولي مثال 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'admin+discourse@example.com'

  ## TODO: خادم بريد SMTP المستخدم للتحقق من الحسابات الجديدة وإرسال الإشعارات
  # عنوان SMTP مطلوب
  # تحذير: يجب وضع كلمة مرور SMTP بين علامات اقتباس لتجنب المشاكل
  DISCOURSE_SMTP_ADDRESS: smtp.provider.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: noreply@example.com
  DISCOURSE_SMTP_PASSWORD: "***"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (اختياري، الافتراضي: true)
  DISCOURSE_SMTP_DOMAIN: example.com # (مطلوب من بعض المزودين)
  DISCOURSE_NOTIFICATION_EMAIL: noreply@example.com
  #DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: peer        # (اختياري، الافتراضي: peer، القيم الصالحة: none، peer، client_once، fail_if_no_peer_cert)
  #DISCOURSE_SMTP_AUTHENTICATION: plain            # (الافتراضي: plain، القيم الصالحة: plain، login، cram_md5)

  ## إذا أضفت قالب Lets Encrypt، قم بإلغاء التعليق أدناه للحصول على شهادة SSL مجانية
  # LETSENCRYPT_ACCOUNT_EMAIL: admin+letsencrypt@example.com

  ## عنوان CDN http أو https لهذا مثيل Discourse (مُعد للسحب)
  ## انظر https://meta.discourse.org/t/14857 للحصول على التفاصيل
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

  ## معرف حساب وعنوان ترخيص Maxmind geolocation IP للبحث عن عناوين IP
  ## انظر https://meta.discourse.org/t/-/173941 للحصول على التفاصيل
  #DISCOURSE_MAXMIND_ACCOUNT_ID: 123456
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

  # فرض HTTPS
  DISCOURSE_FORCE_HTTPS: true
  
  # حدود الطلبات
  DISCOURSE_MAX_REQS_PER_IP_MODE: none
  DISCOURSE_MAX_ADMIN_API_REQS_PER_MINUTE: 12000
  
  DISCOURSE_MAX_DATA_EXPLORER_API_REQ_MODE: none
  DISCOURSE_MAX_DATA_EXPLORER_API_REQS_PER_10_SECONDS: 1000

  DISCOURSE_YJIT_ENABLED: true

## حاوية Docker عديمة الحالة؛ جميع البيانات مخزنة في /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log
  - volume:
      host: /var/discourse/plugins
      guest: /var/plugins

## تذهب الإضافات هنا
## انظر https://meta.discourse.org/t/19157 للحصول على التفاصيل
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - cp -a /var/plugins/. $home/plugins/

## أي أوامر مخصصة للتشغيل بعد البناء
run:
  - exec: echo "Beginning of custom commands"
  ## إذا كنت تريد تعيين عنوان البريد الإلكتروني 'من' للتسجيل الأول، قم بإلغاء التعليق وتغيير:
  ## بعد الحصول على بريد التسجيل الأول، أعد التعليق على السطر. يحتاج فقط للتشغيل مرة واحدة.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

Caddyfile

#---------------------------------------------------------------------------------

{
	storage file_system {
		root /var/caddy/data
	}
}

#---------------------------------------------------------------------------------

# لتحقيق تقييم A+ في أمان SSL
(hsts) {
	header {
		Strict-Transport-Security "max-age=31536000; includeSubDomains"
	}
}

# بيانات اعتماد acme-dns المستضافة ذاتيًا
(tls-challenge) {
	tls admin+letsencrypt@example.com {
		dns acmedns {
			username ***
			password ***
			subdomain ***
			server_url http://acme.example.com:5005
		}
	}
}

#---------------------------------------------------------------------------------
# المنتدى (Discourse)
#---------------------------------------------------------------------------------
example.com {
	#-------------------------------------------------------------------------------
	import hsts
	import tls-challenge
	#-------------------------------------------------------------------------------
	request_header X-Real-IP {remote_host}
	reverse_proxy unix//var/discourse/shared/standalone/nginx.http.sock
	#-------------------------------------------------------------------------------
}

#---------------------------------------------------------------------------------
# النطاقات الفرعية
#---------------------------------------------------------------------------------

#---------------------------------------------------------------------------------
*.example.com {
	#-------------------------------------------------------------------------------
	import hsts
	import tls-challenge
	#-------------------------------------------------------------------------------

	# فرض النسخة غير-www من النطاق
	@www host www.example.com
	redir @www https://example.com{uri} permanent
  
	#-------------------------------------------------------------------------------
  
	@store host store.example.com
	handle @store {
		@wc_private {
			path /license.txt
			path /readme.html

			# ملفات حرجة
			path /wp-config.php
			path /xmlrpc.php
			path /wp-settings.php
			path /wp-load.php
			path /wp-blog-header.php

			path /wp-admin.php

			path /wp-admin/install.php

			path /wp-content/uploads/wc-logs/*
			path /wp-content/uploads/nuvei-logs/*

			path /wp-content/uploads/woocommerce_uploads/*
		}

		# protect_php
		@wc_private_php {
			not path /wp-includes/ms-files.php

			path_regexp protect_php ^/(wp-includes|wp-admin/includes|wp-content/uploads)/.*\.php$
		}
		respond @wc_private 403
		respond @wc_private_php 403

		root * /usr/share/wordpress
		php_fastcgi unix//run/php/php8.3-fpm.sock
		file_server
	}
  
  #-------------------------------------------------------------------------------
  # ملفات HTML مستقلة متعددة
  #-------------------------------------------------------------------------------

  @join host join.example.com
  handle @join {
    root * /var/example/join
    file_server
  }

  #-------------------------------------------------------------------------------
  # بدون مطابقات
  #-------------------------------------------------------------------------------

	handle {
		respond 404
	}

	#-------------------------------------------------------------------------------
}

لأكون أكثر تحديدًا، يحدث هذا الخطأ بعد عدة ساعات من الخطأ السابق، ولا يحدث كثيرًا. لا أرى أي شيء غير عادي في app.yml أو Caddyfile.

إذا كان الاتصال بالـ socket صحيحًا حتى يتم قطعه، أعتقد أنه يمكنك إضافة مهلات زمنية صريحة وخيارات نقل.

أعتقد أنه يمكنك إضافة مهلات زمنية (timeouts) وخيارات نقل (transport) صريحة

كيف؟

حسنًا، كما قلتُ من قبل، لم أستخدم Caddy، لكن يمكنك الاطلاع على وثائقهم الرسمية.

أعتقد أنني وجدت المشكلة. إذا قمت بإعادة البناء، فلا أعيد تشغيل Caddy أبدًا. من الآن فصاعدًا، سأقوم بالآتي:

./launcher rebuild app && systemctl reload caddy

أشتبه في أن Caddy يستخدم ذاكرة التخزين المؤقت للمقبس أو شيئًا مشابهًا بعد إعادة البناء. لكن هذا لا يحدث عادةً مباشرة بعد إعادة البناء. سنرى.