{"id":10266,"date":"2026-03-23T10:52:51","date_gmt":"2026-03-23T13:52:51","guid":{"rendered":"https:\/\/www.fernandoquadro.com.br\/html\/?p=10266"},"modified":"2026-03-23T10:52:51","modified_gmt":"2026-03-23T13:52:51","slug":"como-criar-seu-proprio-catalogo-stac","status":"publish","type":"post","link":"https:\/\/www.fernandoquadro.com.br\/html\/2026\/03\/23\/como-criar-seu-proprio-catalogo-stac\/","title":{"rendered":"Como criar seu pr\u00f3prio Cat\u00e1logo STAC"},"content":{"rendered":"<p>Prezado leitor,<\/p>\n<p>Se voc\u00ea trabalha com dados geoespaciais, principalmente rasters, provavelmente j\u00e1 esbarrou em problemas como:<\/p>\n<ul>\n<li>Dificuldade de organizar grandes volumes de dados<\/li>\n<li>Falta de padroniza\u00e7\u00e3o na publica\u00e7\u00e3o<\/li>\n<li>APIs pouco eficientes para busca espacial\/temporal<\/li>\n<\/ul>\n<p>\u00c9 exatamente aqui que entra o <strong>STAC (SpatioTemporal Asset Catalog)<\/strong>. Mais do que um formato, o STAC <strong>\u00e9 um padr\u00e3o moderno para organizar, catalogar e acessar dados geoespaciais<\/strong>, permitindo buscas r\u00e1pidas e interoper\u00e1veis.<\/p>\n<p>Neste guia, voc\u00ea vai aprender a montar um ambiente completo para:<\/p>\n<ul>\n<li>Organizar seus dados no padr\u00e3o STAC<\/li>\n<li>Publicar via API moderna<\/li>\n<li>Integrar com o GeoServer<\/li>\n<li>Servir dados raster (COG) de forma eficiente<\/li>\n<\/ul>\n<p>Este post apresenta, passo a passo, como montar um ambiente completo para cria\u00e7\u00e3o e publica\u00e7\u00e3o de um cat\u00e1logo STAC (SpatioTemporal Asset Catalog), utilizando Docker, PostGIS, GeoServer e uma API intermedi\u00e1ria (adapter). O objetivo \u00e9 permitir que voc\u00ea organize, publique e consuma dados geoespaciais modernos de forma eficiente.<\/p>\n<p>Antes de come\u00e7ar, \u00e9 importante entender o papel de cada componente:<\/p>\n<ul>\n<li><strong>PostGIS <\/strong>\u2192 Armazena os metadados espaciais<\/li>\n<li><strong>pgSTAC <\/strong>\u2192 Implementa o padr\u00e3o STAC dentro do PostgreSQL<\/li>\n<li><strong>STAC FastAPI<\/strong> \u2192 Exp\u00f5e os dados via API REST<\/li>\n<li><strong>GeoServer<\/strong> \u2192 Publica e renderiza os dados<\/li>\n<li><strong>Adapter (FastAPI)<\/strong> \u2192 Traduz STAC para o formato esperado pelo GeoServer<\/li>\n<\/ul>\n<p>Um ponto importante: o GeoServer ainda n\u00e3o consome STAC \u201cpuro\u201d de forma completa, por isso o uso do adapter \u00e9 essencial.<\/p>\n<p><strong><\/p>\n<h3>1. Atualiza\u00e7\u00e3o do sistema<\/h3>\n<p><\/strong><\/p>\n<p>Antes de instalar qualquer ferramenta, \u00e9 importante garantir que o sistema esteja atualizado. Isso evita problemas de depend\u00eancia e incompatibilidade.<\/p>\n<pre>\r\n> sudo apt update\r\n> sudo apt upgrade -y\r\n<\/pre>\n<p><strong><\/p>\n<h3>2. Instala\u00e7\u00e3o do Docker<\/h3>\n<p><\/strong><\/p>\n<p>O Docker ser\u00e1 usado para isolar cada componente da arquitetura, garantindo reprodutibilidade. Isso evita conflitos de vers\u00e3o e facilita deploy em outros ambientes.<\/p>\n<p>2.1 Adicionar chave GPG:<\/p>\n<pre>\r\n> curl -fsSL https:\/\/download.docker.com\/linux\/ubuntu\/gpg | \\\r\n> sudo gpg --dearmor -o \/usr\/share\/keyrings\/docker-archive-keyring.gpg\r\n<\/pre>\n<p>2.2 Adicionar reposit\u00f3rio:<\/p>\n<pre>\r\necho \\\r\n\"deb [arch=$(dpkg --print-architecture) signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg] https:\/\/download.docker.com\/linux\/ubuntu \\ $(lsb_release -cs) stable\" | \\ sudo tee \/etc\/apt\/sources.list.d\/docker.list > \/dev\/null\r\n<\/pre>\n<p>2.3 Instalar Docker + Compose:<\/p>\n<pre>\r\n> sudo apt update\r\n> sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y\r\n<\/pre>\n<p>Com isso, voc\u00ea ter\u00e1 um ambiente isolado para rodar toda a stack sem conflitos de vers\u00e3o.<\/p>\n<p><strong><\/p>\n<h3>3. Estrutura do projeto<\/h3>\n<p><\/strong><\/p>\n<p>Agora vamos organizar os diret\u00f3rios do projeto:<\/p>\n<pre>\r\n> sudo mkdir -p \/docker\/geoserver\/plugins\r\n> cd \/docker\/geoserver\/plugins\r\n<\/pre>\n<p><strong><\/p>\n<h3>4. Download dos plugins do GeoServer<\/h3>\n<p><\/strong><\/p>\n<p>O plugins que iremos realizar o download adicionam suporte a:<\/p>\n<ul>\n<li>COG (Cloud Optimized GeoTIFF) via HTTP\/S3<\/li>\n<li>Integra\u00e7\u00e3o com STAC<\/li>\n<\/ul>\n<p>Sem esses plugins, o GeoServer n\u00e3o consegue trabalhar corretamente com dados cloud-native.<\/p>\n<pre>\r\n> wget https:\/\/build.geoserver.org\/geoserver\/2.27.x\/community-latest\/geoserver-2.27-SNAPSHOT-cog-http-plugin.zip\r\n> wget https:\/\/build.geoserver.org\/geoserver\/2.27.x\/community-latest\/geoserver-2.27-SNAPSHOT-cog-s3-plugin.zip\r\n> wget https:\/\/build.geoserver.org\/geoserver\/2.27.x\/community-latest\/geoserver-2.27-SNAPSHOT-stac-datastore-plugin.zip\r\n<\/pre>\n<p><strong><\/p>\n<h3>5. Dockerfile do GeoServer<\/h3>\n<p><\/strong><\/p>\n<p>Criamos um Dockerfile para incluir os plugins:<\/p>\n<pre>\r\ncd \/docker\/geoserver\r\nnano Dockerfile\r\n<\/pre>\n<p>O conte\u00fado do arquivo:<\/p>\n<pre>\r\nFROM docker.osgeo.org\/geoserver:2.27.2\r\n\r\nCOPY plugins\/*.jar \/usr\/local\/tomcat\/webapps\/geoserver\/WEB-INF\/lib\/\r\n<\/pre>\n<p>Aqui estamos estendendo a imagem padr\u00e3o do GeoServer para suportar STAC e COG.<\/p>\n<p><strong><\/p>\n<h3>6. Arquivo Docker Compose<\/h3>\n<p><\/strong><\/p>\n<p>Agora definimos toda a infraestrutura: Banco de dados (PostGIS), API STAC e GeoServer. Vamos ent\u00e3o criar o arquivo docker-compose.yaml:<\/p>\n<pre>\r\ncd \/docker\r\nnano docker-compose.yaml\r\n<\/pre>\n<p>Esse arquivo \u00e9 o cora\u00e7\u00e3o da infraestrutura, ele define como os servi\u00e7os se comunicam e persistem dados. O conte\u00fado do arquivo:<\/p>\n<pre>\r\nvolumes:\r\n  postgis-data:\r\n  geoserver-data:\r\n\r\nnetworks:\r\n  internal:\r\n  external:\r\n\r\nservices:\r\n\r\n  db:\r\n    container_name: postgis\r\n    image: postgis\/postgis:16-3.4\r\n    volumes:\r\n      - postgis-data:\/var\/lib\/postgresql\/data\r\n    environment:\r\n      - POSTGRES_DB=postgis\r\n      - POSTGRES_USER=postgis\r\n      - POSTGRES_PASSWORD=senha_postgis\r\n      - IP_LIST=*\r\n      - ALLOW_IP_RANGE=0.0.0.0\/0\r\n      - POSTGRES_MULTIPLE_EXTENSIONS=postgis,hstore,postgis_topology,postgis_raster,pgrouting,btree_gist\r\n      - FORCE_SSL=false\r\n    ports:\r\n      - \"5432:5432\"\r\n    restart: unless-stopped\r\n    healthcheck:\r\n      test: [\"CMD-SHELL\", \"pg_isready -U postgis-d postgis\"]\r\n      interval: 5s\r\n      timeout: 5s\r\n      retries: 10\r\n    networks:\r\n      - internal\r\n\r\n  geoserver:\r\n    container_name: geoserver\r\n    build: .\/geoserver\r\n    volumes:\r\n      - geoserver-data:\/opt\/geoserver\/data_dir\r\n      - \/docker\/geoserver\/imagem_raster:\/opt\/geoserver\/data_dir\/coverages\r\n    environment:\r\n      - TZ=America\/Sao_Paulo\r\n      - GEOSERVER_ADMIN_USER=admin\r\n      - GEOSERVER_ADMIN_PASSWORD=geoserver\r\n      - INSTALL_EXTENSIONS=true\r\n      - EXTRA_JAVA_OPTS=-Xms4G -Xmx6G\r\n      - STABLE_EXTENSIONS=importer,wps,pyramid\r\n      - PROXY_BASE_URL=http:\/\/192.168.186.140:8083\/geoserver\r\n      - GEOSERVER_CSRF_WHITELIST=192.168.186.140\r\n      - HTTP_SCHEME=http\r\n      - CORS_ENABLED=false\r\n    ports:\r\n      - \"8083:8080\"\r\n    restart: unless-stopped\r\n    healthcheck:\r\n      test: curl --fail \"http:\/\/localhost:8080\/geoserver\/web\/wicket\/resource\/org.geoserver.web.GeoServerBasePage\/img\/logo.png\" || exit 1\r\n      interval: 1m30s\r\n      timeout: 10s\r\n      retries: 3\r\n    networks:\r\n      - internal\r\n      - external\r\n\r\n  stac:\r\n    container_name: stac-api\r\n    image: ghcr.io\/stac-utils\/stac-fastapi-pgstac:latest\r\n    environment:\r\n      - PGHOST=db\r\n      - PGPORT=5432\r\n      - PGDATABASE=postgis\r\n      - PGUSER=postgis\r\n      - PGPASSWORD=senha_postgis\r\n    ports:\r\n      - \"8085:8080\"\r\n    depends_on:\r\n      db:\r\n        condition: service_healthy\r\n    networks:\r\n      - internal\r\n<\/pre>\n<p>Agora \u00e9 subir o ambiente:<\/p>\n<pre>\r\n> docker compose build\r\n> docker compose up -d\r\n<\/pre>\n<p><strong><\/p>\n<h3>7. Criar banco STAC (pgstac)<\/h3>\n<p><\/strong><\/p>\n<p>Instalar a ferramenta: <\/p>\n<pre>\r\nsudo apt install -y pipx\r\npipx ensurepath\r\nsource ~\/.bashrc\r\npipx install \"pypgstac[psycopg]\"\r\n<\/pre>\n<p>Configurar conex\u00e3o:<\/p>\n<pre>\r\nexport PGHOST=127.0.0.1\r\nexport PGPORT=5432\r\nexport PGDATABASE=postgis\r\nexport PGUSER=postgis\r\nexport PGPASSWORD=senha_postgis\r\n<\/pre>\n<p>Rodar migra\u00e7\u00e3o:<\/p>\n<pre>\r\n> pypgstac migrate\r\n<\/pre>\n<p>Esse comando cria toda a estrutura STAC dentro do banco:<\/p>\n<ul>\n<li>Tabelas de collections<\/li>\n<li>Tabelas de items<\/li>\n<li>\u00cdndices espaciais e temporais<\/li>\n<\/ul>\n<p>Sem isso, a API STAC n\u00e3o consegue funcionar.<\/p>\n<p><strong><\/p>\n<h3>8. Criar Collection<\/h3>\n<p><\/strong><\/p>\n<p>Collections funcionam como agrupadores l\u00f3gicos de dados. Exemplos: Sentinel-2, Ortofotos, Modelos de eleva\u00e7\u00e3o.<\/p>\n<p>Crie o arquivo:<\/p>\n<pre>\r\nnano collection.json\r\n<\/pre>\n<p>Conte\u00fado do arquivo:<\/p>\n<pre>\r\n{\r\n  \"id\": \"raster-test\",\r\n  \"type\": \"Collection\",\r\n  \"description\": \"Teste de raster\",\r\n  \"license\": \"proprietary\",\r\n  \"extent\": {\r\n    \"spatial\": { \"bbox\": [[-180, -90, 180, 90]] },\r\n    \"temporal\": { \"interval\": [[\"2024-01-01T00:00:00Z\", null]] }\r\n  }\r\n}\r\n<\/pre>\n<p>Para inserir no banco, execute o comando abaixo:<\/p>\n<pre>\r\npypgstac load collections collection.json\r\n<\/pre>\n<p><strong><\/p>\n<h3>9. Criar itens<\/h3>\n<p><\/strong><\/p>\n<p>Os Items representam os dados reais. Exemplo: Um raster espec\u00edfico, um ortomosaico, uma cena de sat\u00e9lite.<\/p>\n<p>Crie o arquivo:<\/p>\n<pre>\r\nnano item.json\r\n<\/pre>\n<p>Conte\u00fado do arquivo:<\/p>\n<pre>\r\n{\r\n  \"type\": \"Feature\",\r\n  \"stac_version\": \"1.0.0\",\r\n  \"id\": \"paraiso-ortomosaico\",\r\n  \"collection\": \"raster-test\",\r\n  \"geometry\": {\r\n    \"type\": \"Polygon\",\r\n    \"coordinates\": [[\r\n      [-48.8961561, -25.0593974],\r\n      [-48.8764276, -25.0593974],\r\n      [-48.8764276, -25.0730781],\r\n      [-48.8961561, -25.0730781],\r\n      [-48.8961561, -25.0593974]\r\n    ]]\r\n  },\r\n  \"bbox\": [-48.8961561,-25.0730781,-48.8764276,-25.0593974],\r\n  \"properties\": {\r\n    \"datetime\": \"2024-01-01T00:00:00Z\",\r\n    \"proj:epsg\": 4326\r\n  },\r\n  \"assets\": {\r\n    \"data\": {\r\n      \"href\": \"http:\/\/SEU_IP:9000\/rasters\/seu_arquivo.tif\",\r\n      \"type\": \"image\/tiff\",\r\n      \"roles\": [\"data\"]\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>Inserir item no banco:<\/p>\n<pre>\r\npypgstac load items item.json\r\n<\/pre>\n<p>Se voc\u00ea precisar editar o conte\u00fado do json e realizar um update no banco, use o seguinte comando:<\/p>\n<pre>\r\npypgstac load items item.json --method upsert\r\n<\/pre>\n<p>Voc\u00ea ainda tem uma outra op\u00e7\u00e3o que \u00e9 a cria\u00e7\u00e3o autom\u00e1tico do arquivo json atrav\u00e9s do rio-stac, para isso voc\u00ea precisa:<\/p>\n<pre>\r\npipx install rio-stac --include-deps\r\nrio stac orotomosaico_cog.tif > item.json\r\n<\/pre>\n<p>Dica importante:<\/p>\n<p>O campo &#8220;href&#8221;: &#8220;http:\/\/SEU_IP:9000\/rasters\/seu_arquivo.tif&#8221; do JSON, \u00e9 o link para o dado real (idealmente um COG acess\u00edvel via HTTP ou S3).<\/p>\n<p><strong><\/p>\n<h3>10. Adapter STAC (compatibilidade com GeoServer)<\/h3>\n<p><\/strong><\/p>\n<p>Essa \u00e9 uma das partes mais importantes da arquitetura, pois o GeoServer n\u00e3o consume STAC de forma totalmente nativa. Ent\u00e3o esse adapter vai resolver as incompatibilidades do GeoServer com STAC, ajustando links e headers. <\/p>\n<p>Para o STAC funcionar perfeitamente no GeoServer, \u00e9 necess\u00e1rio realizar alguns ajustes de:<\/p>\n<ul>\n<li>Content-Type<\/li>\n<li>Href<\/li>\n<li>Navega\u00e7\u00e3o interna<\/li>\n<\/ul>\n<p>Devido a esse problema, foi desenvolvido um adapter em FastAPI que: intercepta requisi\u00e7\u00f5es, ajusta os links (href), corrige headers e diferencia chamadas internas e externas.<\/p>\n<p>Criar API:<\/p>\n<pre>\r\nmkdir \/docker\/api\r\ncd \/docker\/api\r\nnano adapter.py\r\n<\/pre>\n<p>Conte\u00fado do arquivo adapter.py<\/p>\n<pre>\r\nfrom fastapi import FastAPI, Request\r\nfrom fastapi.responses import JSONResponse\r\nimport requests\r\nimport os\r\n\r\napp = FastAPI()\r\n\r\nSTAC_URL = \"http:\/\/stac-api:8080\"\r\n\r\n# URLs\r\nPUBLIC_URL = os.getenv(\"PUBLIC_URL\", \"http:\/\/192.168.186.140:8087\")\r\nINTERNAL_URL = \"http:\/\/stac-adapter:8081\"\r\n\r\n\r\n# -------------------------\r\n# Helper para requisi\u00e7\u00f5es\r\n# -------------------------\r\ndef fetch(url, method=\"GET\", json=None):\r\n    if method == \"POST\":\r\n        r = requests.post(url, json=json)\r\n    else:\r\n        r = requests.get(url)\r\n\r\n    r.raise_for_status()\r\n    return r.json()\r\n\r\n\r\n# -------------------------\r\n# Detecta se \u00e9 chamada interna (GeoServer)\r\n# -------------------------\r\ndef is_internal(request: Request):\r\n    host = request.headers.get(\"host\", \"\")\r\n    return \"stac-adapter\" in host or \"geoserver\" in host\r\n\r\n\r\n# -------------------------\r\n# Fix links (inteligente)\r\n# -------------------------\r\ndef fix_links(data, internal=False):\r\n    base = INTERNAL_URL if internal else PUBLIC_URL\r\n\r\n    def fix(obj):\r\n        if isinstance(obj, dict):\r\n            for k, v in obj.items():\r\n                if k == \"href\" and isinstance(v, str):\r\n                    obj[k] = v.replace(\"http:\/\/stac-api:8080\", base)\r\n                else:\r\n                    fix(v)\r\n        elif isinstance(obj, list):\r\n            for item in obj:\r\n                fix(item)\r\n\r\n    fix(data)\r\n    return data\r\n\r\n\r\n# -------------------------\r\n# ROOT\r\n# -------------------------\r\n@app.api_route(\"\/\", methods=[\"GET\", \"HEAD\"])\r\nasync def root(request: Request):\r\n    data = fetch(f\"{STAC_URL}\/\")\r\n    return JSONResponse(\r\n        content=fix_links(data, internal=is_internal(request)),\r\n        media_type=\"application\/json\"\r\n    )\r\n\r\n\r\n# -------------------------\r\n# COLLECTIONS\r\n# -------------------------\r\n@app.api_route(\"\/collections\", methods=[\"GET\", \"HEAD\"])\r\nasync def collections(request: Request):\r\n    data = fetch(f\"{STAC_URL}\/collections\")\r\n    return JSONResponse(\r\n        content=fix_links(data, internal=is_internal(request)),\r\n        media_type=\"application\/json\"\r\n    )\r\n\r\n\r\n# -------------------------\r\n# COLLECTION\r\n# -------------------------\r\n@app.api_route(\"\/collections\/{collection_id}\", methods=[\"GET\", \"HEAD\"])\r\nasync def collection(collection_id: str, request: Request):\r\n    data = fetch(f\"{STAC_URL}\/collections\/{collection_id}\")\r\n    return JSONResponse(\r\n        content=fix_links(data, internal=is_internal(request)),\r\n        media_type=\"application\/geo+json\"\r\n    )\r\n\r\n\r\n# -------------------------\r\n# ITEMS\r\n# -------------------------\r\n@app.api_route(\"\/collections\/{collection_id}\/items\", methods=[\"GET\", \"HEAD\"])\r\nasync def items(collection_id: str, request: Request):\r\n    data = fetch(f\"{STAC_URL}\/collections\/{collection_id}\/items\")\r\n    return JSONResponse(\r\n        content=fix_links(data, internal=is_internal(request)),\r\n        media_type=\"application\/geo+json\"\r\n    )\r\n\r\n\r\n# -------------------------\r\n# ITEM ESPEC\u00cdFICO\r\n# -------------------------\r\n@app.api_route(\"\/collections\/{collection_id}\/items\/{item_id}\", methods=[\"GET\", \"HEAD\"])\r\nasync def item(collection_id: str, item_id: str, request: Request):\r\n    data = fetch(f\"{STAC_URL}\/collections\/{collection_id}\/items\/{item_id}\")\r\n    return JSONResponse(\r\n        content=fix_links(data, internal=is_internal(request)),\r\n        media_type=\"application\/geo+json\"\r\n    )\r\n\r\n\r\n# -------------------------\r\n# SEARCH\r\n# -------------------------\r\n@app.api_route(\"\/search\", methods=[\"GET\", \"POST\", \"HEAD\"])\r\nasync def search(request: Request):\r\n    if request.method == \"POST\":\r\n        body = await request.json()\r\n        data = fetch(f\"{STAC_URL}\/search\", method=\"POST\", json=body)\r\n    else:\r\n        data = fetch(f\"{STAC_URL}\/search\")\r\n\r\n    return JSONResponse(\r\n        content=fix_links(data, internal=is_internal(request)),\r\n        media_type=\"application\/geo+json\"\r\n    )\r\n<\/pre>\n<p>Agora vamos ao conte\u00fado do arquivo Dockerfile:<\/p>\n<pre>\r\nFROM python:3.11-slim\r\n\r\nWORKDIR \/app\r\n\r\nRUN pip install fastapi uvicorn requests\r\n\r\nCOPY adapter.py .\r\n\r\nCMD [\"uvicorn\", \"adapter:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8081\"]\r\n<\/pre>\n<p>E pra finalizar, voc\u00ea deve adicionar ao seu docker-compose:<\/p>\n<pre>\r\nadapter:\r\n  container_name: stac-adapter\r\n  build: .\/api\r\n  ports:\r\n    - \"8087:8081\"\r\n  depends_on:\r\n    - stac\r\n  networks:\r\n    - internal\r\n    - external\r\n<\/pre>\n<p>Agora \u00e9 s\u00f3 subir o adapter:<\/p>\n<pre>\r\ndocker compose up -d --build\r\n<\/pre>\n<p><strong><\/p>\n<h3>11. Nginx<\/h3>\n<p><\/strong><\/p>\n<p>Agora, para finalizar, vamos instalar o nginx e deixar tudo rodando externamente na porta 80. O Nginx atua como proxy reverso, centralizando o acesso:<\/p>\n<ul>\n<li>\/geoserver \u2192 GeoServer<\/li>\n<li>\/stac \u2192 Adapter<\/li>\n<li>\/stac-api \u2192 API direta<\/li>\n<\/ul>\n<p>E ainda ajuda na organiza\u00e7\u00e3o das rotas, facilidade de exposi\u00e7\u00e3o externa e melhor controle de seguran\u00e7a.<\/p>\n<p>Vamos criar o arquivo nginx-stac.conf:<\/p>\n<pre>\r\ncd \/docker\/\r\nnano nginx-stac.conf\r\n<\/pre>\n<p>Esse arquivo deve conter o seguinte conte\u00fado:<\/p>\n<pre>\r\nserver {\r\n    listen 80;\r\n\r\n    # -------------------------\r\n    # GEOSERVER\r\n    # -------------------------\r\n    location \/geoserver\/ {\r\n        proxy_pass http:\/\/geoserver:8080\/geoserver\/;\r\n\r\n        proxy_set_header Host $host;\r\n        proxy_set_header X-Real-IP $remote_addr;\r\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\r\n    }\r\n\r\n    # -------------------------\r\n    # STAC (via adapter)\r\n    # -------------------------\r\n    location \/stac\/ {\r\n        proxy_pass http:\/\/adapter:8081\/;\r\n\r\n        proxy_set_header Host $host;\r\n        proxy_set_header X-Real-IP $remote_addr;\r\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\r\n    }\r\n\r\n    # -------------------------\r\n    # STAC DIRETO (opcional)\r\n    # -------------------------\r\n    location \/stac-api\/ {\r\n        proxy_pass http:\/\/stac-api:8080\/;\r\n\r\n        proxy_set_header Host $host;\r\n        proxy_set_header X-Real-IP $remote_addr;\r\n    }\r\n}\r\n<\/pre>\n<p>Voc\u00ea precisar alterar a seguinte linha do arquivo adapter.py:<\/p>\n<pre>\r\nPUBLIC_URL = os.getenv(\"PUBLIC_URL\", \"http:\/\/192.168.186.140:8087\")\r\n<\/pre>\n<p>Para:<\/p>\n<pre>\r\nPUBLIC_URL = os.getenv(\"PUBLIC_URL\", \"http:\/\/192.168.186.140\/stac\")\r\n<\/pre>\n<p>Agora \u00e9 s\u00f3 subir o seu container, e pronto:<\/p>\n<pre>\r\ndocker compose up -d --build\r\n<\/pre>\n<p>Se tudo estiver correto, voc\u00ea ver\u00e1 sua collection retornada via API.<\/p>\n<p><strong><\/p>\n<h3>12. Conclus\u00e3o<\/h3>\n<p><\/strong><\/p>\n<p>Com essa arquitetura, voc\u00ea passa a ter:<\/p>\n<ul>\n<li>Um cat\u00e1logo STAC estruturado e escal\u00e1vel<\/li>\n<li>Uma API moderna para consulta espacial e temporal<\/li>\n<li>Integra\u00e7\u00e3o com GeoServer<\/li>\n<li>Suporte a dados cloud-native (COG)<\/li>\n<\/ul>\n<p>Mais do que isso, voc\u00ea construiu uma base s\u00f3lida para aplica\u00e7\u00f5es geoespaciais modernas, preparada para lidar com grandes volumes de dados de forma eficiente.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Prezado leitor, Se voc\u00ea trabalha com dados geoespaciais, principalmente rasters, provavelmente j\u00e1 esbarrou em problemas como: Dificuldade de organizar grandes volumes de dados Falta de padroniza\u00e7\u00e3o na publica\u00e7\u00e3o APIs pouco eficientes para busca espacial\/temporal \u00c9 exatamente aqui que entra o&#8230; <a class=\"more-link\" href=\"https:\/\/www.fernandoquadro.com.br\/html\/2026\/03\/23\/como-criar-seu-proprio-catalogo-stac\/\">Continue Reading &rarr;<\/a><\/p>\n","protected":false},"author":275,"featured_media":10285,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24],"tags":[356,304,208,212,357],"class_list":["post-10266","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-gis","tag-cog","tag-docker","tag-geoserver","tag-postgis","tag-stac"],"_links":{"self":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts\/10266","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/users\/275"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/comments?post=10266"}],"version-history":[{"count":32,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts\/10266\/revisions"}],"predecessor-version":[{"id":10299,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts\/10266\/revisions\/10299"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/media\/10285"}],"wp:attachment":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/media?parent=10266"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/categories?post=10266"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/tags?post=10266"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}