Amazon S3 er en ekstremt stærk tjeneste i kernen af Amazon Web Services. Men uden for produktionsmiljøet kan S3 være en udfordring at arbejde med. Det indebærer at sende adgangsnøgler rundt, oprette brugerkonti og opretholde en pålidelig netværksforbindelse - for ikke at nævne, at det koster penge. Heldigvis findes der et værktøj, der hjælper med at løse dette problem. FakeS3 er en letvægtsserver, som simulerer den rigtige S3's adfærd. Den reagerer på de samme opkald, som Amazon S3 reagerer på, og gemmer uploadede filer i dit lokale filsystem - der er ingen anmodninger til Amazons tjeneste. Selvom gem ikke understøtter det fulde sæt af S3-kommandoer, er den implementerede API tilstrækkelig til de fleste applikationers brugsscenarier.
I denne artikel vil jeg præsentere tilgangen til at integrere AWS og FakeS3 med Paperclip - et populært bibliotek for vedhæftede filer til Active Record. Paperclip og S3 blandet sammen giver et effektivt fillagringssystem, der kombinerer nyttige Paperclip-kernefunktioner (som valideringsstyring og billedtransformationer) med fordelene ved online-lagring. Selvom konfigurationen af disse værktøjer ikke er indlysende og kræver, at man graver sig ned i detaljeret dokumentation samt løser mange gem-specifikke problemer, er det værd at bruge lidt tid på at gøre udviklingen hurtigere og mere effektiv.
Hvad er vores mål?
Integrationen af de beskrevne værktøjer kræver tre trin:
- Starter S3-fakeserver leveret af FakeS3-perlen i baggrunden.
- Konfiguration af AWS S3-klient til at uddelegere alle anmodninger til lanceret fakeserver.
- Konfiguration af Paperclip til at bruge et falsk S3-slutpunkt i URL'er til indbyggede ressourcer.
Installation
Lad os starte med at installere de nødvendige gems:
# Gemfil
gem "paperclip"
gem "aws-sdk", "~> 1.6"
gem "fakes3", group: [:development, :test]
Sørg for at installere version 1.6 af aws-sdk. Paperclip, som bruger SKD til at administrere lagerplads i Amazons tjeneste, fungerer ikke godt med højere versioner af denne perle. Det skyldes væsentlige ændringer i SDK's API med version 2.0.
Husk også, at hovedformålet med FakeS3 er at minimere runtime-afhængigheder. Det er mere et udviklingsværktøj til at teste S3-kald i din Kode snarere end en produktionsserver, der ønsker at kopiere S3-funktionalitet. Derfor bør du kun inkludere gem i udviklings- og testgrupper.
AWS-konfiguration
AWS SDK indeholder en dedikeret hjælpemetode, der er ansvarlig for at indlæse konfigurationen. Den vil som standard indlæse konfigurationen fra config/aws.yml
udtrække parametrene for det aktuelle miljø og sende dem til AWS-klienten. For det første skal du kalde følgende metode i en initializer:
# config/initializers/aws.rb
AWS::Rails.load_yaml_config
Nu, hvor vi har indlæst konfigurationsfilen korrekt, kan vi fortsætte med at specificere dens indhold:
# config/aws.yml
udvikling: &udvikling
access_key_id: "abc"
secret_access_key: "abc"
s3_endpoint: "localhost"
s3_port: 10001
s3_force_path_style: true
use_ssl: false
test: *udvikling
Lad os diskutere alle parametre en efter en:
adgangsnøgle_id, hemmelig_adgangsnøgle
- AWS-klientlegitimationsoplysninger, der kræves for at få adgang til din Amazon-konto. De ignoreres af den falske S3-server og dermed af brugerdefinerede værdier i sandkassemiljøer.s3_endpoint, s3_port
- Specifikation af S3-slutpunkt. Vi bruger disse parametre til at erstatte det rigtige S3-slutpunkt med et falsk slutpunkt, der lanceres af FakeS3-perlen - alle anmodninger til Amazons tjeneste vil nu blive delegeret til den lokale fakeserver.s3_force_path_style
- S3 accepterer to måder at inkludere buckets navn i URL'en på. Du kan vælge at placere buckets navn i domænestil (bucket.s3.amazonaws.com) eller sti-stil (s3.amazonaws.com/bucket). For at holde tingene enkle og undgå ekstra konfiguration i forbindelse med kortlægning af buckets subdomæne til loopback-adressen foretrækker jeg path-style frem for domain-style i udviklingsmiljøet.brug_ssl
- tvinger AWS SDK til at bruge HTTPS i stedet for vanilje-HTTP. Vi er nødt til at deaktivere denne mulighed, fordi FakeS3-perlen ikke understøtter HTTPS-anmodninger, som AWS-klienten udfører som standard.
Konfiguration til produktionsmiljø er ret ligetil:
# config/aws.yml
produktion: &produktion
access_key_id:
secret_access_key:
staging: *produktion
Denne gang har vi imidlertid at gøre med en ægte S3-tjeneste, og derfor skal du angive autentiske AWS-legitimationsoplysninger.
På grund af potentielle sikkerhedsrisici er det en god praksis at holde hemmelige værdier som adgangsnøgler ude af dit versionskontrolsystem, f.eks. ved at bruge miljøvariabler. Vi bruger ERB til at indsætte dens værdier i konfigurationsfilen.
Paperclip-konfiguration
Nu er det tid til at møde Paperclip og tvinge den til at arbejde pænt sammen med den allerede konfigurerede S3-klient. Hovedformålet med Paperclips konfiguration er at få fat i den lagringssti, der skal lokalisere ressourcer, som fakeserveren er vært for:
localhost:10001/:bucket_name/:path
Lad os igen starte med udviklingsmiljøet:
# config/paperclip.yml
udvikling: &udvikling
opbevaring: :s3
bucket: "udvikling"
s3_host_name: "localhost"
url: ":s3_alias_url"
path: ":class/:attachment/:id_partition/:style/:filename.:extension"
s3_host_alias: "localhost:10001/development"
test: *udvikling
Opbevaring
- angiver lagermediet (som standard lokalt filsystem). Da vi bruger AWS S3, skal vi ændre det til:s3
.spand
- navnet på den S3-bucket, der skal gemme dine filer. Hvis bucket'en ikke findes, vil Paperclip forsøge at oprette den.url
- sat til:s3_alias_url
vil få Paperclip til at aliasere S3-buckets værtsnavn med den værdi, der er angivet af:s3_host_alias
parameter.s3_host_alias
- alias for standard S3-buckets vært. Bemærk, at placeringen af host, port og buckets navn svarer til konfigurationen af AWS-klienten.sti
- mønster for nøgler, som filerne skal gemmes under i bucket. Nøgler skal være unikke inden for bucket, ligesom filnavne. Da S3 ikke understøtter mapper, kan du bruge en/
symbol til at simulere mappestrukturer.
# config/paperclip.yml
produktion: &produktion
opbevaring: :s3
bucket:
url: ":s3_domain_url"
path: ":class/:attachment/:id_partition/:style/:filename.:extension"
staging: *produktion
På samme måde som AWS-legitimationsoplysninger anses bucket-navnet også for at være en hemmelig værdi, som skal gemmes uden for din kodebase. Jeg anbefaler at gemme navnet i en miljøvariabel.
Til sidst skal du flette konfigurationen ind i Paperclips standardindstillinger i en initializer:
# config/initializers/paperclip.rb
paperclip_defaults = Rails.application.config_for :paperclip
paperclip_defaults.symbolize_keys!
Paperclip::Attachment.default_options.merge! paperclip_defaults
Kører fakes3
Både AWS- og Paperclip-konfigurationer indeholder en henvisning til den lokale S3-fakeserver, som forventes at køre under localhost:10001
. Før du arbejder med udvikling, skal du starte serveren med følgende kommando (leveret af FakeS3 gem):
fakes3 -r public/system -p 10001
Overførte parametre er:
rod -r
- rodmappe, hvorunder uploadede filer vil blive gemt. Overvej at udelukke det fra VCS, hvis du ikke vil have uploadede filer gemt i dit repository.port -p
- nummeret på den port, som den lokale server skal køre på.
Hvis du bruger Foreman til processtyring i dit program, kan det være praktisk at tilføje følgende post i Procfile:
# Procfile
fakes3: fakes3 -r ${FAKES3_STORAGE_PATH:-public/system} -p ${FAKES3_PORT:-10001} -p ${FAKES3_PORT:-10001}
Det vil spare dig for den tid, det tager at starte fakeserver, hver gang du skal udvikle nogle S3-relaterede funktioner.
Konklusion
Vi har konfigureret AWS-klienten til at uddelegere alle anmodninger til den lokale fakeserver, sat Paperclip op til at bruge et falsk S3-slutpunkt i de indbyggede ressourcers URL'er og startet fakeserveren, der leveres af Fake S3 gem, som gemmer alle filer i det lokale filsystem.
Som følge heraf blev vi uafhængige af internetforbindelse og sparede penge, hvilket gjorde vores udvikling hurtigere og mere pålidelig.