x-benchmark: &benchmark
  restart: no
  labels:
    proxy.exclude: true
    proxy.#1.healthcheck.disable: true
services:
  app:
    image: godoxy-dev
    build:
      context: .
      dockerfile: dev.Dockerfile
    container_name: godoxy-proxy-dev
    restart: unless-stopped
    env_file: dev.env
    environment:
      DOCKER_HOST: unix:///var/run/docker.sock
      TZ: Asia/Hong_Kong
      API_ADDR: 127.0.0.1:8999
      API_USER: dev
      API_PASSWORD: 1234
      API_SKIP_ORIGIN_CHECK: true
      API_JWT_TTL: 24h
      DEBUG: true
      API_JWT_SECRET: 1234567891234567
    labels:
      proxy.exclude: true
      proxy.#1.healthcheck.disable: true
    ipc: host
    network_mode: host
    volumes:
      - ./bin/godoxy:/app/run:ro
      - /var/run/docker.sock:/var/run/docker.sock
      - ./dev-data/config:/app/config
      - ./dev-data/certs:/app/certs
      - ./dev-data/error_pages:/app/error_pages:ro
      - ./dev-data/data:/app/data
      - ./dev-data/logs:/app/logs
      - ~/certs/myCA.pem:/etc/ssl/certs/ca.crt:ro
  parca:
    image: ghcr.io/parca-dev/parca:v0.24.2
    container_name: godoxy-parca
    restart: unless-stopped
    command: [/parca, --config-path, /parca.yaml]
    network_mode: host
    # ports:
    #   - 7070:7070
    configs:
      - source: parca
        target: /parca.yaml
    labels:
      proxy.#1.port: "7070"
  tinyauth:
    image: ghcr.io/steveiliop56/tinyauth:v3
    container_name: tinyauth
    restart: unless-stopped
    environment:
      - SECRET=12345678912345671234567891234567
      - APP_URL=https://tinyauth.my.app
      - USERS=user:$$2a$$10$$UdLYoJ5lgPsC0RKqYH/jMua7zIn0g9kPqWmhYayJYLaZQ/FTmH2/u # user:password
    labels:
      proxy.tinyauth.port: "3000"
  jotty: # issue #182
    image: ghcr.io/fccview/jotty:latest
    container_name: jotty
    user: "1000:1000"
    tmpfs:
      - /app/data:rw,uid=1000,gid=1000
      - /app/config:rw,uid=1000,gid=1000
      - /app/.next/cache:rw,uid=1000,gid=1000
    restart: unless-stopped
    environment:
      - NODE_ENV=production
    labels:
      proxy.aliases: "jotty.my.app"
  postgres-test:
    image: postgres:18-alpine
    container_name: postgres-test
    restart: unless-stopped
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
  h2c_test_server:
    build:
      context: cmd/h2c_test_server
      dockerfile: Dockerfile
    container_name: h2c_test
    restart: unless-stopped
    labels:
      proxy.#1.scheme: h2c
      proxy.#1.port: 80
  bench: # returns 4096 bytes of random data
    <<: *benchmark
    build:
      context: cmd/bench_server
      dockerfile: Dockerfile
    container_name: bench
  godoxy:
    <<: *benchmark
    build: .
    container_name: godoxy-benchmark
    ports:
      - 8080:80
    configs:
      - source: godoxy_config
        target: /app/config/config.yml
      - source: godoxy_provider
        target: /app/config/providers.yml
  traefik:
    <<: *benchmark
    image: traefik:latest
    container_name: traefik
    command:
      - --api.insecure=true
      - --entrypoints.web.address=:8081
      - --providers.file.directory=/etc/traefik/dynamic
      - --providers.file.watch=true
      - --log.level=ERROR
    ports:
      - 8081:8081
    configs:
      - source: traefik_config
        target: /etc/traefik/dynamic/routes.yml
  caddy:
    <<: *benchmark
    image: caddy:latest
    container_name: caddy
    ports:
      - 8082:80
    configs:
      - source: caddy_config
        target: /etc/caddy/Caddyfile
    tmpfs:
      - /data
      - /config
  nginx:
    <<: *benchmark
    image: nginx:latest
    container_name: nginx
    command: nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
    ports:
      - 8083:80
    configs:
      - source: nginx_config
        target: /etc/nginx/nginx.conf

configs:
  godoxy_config:
    content: |
      providers:
        include:
          - providers.yml
  godoxy_provider:
    content: |
      bench.domain.com:
        host: bench
  traefik_config:
    content: |
      http:
        routers:
          bench:
            rule: "Host(`bench.domain.com`)"
            entryPoints:
              - web
            service: bench
        services:
          bench:
            loadBalancer:
              servers:
                - url: "http://bench:80"
  caddy_config:
    content: |
      {
        admin off
        auto_https off
        default_bind 0.0.0.0

        servers {
          protocols h1 h2c
        }
      }

      http://bench.domain.com {
        reverse_proxy bench:80
      }
  nginx_config:
    content: |
      worker_processes auto;
      worker_rlimit_nofile 65535;
      error_log /dev/null;
      pid /var/run/nginx.pid;

      events {
        worker_connections 10240;
        multi_accept on;
        use epoll;
      }

      http {
        include /etc/nginx/mime.types;
        default_type application/octet-stream;
        
        access_log off;
        
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        keepalive_requests 10000;
        
        upstream backend {
          server bench:80;
          keepalive 128;
        }

        server {
          listen 80 default_server;
          server_name _;
          http2 on;

          return 404;
        }

        server {
          listen 80;
          server_name bench.domain.com;
          http2 on;
          
          location / {
            proxy_pass http://backend;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            proxy_set_header Host $$host;
            proxy_set_header X-Real-IP $$remote_addr;
            proxy_set_header X-Forwarded-For $$proxy_add_x_forwarded_for;
            proxy_buffering off;
          }
        }
      }
  parca:
    content: |
      object_storage:
        bucket:
          type: "FILESYSTEM"
          config:
            directory: "./data"
      scrape_configs:
        - job_name: "parca"
          scrape_interval: "1s"
          static_configs:
            - targets: [ 'localhost:7777' ]
