Referensi

CaptchaAI dalam Production: Manajemen Konfigurasi

API key dan timeout yang di-hardcode berfungsi untuk prototipe. Production memerlukan konfigurasi spesifik per lingkungan, secret management, dan kemampuan mengubah pengaturan tanpa re-deploy.

Hierarki Konfigurasi

Priority (highest → lowest):

1. Environment variables     ← deployment-specific overrides
2. Config file (YAML/JSON)   ← version-controlled defaults
3. Application defaults      ← fallback values in code

Referensi Konfigurasi Lengkap

Parameter Env Variable Default Deskripsi
API Key CAPTCHAAI_API_KEY Wajib. API key CaptchaAI Anda
Submit URL CAPTCHAAI_SUBMIT_URL https://ocr.captchaai.com/in.php Endpoint submit task
Poll URL CAPTCHAAI_POLL_URL https://ocr.captchaai.com/res.php Endpoint polling hasil
Interval poll CAPTCHAAI_POLL_INTERVAL 5 Detik antar polling
Maks poll CAPTCHAAI_MAX_POLLS 60 Maksimum polling sebelum timeout
Concurrency CAPTCHAAI_CONCURRENCY 10 Maksimum task CAPTCHA paralel
Timeout CAPTCHAAI_TIMEOUT 300 Timeout keseluruhan dalam detik
Proxy CAPTCHAAI_PROXY URL proxy untuk solve CAPTCHA
Callback URL CAPTCHAAI_CALLBACK_URL URL webhook untuk hasil async
Retry CAPTCHAAI_RETRIES 3 Percobaan ulang untuk kegagalan sementara
Log level CAPTCHAAI_LOG_LEVEL info Verbositas logging

Config Loader

Python

import os
import yaml
from dataclasses import dataclass, field
from pathlib import Path


@dataclass
class CaptchaAIConfig:
    api_key: str = ""
    submit_url: str = "https://ocr.captchaai.com/in.php"
    poll_url: str = "https://ocr.captchaai.com/res.php"
    poll_interval: int = 5
    max_polls: int = 60
    concurrency: int = 10
    timeout: int = 300
    proxy: str = ""
    callback_url: str = ""
    retries: int = 3
    log_level: str = "info"

    @classmethod
    def load(cls, config_path=None):
        """Load config: env vars override file, which overrides defaults."""
        config = cls()

        # Layer 2: Config file
        if config_path and Path(config_path).exists():
            with open(config_path) as f:
                file_config = yaml.safe_load(f) or {}
            for key, value in file_config.items():
                if hasattr(config, key):
                    setattr(config, key, value)

        # Layer 1: Environment variables (highest priority)
        env_map = {
            "CAPTCHAAI_API_KEY": "api_key",
            "CAPTCHAAI_SUBMIT_URL": "submit_url",
            "CAPTCHAAI_POLL_URL": "poll_url",
            "CAPTCHAAI_POLL_INTERVAL": "poll_interval",
            "CAPTCHAAI_MAX_POLLS": "max_polls",
            "CAPTCHAAI_CONCURRENCY": "concurrency",
            "CAPTCHAAI_TIMEOUT": "timeout",
            "CAPTCHAAI_PROXY": "proxy",
            "CAPTCHAAI_CALLBACK_URL": "callback_url",
            "CAPTCHAAI_RETRIES": "retries",
            "CAPTCHAAI_LOG_LEVEL": "log_level",
        }

        for env_key, attr_name in env_map.items():
            value = os.environ.get(env_key)
            if value is not None:
                # Cast to correct type
                current = getattr(config, attr_name)
                if isinstance(current, int):
                    value = int(value)
                setattr(config, attr_name, value)

        config.validate()
        return config

    def validate(self):
        if not self.api_key:
            raise ValueError("CAPTCHAAI_API_KEY is required")
        if self.poll_interval < 1:
            raise ValueError("poll_interval must be >= 1")
        if self.concurrency < 1:
            raise ValueError("concurrency must be >= 1")


# Usage
config = CaptchaAIConfig.load("config/captchaai.yaml")
print(f"Concurrency: {config.concurrency}, Timeout: {config.timeout}s")

JavaScript

const fs = require("fs");
const yaml = require("js-yaml");
const path = require("path");

class CaptchaAIConfig {
  static defaults = {
    apiKey: "",
    submitUrl: "https://ocr.captchaai.com/in.php",
    pollUrl: "https://ocr.captchaai.com/res.php",
    pollInterval: 5,
    maxPolls: 60,
    concurrency: 10,
    timeout: 300,
    proxy: "",
    callbackUrl: "",
    retries: 3,
    logLevel: "info",
  };

  static envMap = {
    CAPTCHAAI_API_KEY: "apiKey",
    CAPTCHAAI_SUBMIT_URL: "submitUrl",
    CAPTCHAAI_POLL_URL: "pollUrl",
    CAPTCHAAI_POLL_INTERVAL: { key: "pollInterval", type: "int" },
    CAPTCHAAI_MAX_POLLS: { key: "maxPolls", type: "int" },
    CAPTCHAAI_CONCURRENCY: { key: "concurrency", type: "int" },
    CAPTCHAAI_TIMEOUT: { key: "timeout", type: "int" },
    CAPTCHAAI_PROXY: "proxy",
    CAPTCHAAI_CALLBACK_URL: "callbackUrl",
    CAPTCHAAI_RETRIES: { key: "retries", type: "int" },
    CAPTCHAAI_LOG_LEVEL: "logLevel",
  };

  static load(configPath = null) {
    let config = { ...CaptchaAIConfig.defaults };

    // Layer 2: Config file
    if (configPath && fs.existsSync(configPath)) {
      const ext = path.extname(configPath);
      const raw = fs.readFileSync(configPath, "utf8");
      const fileConfig = ext === ".json" ? JSON.parse(raw) : yaml.load(raw);
      config = { ...config, ...fileConfig };
    }

    // Layer 1: Environment variables
    for (const [envKey, mapping] of Object.entries(CaptchaAIConfig.envMap)) {
      const value = process.env[envKey];
      if (value !== undefined) {
        const attrKey = typeof mapping === "string" ? mapping : mapping.key;
        const type = typeof mapping === "string" ? "string" : mapping.type;
        config[attrKey] = type === "int" ? parseInt(value, 10) : value;
      }
    }

    CaptchaAIConfig.validate(config);
    return config;
  }

  static validate(config) {
    if (!config.apiKey) throw new Error("CAPTCHAAI_API_KEY is required");
    if (config.pollInterval < 1) throw new Error("pollInterval must be >= 1");
    if (config.concurrency < 1) throw new Error("concurrency must be >= 1");
  }
}

// Usage
const config = CaptchaAIConfig.load("config/captchaai.yaml");
console.log(`Concurrency: ${config.concurrency}, Timeout: ${config.timeout}s`);

File Konfigurasi Per Lingkungan

# config/captchaai.yaml — base
api_key: ""  # Selalu set via env var
concurrency: 5
poll_interval: 5
retries: 3
log_level: info
# config/captchaai.production.yaml
concurrency: 20
poll_interval: 3
timeout: 180
log_level: warning
# config/captchaai.staging.yaml
concurrency: 3
poll_interval: 5
timeout: 300
log_level: debug

Secret Management

Jangan pernah menyimpan API key di file konfigurasi atau version control.

Metode Terbaik untuk Contoh
Environment variable Container, CI/CD export CAPTCHAAI_API_KEY=abc123
AWS Secrets Manager Infrastruktur AWS Ambil saat startup; rotasi otomatis
HashiCorp Vault Multi-cloud, on-prem Dynamic secret dengan TTL
Docker Secrets Docker Swarm/Compose Di-mount di /run/secrets/
File .env (dev only) Development lokal Library dotenv; tambahkan ke .gitignore

Contoh Penulisan Docker

services:
  captcha-worker:
    image: captcha-worker:latest
    environment:

      - CAPTCHAAI_API_KEY=${CAPTCHAAI_API_KEY}
      - CAPTCHAAI_CONCURRENCY=15
      - CAPTCHAAI_LOG_LEVEL=warning
    env_file:

      - .env.production

Feature Flag

Alihkan kemampuan tanpa re-deploy:

class FeatureFlags:
    def __init__(self):
        self.flags = {
            "use_callback": os.environ.get("FF_USE_CALLBACK", "false") == "true",
            "enable_proxy": os.environ.get("FF_ENABLE_PROXY", "true") == "true",
            "max_concurrent": int(os.environ.get("FF_MAX_CONCURRENT", "10")),
        }

    def is_enabled(self, flag):
        return self.flags.get(flag, False)

    def get(self, flag, default=None):
        return self.flags.get(flag, default)

Pemecahan Masalah

Masalah Penyebab Solusi
API key tidak termuat Env var tidak ada; nama variabel salah Cek echo $CAPTCHAAI_API_KEY; verifikasi ejaan
File konfigurasi diabaikan Path salah atau library YAML tidak ada Verifikasi file ada; install pyyaml / js-yaml
Production menggunakan pengaturan dev Override spesifik lingkungan tidak diterapkan Cek prioritas env var; verifikasi NODE_ENV / APP_ENV
Secret terlihat di log Config dump menyertakan API key Mask field sensitif dalam output log

Pertanyaan Umum

Haruskah saya menggunakan YAML atau JSON untuk file konfigurasi?

YAML untuk file yang diedit manusia (mendukung komentar). JSON untuk konfigurasi yang dihasilkan mesin atau saat Anda ingin parsing yang ketat.

Seberapa sering saya harus rotasi API key?

Rotasi segera jika dikompromikan. Jadwalkan rotasi setiap 90 hari untuk compliance. Gunakan secret manager yang mendukung rotasi otomatis.

Bisakah saya mengubah concurrency tanpa restart?

Ya — baca pengaturan dari environment variable atau config service di setiap batch task, bukan hanya saat startup. Ini memungkinkan Anda menyesuaikan concurrency dengan memperbarui env var dan mengirim sinyal reload.


Artikel Terkait


Siapkan konfigurasi production Anda — mulai dengan API key CaptchaAI dan buat dari template konfigurasi di atas.

Komentar dinonaktifkan untuk artikel ini.