Sign inSign up

st693ava/docker-s3-volume

By st693ava

•Updated 4 days ago

Volumes Docker sobre S3 / Cloudflare R2 com índice local: file_exists em microssegundos

Plugin
0

200

st693ava/docker-s3-volume repository overview

⁠docker-s3-volume

Plugin Docker (volume driver) que monta buckets S3 (Cloudflare R2, AWS S3, MinIO, …) como pastas locais. Pensado para aplicações legadas e buckets enormes: sem sincronização, sem cópia local, e com um índice completo da árvore que responde a file_exists, filesize e scandir em microssegundos. Afinado contra o Cloudflare R2 com 415 mil ficheiros reais (152 GiB).

services:
  app:
    image: php:8.3-apache
    volumes:
      - documentos:/var/www/html/protected/data

volumes:
  documentos:
    driver: st693ava/docker-s3-volume
    driver_opts:
      bucket: "os-meus-documentos"
      profile: "r2"
      uid: "33"               # www-data
      gid: "33"
      changes: "log"          # ver as escritas dos outros hosts em segundos
      reindex_interval: "24h" # rede de segurança diária

⁠Instalação

Publica-se uma tag por arquitectura (0.1.6-amd64 e 0.1.6-arm64). O --alias dá ao driver o mesmo nome em todas as máquinas e entre versões:

ARCH=$(docker info --format '{{.Architecture}}' | sed 's/x86_64/amd64/; s/aarch64/arm64/')
docker plugin install st693ava/docker-s3-volume:0.1.6-$ARCH \
  --alias st693ava/docker-s3-volume --grant-all-permissions \
  credentials.source=/etc/docker-s3-volume

O ficheiro /etc/docker-s3-volume/s3-credentials (dono root, chmod 600) tem os perfis no formato do ~/.aws/credentials; é relido em cada montagem. As credenciais nunca vão nas opções do volume (ficariam visíveis no docker volume inspect).

[r2]
endpoint = https://<conta>.eu.r2.cloudflarestorage.com
access_key_id = ...
secret_access_key = ...

⁠Funcionalidades

  • Índice autoritativo em disco: consultas a ficheiros existentes ou inexistentes não fazem pedidos ao S3. Numa página real com 51 file_exists, o volume gastou 0,2 ms no total.
  • Escritas síncronas: o fclose() só devolve sucesso com o objecto no S3. Multipart com partes iguais (compatível com o R2), Content-MD5 em cada pedido, repetição automática depois de falhas e um diário para recuperar depois de um crash.
  • Alterações feitas noutros hosts: diário partilhado no próprio bucket (changes: "log", um LIST por minuto seja qual for o tamanho do bucket), correcção automática quando um ficheiro desaparece (404) e reindexação periódica como rede de segurança, perto do mínimo de pedidos LIST.
  • Indexação rápida: 415 719 objectos no R2 reindexados em 2,8 s com 56 MiB (128 pedidos em paralelo), 462 pedidos LIST.
  • Testado contra falhas: ligações cortadas, 5xx, corpos corrompidos, S3 em baixo, kill -9 a meio de envios, sinais na aplicação e carga prolongada com dados reais.
  • Versões: nativas quando o bucket as tem activas; caso contrário, o plugin guarda-as em .versions/ (invisível no volume). O plugin nunca altera a configuração do bucket.
  • Cache de assets em disco (css, js, imagens, fontes), por frequência de acesso recente. Os PDFs ficam de fora por defeito.
  • Diagnóstico: debug: "true" regista cada operação e cada pedido ao S3, com resumos de latência por minuto; slow_log regista só as operações lentas. Ambos desligados por defeito.
  • Estado no docker volume inspect: índice, versionamento, envios, cache, alterações de fora e crashes.

⁠Cloudflare R2

  • É o servidor que fala com o bucket, por isso o bucket deve ficar perto dele. A partir da Alemanha: GET de um ficheiro pequeno com 58 ms na jurisdição EU, 76 ms em EEUR e 83 ms em WEUR. A jurisdição EU usa o endpoint <conta>.eu.r2.cloudflarestorage.com.
  • Use um token de API restrito ao bucket (leitura e escrita de objectos): o Access Key ID é o id do token e o Secret é o SHA-256 do valor.
  • A API S3 do R2 só aceita HTTP/1.1; o paralelismo faz-se com muitas ligações reutilizadas.
  • O R2 normaliza os nomes Unicode (NFC e NFD do mesmo nome são um só objecto); o plugin encontra o ficheiro em qualquer das formas.

⁠Opções do volume

OpçãoDefeitoDescrição
bucket—Bucket (obrigatório)
prefix—Subpasta do bucket exposta como raiz do volume
profiledefaultPerfil de credenciais
endpoint, region, securedo perfilSobrepõem-se ao perfil
read_onlyfalseVolume só de leitura (também no kernel: ro)
uid, gid0Dono dos ficheiros
file_mode, dir_mode0644, 0755Permissões
versioningfalsetrue (nativo ou do plugin), native, copy
versions_keep0Versões a manter por ficheiro (0 = todas)
version_on_deletetrueGuardar versão antes de apagar
cache_mb1024Cache local de assets em MiB (0 desliga)
cache_max_file_kb4096Tamanho máximo de um ficheiro na cache
cache_extassets webExtensões admitidas na cache
prefetchfalsePré-carregar um asset depois de um file_exists
changesofflog: diário de alterações partilhado no bucket
changes_interval1mLeitura do diário (1 LIST por leitura)
changes_batch10sJunta as alterações do volume num só PUT no diário
reindex_interval0Reindexação periódica (ex.: 24h; 0 desliga)
reindex_max_interval0Intervalo adaptativo: duplica enquanto não houver diferenças
reindex_on_mountfalseReconstruir o índice em cada montagem
workers128Pedidos LIST em paralelo na indexação
mem_mb256Memória para buffers de leitura
kernel_ttl1hCache de atributos no kernel
max_inodes200000Ficheiros mantidos em memória
part_size_mb16Tamanho das partes multipart
http2falseUsar HTTP/2
debugfalseRegistar todas as operações e pedidos ao S3
slow_log0Registar as operações mais lentas do que isto (ex.: 1s)

⁠Actualizar

CREDS=$(docker plugin inspect -f '{{range .Settings.Mounts}}{{.Source}}{{end}}' st693ava/docker-s3-volume)
docker plugin disable -f st693ava/docker-s3-volume
docker plugin upgrade --skip-remote-check --grant-all-permissions st693ava/docker-s3-volume st693ava/docker-s3-volume:0.1.6-$ARCH
docker plugin set st693ava/docker-s3-volume credentials.source=$CREDS
docker plugin enable st693ava/docker-s3-volume

O docker plugin upgrade mantém os volumes, os índices e a cache, mas não volta a aplicar credentials.source: por isso é reposto antes de reactivar.

⁠Limitações

  • Renomear pastas com conteúdo devolve EXDEV (o mv e o rename() do PHP copiam ficheiro a ficheiro).
  • chmod/chown são aceites sem efeito; as permissões vêm das opções.
  • Se o processo de um volume terminar inesperadamente, é reiniciado; os containers que já estavam a correr precisam de docker restart (limitação do FUSE).
  • Escritas feitas fora do plugin sem diário (outra ferramenta, a consola do R2) só aparecem na reindexação seguinte.

Tag summary

Content type

Plugin

Digest

sha256:b9c3eefac…

Size

13.3 MB

Last updated

4 days ago

docker plugin install st693ava/docker-s3-volume:0.1.6-amd64