diff --git a/.dockerignore b/.dockerignore index b6d6ad4..cd1f67e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,7 +7,6 @@ .env.* !.env.example !.env.production.example -docker/xray/config.local.json node_modules vendor diff --git a/.env.production.example b/.env.production.example index eb5c3cb..bba4bfe 100644 --- a/.env.production.example +++ b/.env.production.example @@ -5,24 +5,6 @@ APP_DEBUG=false APP_URL=https://example.com HTTP_PORT=8080 -DOCKER_REGISTRY=docker.arvancloud.ir - -# Optional VLESS/Xray proxy fallback. -# Start with: docker compose --env-file .env.production --profile proxy up -d vless-proxy -XRAY_IMAGE=ghcr.io/xtls/xray-core:latest -XRAY_CONFIG_FILE=./docker/xray/config.local.json -VLESS_PROXY_HTTP_PORT=2080 -VLESS_PROXY_SOCKS_PORT=2081 -DOCKER_BUILD_HTTP_PROXY= -DOCKER_BUILD_HTTPS_PROXY= -DOCKER_BUILD_NO_PROXY=localhost,127.0.0.1,::1 -DEBIAN_APT_MIRROR= -DEBIAN_SECURITY_APT_MIRROR= -DEBIAN_APT_DISABLE_UPDATES= -APP_HTTP_PROXY= -APP_HTTPS_PROXY= -APP_NO_PROXY=localhost,127.0.0.1,::1,mariadb,nginx,app,queue,scheduler,vless-proxy - APP_LOCALE=fa APP_FALLBACK_LOCALE=en APP_FAKER_LOCALE=fa_IR diff --git a/.gitignore b/.gitignore index c223a28..7be55e2 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,6 @@ /.vscode /.zed /auth.json -/docker/xray/config.local.json /node_modules /public/build /public/fonts-manifest.dev.json diff --git a/Dockerfile b/Dockerfile index 62276fd..19d4e79 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -# syntax=docker.arvancloud.ir/docker/dockerfile:1.7 +# syntax=docker/dockerfile:1.7 ARG DOCKER_REGISTRY=docker.arvancloud.ir ARG PHP_VERSION=8.4 @@ -6,17 +6,10 @@ ARG PHP_VERSION=8.4 FROM ${DOCKER_REGISTRY}/node:24-alpine AS assets WORKDIR /app -ARG HTTP_PROXY -ARG HTTPS_PROXY -ARG NO_PROXY -ARG http_proxy -ARG https_proxy -ARG no_proxy - RUN sed -i 's|https://dl-cdn.alpinelinux.org|https://mirror.arvancloud.ir/alpine|g' /etc/apk/repositories COPY package.json package-lock.json ./ -RUN timeout 300 npm ci +RUN npm ci COPY resources ./resources COPY public ./public @@ -28,24 +21,17 @@ ARG PHP_VERSION FROM ${DOCKER_REGISTRY}/php:${PHP_VERSION}-fpm-bookworm AS app WORKDIR /var/www/html -ARG HTTP_PROXY -ARG HTTPS_PROXY -ARG NO_PROXY -ARG http_proxy -ARG https_proxy -ARG no_proxy -ARG DEBIAN_APT_MIRROR -ARG DEBIAN_SECURITY_APT_MIRROR -ARG DEBIAN_APT_DISABLE_UPDATES - ENV COMPOSER_ALLOW_SUPERUSER=1 COPY docker/php/install-php-extensions /usr/local/bin/install-php-extensions -COPY docker/apt/configure-arvan-mirror.sh /tmp/configure-arvan-mirror.sh -RUN chmod +x /tmp/configure-arvan-mirror.sh \ - && /tmp/configure-arvan-mirror.sh \ - && rm /tmp/configure-arvan-mirror.sh \ +RUN if [ -f /etc/apt/sources.list.d/debian.sources ]; then \ + sed -i \ + -e 's|https\?://deb\.debian\.org/debian|http://mirror.arvancloud.ir/debian|g' \ + -e 's|https\?://security\.debian\.org/debian-security|http://mirror.arvancloud.ir/debian|g' \ + -e 's| bookworm-updates||g' \ + /etc/apt/sources.list.d/debian.sources; \ + fi \ && apt-get -o Acquire::Check-Valid-Until=false update \ && apt-get install -y --no-install-recommends \ curl \ @@ -107,13 +93,6 @@ CMD ["php-fpm"] ARG DOCKER_REGISTRY FROM ${DOCKER_REGISTRY}/nginx:1.27-alpine AS nginx -ARG HTTP_PROXY -ARG HTTPS_PROXY -ARG NO_PROXY -ARG http_proxy -ARG https_proxy -ARG no_proxy - RUN sed -i 's|https://dl-cdn.alpinelinux.org|https://mirror.arvancloud.ir/alpine|g' /etc/apk/repositories COPY docker/nginx/default.conf /etc/nginx/conf.d/default.conf diff --git a/README.md b/README.md index 8421a66..08870d1 100644 --- a/README.md +++ b/README.md @@ -17,61 +17,12 @@ APP_KEY=base64:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx= سپس `APP_URL`، `HTTP_PORT`، `DB_PASSWORD`، `MARIADB_PASSWORD` و `MARIADB_ROOT_PASSWORD` را هم تغییر دهید. مقدار پیش‌فرض `HTTP_PORT=8080` است. -اگر قبلاً بدون `APP_KEY` کانتینرها را بالا آورده‌اید، بعد از پر کردن کلید این‌ها را اجرا کنید: - -```bash -docker compose --env-file .env.production exec app php artisan config:clear -docker compose --env-file .env.production restart app queue scheduler -``` - برای build کردن imageها: ```bash docker compose --env-file .env.production build ``` -### حالت fallback با VLESS/Xray - -کانفیگ VLESS داخل `docker/xray/config.local.json` قرار دارد و این فایل در git ignore شده است. فایل نمونه‌ی بدون اطلاعات اتصال هم در `docker/xray/config.example.json` موجود است. اگر این فایل local را نداشتید، از نمونه کپی بگیرید و مقدارهای اتصال را پر کنید. - -برای وقتی که اینترنت مستقیم یا mirrorها درست جواب نمی‌دهند، اول پروکسی را با profile جدا بالا بیاورید: - -```bash -docker compose --env-file .env.production --profile proxy up -d vless-proxy -``` - -پروکسی HTTP روی سیستم میزبان از `127.0.0.1:2080` و SOCKS از `127.0.0.1:2081` در دسترس است. برای build stepهای داخل Dockerfile از این دستور استفاده کنید: - -```bash -DOCKER_BUILD_HTTP_PROXY=http://host.docker.internal:2080 \ -DOCKER_BUILD_HTTPS_PROXY=http://host.docker.internal:2080 \ -docker compose --env-file .env.production build -``` - -اگر خود pull کردن imageهای Docker مشکل داشت، این پروکسی را در Docker Desktop هم تنظیم کنید: - -```text -HTTP proxy: http://127.0.0.1:2080 -HTTPS proxy: http://127.0.0.1:2080 -``` - -برای Debian apt، پیش‌فرض روی repository رسمی Debian می‌ماند چون mirror آروان ممکن است با نسخه‌ی base image sync نباشد و dependency conflict بدهد. اگر عمداً خواستید apt را هم به mirror دیگری ببرید، این متغیرها را هنگام build تنظیم کنید: - -```bash -DEBIAN_APT_MIRROR=http://mirror.example/debian \ -DEBIAN_SECURITY_APT_MIRROR=http://mirror.example/debian-security \ -DEBIAN_APT_DISABLE_UPDATES=true \ -docker compose --env-file .env.production build -``` - -برای اینکه درخواست‌های خروجی خود اپلیکیشن هم از پروکسی رد شوند: - -```bash -APP_HTTP_PROXY=http://vless-proxy:8080 \ -APP_HTTPS_PROXY=http://vless-proxy:8080 \ -docker compose --env-file .env.production --profile proxy up -d -``` - اول دیتابیس را بالا بیاورید: ```bash @@ -96,14 +47,10 @@ docker compose --env-file .env.production up -d http://localhost:8080 ``` -برای تغییر پورت، مقدار زیر را در `.env.production` عوض کنید و سرویس `nginx` را دوباره بالا بیاورید: +Swagger: -```env -HTTP_PORT=8081 -``` - -```bash -docker compose --env-file .env.production up -d --force-recreate nginx +```text +http://localhost:8080/api/documentation ``` برای دیدن وضعیت سرویس‌ها: @@ -138,12 +85,11 @@ docker compose --env-file .env.production down -v ## خطای `No application encryption key has been specified` -یعنی `APP_KEY` در `.env.production` خالی است یا بعد از تغییر env، cache قدیمی مانده. +یعنی `APP_KEY` در `.env.production` خالی است. 1. مقدار `APP_KEY` را در `.env.production` تنظیم کنید. -2. cache را پاک و سرویس‌ها را restart کنید: +2. سرویس‌ها را restart کنید: ```bash -docker compose --env-file .env.production exec app php artisan config:clear docker compose --env-file .env.production restart app queue scheduler ``` diff --git a/docker-compose.yml b/docker-compose.yml index 33970f9..bd457be 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,51 +1,15 @@ -x-build-args: &build-args - DOCKER_REGISTRY: ${DOCKER_REGISTRY:-docker.arvancloud.ir} - HTTP_PROXY: ${DOCKER_BUILD_HTTP_PROXY:-} - HTTPS_PROXY: ${DOCKER_BUILD_HTTPS_PROXY:-${DOCKER_BUILD_HTTP_PROXY:-}} - NO_PROXY: ${DOCKER_BUILD_NO_PROXY:-localhost,127.0.0.1,::1} - http_proxy: ${DOCKER_BUILD_HTTP_PROXY:-} - https_proxy: ${DOCKER_BUILD_HTTPS_PROXY:-${DOCKER_BUILD_HTTP_PROXY:-}} - no_proxy: ${DOCKER_BUILD_NO_PROXY:-localhost,127.0.0.1,::1} - DEBIAN_APT_MIRROR: ${DEBIAN_APT_MIRROR:-} - DEBIAN_SECURITY_APT_MIRROR: ${DEBIAN_SECURITY_APT_MIRROR:-} - DEBIAN_APT_DISABLE_UPDATES: ${DEBIAN_APT_DISABLE_UPDATES:-} - -x-app-proxy-environment: &app-proxy-environment - HTTP_PROXY: ${APP_HTTP_PROXY:-} - HTTPS_PROXY: ${APP_HTTPS_PROXY:-${APP_HTTP_PROXY:-}} - NO_PROXY: ${APP_NO_PROXY:-localhost,127.0.0.1,::1,mariadb,nginx,app,queue,scheduler,vless-proxy} - services: - vless-proxy: - image: ${XRAY_IMAGE:-ghcr.io/xtls/xray-core:latest} - restart: unless-stopped - profiles: - - proxy - command: ["run", "-config", "/usr/local/etc/xray/config.json"] - volumes: - - type: bind - source: ${XRAY_CONFIG_FILE:-./docker/xray/config.local.json} - target: /usr/local/etc/xray/config.json - read_only: true - bind: - create_host_path: false - ports: - - "127.0.0.1:${VLESS_PROXY_HTTP_PORT:-2080}:8080" - - "127.0.0.1:${VLESS_PROXY_SOCKS_PORT:-2081}:1080" - networks: - - hoshpoint - app: build: context: . target: app - args: *build-args + args: + DOCKER_REGISTRY: docker.arvancloud.ir image: hoshpoint-backend-app:production restart: unless-stopped env_file: - ${APP_ENV_FILE:-.env.production} environment: - <<: *app-proxy-environment APP_ENV: production APP_DEBUG: "false" LOG_CHANNEL: stderr @@ -63,7 +27,8 @@ services: build: context: . target: nginx - args: *build-args + args: + DOCKER_REGISTRY: docker.arvancloud.ir image: hoshpoint-backend-nginx:production restart: unless-stopped depends_on: @@ -81,7 +46,6 @@ services: env_file: - ${APP_ENV_FILE:-.env.production} environment: - <<: *app-proxy-environment APP_ENV: production APP_DEBUG: "false" LOG_CHANNEL: stderr @@ -102,7 +66,6 @@ services: env_file: - ${APP_ENV_FILE:-.env.production} environment: - <<: *app-proxy-environment APP_ENV: production APP_DEBUG: "false" LOG_CHANNEL: stderr diff --git a/docker/apt/configure-arvan-mirror.sh b/docker/apt/configure-arvan-mirror.sh deleted file mode 100644 index 62916e2..0000000 --- a/docker/apt/configure-arvan-mirror.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env sh -set -eu - -sources="/etc/apt/sources.list.d/debian.sources" - -if [ ! -f "$sources" ]; then - exit 0 -fi - -debian_mirror="${DEBIAN_APT_MIRROR:-}" -security_mirror="${DEBIAN_SECURITY_APT_MIRROR:-}" -disable_updates="${DEBIAN_APT_DISABLE_UPDATES:-false}" - -if [ -n "$debian_mirror" ]; then - sed -i \ - -e "s|^URIs: https\\?://deb\\.debian\\.org/debian$|URIs: $debian_mirror|g" \ - "$sources" -fi - -if [ -n "$security_mirror" ]; then - sed -i \ - -e "s|^URIs: https\\?://deb\\.debian\\.org/debian-security$|URIs: $security_mirror|g" \ - -e "s|^URIs: https\\?://security\\.debian\\.org/debian-security$|URIs: $security_mirror|g" \ - "$sources" -fi - -case "$disable_updates" in - 1|true|TRUE|yes|YES) - sed -i -e '/^Suites:/ s| bookworm-updates||g' "$sources" - ;; -esac diff --git a/docker/daemon.json.example b/docker/daemon.json.example deleted file mode 100644 index 445ceb2..0000000 --- a/docker/daemon.json.example +++ /dev/null @@ -1,3 +0,0 @@ -{ - "registry-mirrors": ["https://docker.arvancloud.ir"] -} diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index baa4dbc..6c3bbc9 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -25,14 +25,8 @@ if [ -z "${APP_KEY:-}" ]; then exit 1 fi -if [ "${APP_ENV:-production}" = "production" ]; then - if php artisan list --raw 2>/dev/null | grep -q '^l5-swagger:generate'; then - php artisan l5-swagger:generate --no-interaction - fi - - php artisan config:cache --no-interaction - php artisan event:cache --no-interaction - php artisan view:cache --no-interaction +if php artisan list --raw 2>/dev/null | grep -q '^l5-swagger:generate'; then + php artisan l5-swagger:generate --no-interaction fi exec "$@" diff --git a/docker/xray/config.example.json b/docker/xray/config.example.json deleted file mode 100644 index 3a0a93c..0000000 --- a/docker/xray/config.example.json +++ /dev/null @@ -1,234 +0,0 @@ -{ - "log": {}, - "inbounds": [ - { - "tag": "socks", - "settings": { - "userLevel": 8, - "auth": "noauth", - "udp": true - }, - "protocol": "socks", - "port": 55869, - "listen": "127.0.0.1", - "sniffing": { - "enabled": true, - "destOverride": [ - "tls", - "http", - "quic" - ], - "domainsExcluded": [ - "courier.push.apple.com" - ] - } - }, - { - "tag": "directSocks", - "protocol": "socks", - "settings": { - "userLevel": 8, - "auth": "noauth", - "udp": true - }, - "port": 1087, - "listen": "127.0.0.1" - }, - { - "tag": "api", - "protocol": "dokodemo-door", - "settings": { - "address": "[::1]" - }, - "port": 55870, - "listen": "[::1]" - } - ], - "outbounds": [ - { - "mux": { - "concurrency": 50, - "enabled": false, - "xudpConcurrency": 128, - "xudpProxyUDP443": "allow" - }, - "streamSettings": { - "xHttpSettings": { - "mode": "auto", - "path": "/", - "host": "main.treenix-ping.com", - "extra": { - "scMinPostsIntervalMs": "30", - "xPaddingBytes": "100-1000", - "scMaxEachPostBytes": "1000000" - } - }, - "network": "xhttp", - "security": "tls", - "tlsSettings": { - "allowInsecure": false, - "serverName": "main.treenix-ping.com", - "alpn": [ - "h2", - "http/1.1" - ], - "fingerprint": "chrome" - } - }, - "protocol": "vless", - "settings": { - "vnext": [ - { - "port": 443, - "address": "01d.ir", - "users": [ - { - "flow": "", - "level": 8, - "encryption": "mlkem768x25519plus.native.0rtt.Bf9R7vF7RcUZMTcA2Xa3RG0L85xr8QLVLbnzZaHcylA", - "email": "", - "id": "b7387661-1c9d-4f0b-9862-801cb5fa5a2c" - } - ] - } - ] - }, - "tag": "proxy" - }, - { - "streamSettings": { - "sockopt": { - "tcpNoDelay": true - } - }, - "protocol": "freedom", - "settings": { - "fragment": { - "length": "80-250", - "interval": "10-100", - "packets": "tlshello" - }, - "userLevel": 8 - }, - "tag": "fragment" - } - ], - "api": { - "tag": "api", - "services": [ - "StatsService" - ] - }, - "dns": { - "disableFallbackIfMatch": true, - "hosts": { - "dns.quad9.net": [ - "9.9.9.9", - "149.112.112.112", - "2620:fe::fe", - "2620:fe::9" - ], - "dns.cloudflare.com": [ - "104.16.132.229", - "104.16.133.229", - "2606:4700::6810:84e5", - "2606:4700::6810:85e5" - ], - "dns.google": [ - "8.8.8.8", - "8.8.4.4", - "2001:4860:4860::8888", - "2001:4860:4860::8844" - ], - "common.dot.dns.yandex.net": [ - "77.88.8.8", - "77.88.8.1", - "2a02:6b8::feed:0ff", - "2a02:6b8:0:1::feed:0ff" - ], - "cloudflare-dns.com": [ - "104.16.248.249", - "104.16.249.249", - "2606:4700::6810:f8f9", - "2606:4700::6810:f9f9" - ], - "dns.alidns.com": [ - "223.5.5.5", - "223.6.6.6", - "2400:3200::1", - "2400:3200:baba::1" - ], - "one.one.one.one": [ - "1.1.1.1", - "1.0.0.1", - "2606:4700:4700::1111", - "2606:4700:4700::1001" - ], - "dot.pub": [ - "1.12.12.12", - "120.53.53.53" - ] - }, - "disableCache": true, - "tag": "dnsQuery", - "disableFallback": true, - "queryStrategy": "UseIP", - "servers": [ - { - "address": "8.8.8.8", - "skipFallback": false - } - ] - }, - "stats": {}, - "routing": { - "domainStrategy": "AsIs", - "rules": [ - { - "outboundTag": "api", - "type": "field", - "inboundTag": [ - "api" - ], - "ruleTag": "rule-0" - }, - { - "outboundTag": "proxy", - "type": "field", - "inboundTag": [ - "dnsQuery" - ], - "ruleTag": "rule-1" - }, - { - "outboundTag": "direct", - "type": "field", - "inboundTag": [ - "directSocks" - ], - "ruleTag": "rule-2" - } - ], - "balancers": [] - }, - "policy": { - "system": { - "statsInboundUplink": true, - "statsInboundDownlink": true, - "statsOutboundDownlink": true, - "statsOutboundUplink": true - }, - "levels": { - "8": { - "uplinkOnly": 1, - "statsUserUplink": false, - "handshake": 4, - "bufferSize": 0, - "connIdle": 30, - "downlinkOnly": 1, - "statsUserDownlink": false - } - } - }, - "transport": {} -} \ No newline at end of file diff --git a/resources/css/app.css b/resources/css/app.css index 54b247e..62b9686 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -4,6 +4,6 @@ @source '../../storage/framework/views/*.php'; @theme { - --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', + --font-sans: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; } diff --git a/vite.config.js b/vite.config.js index 1fd66d5..f35b4e7 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,6 +1,5 @@ import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; -import { bunny } from 'laravel-vite-plugin/fonts'; import tailwindcss from '@tailwindcss/vite'; export default defineConfig({ @@ -8,11 +7,6 @@ export default defineConfig({ laravel({ input: ['resources/css/app.css', 'resources/js/app.js'], refresh: true, - fonts: [ - bunny('Instrument Sans', { - weights: [400, 500, 600], - }), - ], }), tailwindcss(), ],