Managing and Updating `config.json` in Production: Best Practices for geoip

Store config.json under version control, validate it through CI pipelines, and use environment-specific overlays to keep the loyalsoldier/geoip configuration reliable, auditable, and safely updatable.

The config.json file serves as the central blueprint that defines all input sources and output targets for the loyalsoldier/geoip CLI tool. In production environments, maintaining this configuration requires strict discipline to prevent breaking changes, ensure reproducibility, and protect sensitive credentials. Implementing robust management practices for config.json ensures that your IP geolocation data pipeline remains stable and maintainable across deployments.

Version Control and Auditability

Tracking every modification to config.json is essential for maintaining a reliable production pipeline.

Tracking Changes with Git

Store the base configuration file in your Git repository to create an immutable history of all modifications. The loyalsoldier/geoip project maintains its default configuration at the repository root, allowing teams to review changes through pull requests before merging. This practice enables rapid rollbacks when a new input source or output filter introduces unexpected behavior.

Documenting Configuration Intent

Every entry in config.json should include clear documentation explaining why a specific list was added, its source authority, and any applied filters such as onlyIPType or wantedList. Maintain a separate CHANGELOG.md or detailed section in your internal documentation that maps configuration changes to business requirements. The repository's configuration.md file serves as the canonical reference for understanding supported input and output formats.

Environment Isolation and Security

Production environments require isolation from development settings and protection of sensitive credentials.

Using Overlay Files for Environment Overrides

Create environment-specific override files such as config.prod.json or config.staging.json that extend the base configuration rather than duplicating it. Use jq to merge these layers dynamically, keeping environment-specific URIs and file paths separate from the version-controlled base file.


# Merge base config with production overrides

jq -s '.[0] * .[1]' config.json /secure/config.prod.json > config.merged.json
geoip run -c config.merged.json

This approach keeps the base config.json in the repository while storing sensitive overrides in secure locations accessible only to specific environments.

Protecting Credentials with Environment Variables

Never embed authentication tokens or passwords directly in config.json. The repository's .gitignore already excludes .env files to prevent accidental commits. Store required tokens in environment variables and inject them at runtime, as the CLI reads variables via os.Getenv.

Validation and Pre-Deployment Checks

Validating configuration syntax and semantics before deployment prevents service interruptions.

Schema Validation Using lib/config.go

The lib/config.go file handles JSON unmarshalling and action validation (lines 55–78). Create a validation step in your deployment pipeline that uses the same logic as the production binary to catch malformed JSON or invalid action types before they reach production.

package main

import (
    "log"
    "github.com/loyalsoldier/geoip/lib"
)

func main() {
    cfg, err := lib.LoadConfig("config.json")
    if err != nil {
        log.Fatalf("invalid config: %v", err)
    }
    log.Printf("config OK – %d inputs, %d outputs", len(cfg.Input), len(cfg.Output))
}

CI Pipeline Integration

Extend the existing GitHub workflow in .github/workflows/build.yml to execute configuration validation on every pull request. Add a step that runs go vet, go test, and a custom validation command to ensure the configuration loads correctly.

- name: Validate config.json
  run: |
    go run ./cmd/validate-config -c config.json

Data Integrity and Immutability

Remote data sources and generated artifacts require version pinning and backup strategies.

Pinning Remote Resources to Specific Versions

Many config.json entries reference remote resources via uri fields. Pin these to specific commit SHAs or release tags rather than using moving branches like master. This prevents breaking changes when upstream sources modify their data formats.

{
  "type": "text",
  "action": "add",
  "args": {
    "name": "cn",
    "uri": "https://raw.githubusercontent.com/17mon/china_ip_list/v2024-01-01/china_ip_list.txt",
    "onlyIPType": "ipv4"
  }
}

Backup Strategies for Generated Artifacts

The geoip tool generates binary and text files such as output/geoip.dat. Implement versioned storage using directory structures (output/v1/, output/v2/) or immutable object storage to preserve previous builds. This enables rapid rollback if a configuration change unintentionally excludes critical IP ranges.

Deployment Automation

Manual configuration updates introduce human error and inconsistency.

Incremental Update Strategies

Avoid large monolithic configuration changes that are difficult to review. Add or remove single blocks—such as one new json source—and run the CLI locally using geoip run -c config.json to verify the effect before committing. This incremental approach reduces the blast radius of configuration errors.

Automated Regeneration Workflows

Production environments should never rely on manual binary execution. Integrate geoip run -c config.json into scheduled jobs, container entrypoints, or orchestration pipelines. Since the binary reads the configuration at startup, updating the file automatically refreshes the generated artifacts without requiring process restarts or complex deployment rituals.

Summary

  • Version control config.json using Git to maintain audit trails and enable rollbacks through pull requests.
  • Separate environment-specific settings using overlay files merged with jq, keeping production URIs and paths out of the base repository.
  • Validate configurations before deployment using lib.LoadConfig from lib/config.go to catch schema errors early.
  • Pin remote data sources to specific tags or commit SHAs to prevent upstream changes from breaking your pipeline.
  • Protect secrets using environment variables rather than embedding credentials in JSON files.
  • Automate the regeneration process through CI/CD pipelines and scheduled jobs to eliminate manual intervention.

Frequently Asked Questions

How do I validate config.json before deploying to production?

Use the lib.LoadConfig function from lib/config.go to programmatically validate the file. This function unmarshals the JSON and validates all actions (lines 66–78), returning an error if the configuration contains invalid syntax or unsupported action types. Run this validation as part of your CI pipeline to block deployments of malformed configurations.

What is the best way to handle secrets in geoip configuration files?

Store authentication tokens and sensitive URIs in environment variables rather than in config.json. The loyalsoldier/geoip CLI reads these variables at runtime via os.Getenv. Keep environment-specific override files in secure storage outside version control, and merge them with the base configuration at deployment time using tools like jq.

How can I test configuration changes without affecting production data?

Create environment-specific overlay files (e.g., config.staging.json) that modify input sources or output paths for testing purposes. Merge these with your base configuration and run the CLI locally or in a staging environment. This approach allows you to verify that new sources or filters generate the expected datasets without risking production artifacts.

Should I pin remote data sources to specific versions?

Yes. Instead of referencing moving branches like master in uri fields, pin to specific release tags or commit SHAs (e.g., v2024-01-01). This practice ensures reproducible builds by preventing upstream repositories from introducing breaking changes or data removals that could corrupt your generated geoip databases.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →