Amazon S3 er en ekstremt kraftig tjeneste som utgjør kjernen i Amazon Web Services. Utenfor produksjonsmiljøet kan S3 imidlertid være utfordrende å jobbe med. Det innebærer å sende tilgangsnøkler rundt, opprette brukerkontoer og opprettholde en pålitelig nettverkstilkobling - for ikke å snakke om at det koster penger. FakeS3 er en lettvektsserver som simulerer oppførselen til den ekte S3. Den svarer på de samme anropene som Amazon S3 svarer på, og lagrer opplastede filer i ditt lokale filsystem - ingen forespørsler sendes til Amazons tjeneste. Selv om gem ikke støtter alle S3-kommandoer, er det implementerte API-et tilstrekkelig for de fleste bruksområder.
I denne artikkelen skal jeg presentere metoden for å integrere AWS og FakeS3 med Paperclip - et populært filvedleggsbibliotek for Active Record. Paperclip og S3 blandet sammen gir et effektivt fillagringssystem som kombinerer nyttige Paperclips kjernefunksjoner (som valideringsadministrasjon og bildetransformasjoner) med fordelene med online lagring. Selv om konfigurasjonen av disse verktøyene ikke er åpenbar og krever at man graver seg ned i detaljert dokumentasjon samt løser mange gem-spesifikke problemer, er det verdt å bruke litt tid på å gjøre utviklingen raskere og mer effektiv.
Hva er målet vårt?
Integrering av de beskrevne verktøyene krever tre trinn:
- Starter S3-fakeserver levert av FakeS3-perlen i bakgrunnen.
- Konfigurere AWS S3-klienten til å delegere alle forespørsler til en lansert fakeserver.
- Konfigurere Paperclip til å bruke falske S3-endepunkter i URL-adresser for innebygde ressurser.
Installasjon
La oss begynne med å installere nødvendige gems:
# Gemfile
gem "paperclip"
gem "aws-sdk", "~> 1.6"
gem "fakes3", group: [:development, :test]
Sørg for å installere versjon 1.6 av aws-sdk. Paperclip, som bruker SKD til å administrere lagring i Amazons tjeneste, fungerer ikke godt med høyere versjoner av denne perlen. Dette skyldes betydelige endringer i SDKs API med versjon 2.0.
Husk også at hovedmålet med FakeS3 er å minimere kjøretidsavhengigheter. Det er mer et utviklingsverktøy for å teste S3-kall i kode i stedet for en produksjonsserver som ønsker å duplisere S3-funksjonalitet. Derfor bør du bare inkludere gem i utviklings- og testgrupper.
AWS-konfigurasjon
AWS SDK tilbyr en dedikert hjelpemetode som er ansvarlig for å laste inn konfigurasjon. Den vil som standard laste inn konfigurasjon fra config/aws.yml
henter ut parametrene for det aktuelle miljøet og sender dem til AWS-klienten. Først kaller du følgende metode i en initialisator:
# config/initializers/aws.rb
AWS::Rails.load_yaml_config
Nå som konfigurasjonsfilen er lastet inn på riktig måte, kan vi fortsette med å spesifisere innholdet i den:
# config/aws.yml
development: &development
access_key_id: "abc"
secret_access_key: "abc"
s3_endepunkt: "localhost"
s3_port: 10001
s3_force_path_style: true
use_ssl: false
test: *utvikling
La oss diskutere alle parametrene én etter én:
tilgangsnøkkel_id, hemmelig_tilgangsnøkkel
- AWS-klientlegitimasjon som kreves for å få tilgang til Amazon-kontoen din. De ignoreres av den falske S3-serveren, og dermed egendefinerte verdier i sandkassemiljøer.s3_endepunkt, s3_port
- S3-endepunktspesifikasjon. Vi bruker disse parameterne til å erstatte det virkelige S3-endepunktet med et falskt endepunkt lansert av FakeS3-perlen - alle forespørsler til Amazons tjeneste vil nå bli delegert til den lokale fakeserveren.s3_force_path_style
- S3 aksepterer to måter å inkludere bucket-navnet i URL-adressen på. Du kan velge om du vil ha navnet på skuffen plassert i domene-stil (bucket.s3.amazonaws.com) eller sti-stil (s3.amazonaws.com/bucket). For å holde ting enkelt og unngå ekstra konfigurasjon i forbindelse med mapping av bøttas underdomene til loopback-adresse, foretrekker jeg sti-stil fremfor domene-stil i utviklingsmiljøer.use_ssl
- tvinger AWS SDK til å bruke HTTPS i stedet for vanilje-HTTP. Vi må deaktivere dette alternativet, fordi FakeS3-perlen ikke støtter HTTPS-forespørsler som AWS-klienten utfører som standard.
Konfigurasjonen for produksjonsmiljøet er ganske enkel:
# config/aws.yml
produksjon: &produksjon
access_key_id:
secret_access_key:
staging: *produksjon
Denne gangen har vi imidlertid å gjøre med en ekte S3-tjeneste, og du må derfor oppgi autentisk AWS-legitimasjon.
På grunn av potensielle sikkerhetsrisikoer er det lurt å holde hemmelige verdier som tilgangsnøkler utenfor versjonskontrollsystemet, f.eks. ved å bruke miljøvariabler. Vi bruker ERB til å injisere verdiene i konfigurasjonsfilen.
Paperclip-konfigurasjon
Nå er det på tide å møte Paperclip og tvinge den til å fungere fint med den allerede konfigurerte S3-klienten. Hovedmålet med Paperclips konfigurasjon er å få tak i lagringsstien som vil finne ressurser som er vert for fakeserver:
localhost:10001/:bucket_name/:path
Igjen, la oss begynne med utviklingsmiljøet:
# config/paperclip.yml
utvikling: &utvikling
lagring: :s3
bucket: "development"
s3_host_name: "localhost"
url: ":s3_alias_url"
path: ":class/:attachment/:id_partition/:style/:filename.:extension"
s3_host_alias: "localhost:10001/development"
test: *development
lagring
- spesifiserer lagringsmedium (som standard lokalt filsystem). Siden vi bruker AWS S3, må vi endre det til:s3
.bøtte
- navnet på S3-bøtta som skal lagre filene dine. Hvis skuffen ikke finnes, vil Paperclip forsøke å opprette den.url
- satt til:s3_alias_url
vil få Paperclip til å alias S3-bøttens vertsnavn med verdien spesifisert av:s3_host_alias
parameter.s3_host_alias
- alias for standard S3-buckets vert. Legg merke til at plassering av host, port og buckets navn samsvarer med konfigurasjonen av AWS-klienten.sti
- mønster for nøkler som filene skal lagres under i bøtta. Nøkler bør være unike i bøtta, på samme måte som filnavn. Siden S3 ikke støtter kataloger, kan du bruke en/
symbolet for å simulere katalogstrukturer.
# config/paperclip.yml
produksjon: &produksjon
lagring: :s3
bucket:
url: ":s3_domain_url"
path: ":class/:attachment/:id_partition/:style/:filename.:extension"
staging: *produksjon
På samme måte som AWS-legitimasjon, anses bøtte-navnet også å være en hemmelig verdi som bør lagres utenfor kodebasen din. Jeg anbefaler å lagre navnet i en miljøvariabel.
Til slutt kan du slå sammen konfigurasjonen med Paperclips standardalternativer i en initialiser:
# config/initializers/paperclip.rb
paperclip_defaults = Rails.application.config_for :paperclip
paperclip_defaults.symbolize_keys!
Paperclip::Attachment.default_options.merge! paperclip_defaults
Kjører fakes3
Både AWS- og Paperclip-konfigurasjonene inneholder en referanse til den lokale S3-fakeserveren som forventes å kjøre under localhost:10001
. Før du begynner å jobbe med utvikling, bør du starte serveren med følgende kommando (levert av FakeS3 gem):
fakes3 -r public/system -p 10001
Overførte parametere er:
rot -r
- rotkatalogen som opplastede filer skal lagres under. Vurder å ekskludere den fra VCS hvis du ikke vil at opplastede filer skal lagres i depotet ditt.port -p
- nummeret på porten som den lokale serveren skal kjøres på.
Hvis du bruker Foreman til prosessadministrasjon i programmet ditt, kan det være praktisk å legge til følgende oppføring i Procfile:
# Procfile
fakes3: fakes3 -r ${FAKES3_STORAGE_PATH:-public/system} -p ${FAKES3_PORT:-10001 -p ${FAKES3_PORT:-10001}
Dette vil spare deg for å bruke tid på å starte fakeserveren hver gang du trenger å utvikle S3-relaterte funksjoner.
Konklusjon
Vi har konfigurert AWS-klienten til å delegere alle forespørsler til lokal fakeserver, konfigurert Paperclip til å bruke falske S3-sluttpunkter i URL-adressene til innebygde ressurser og lansert fakeserver levert av Fake S3 gem som lagrer alle filer i lokalt filsystem.
Dermed ble vi uavhengige av Internett-tilkobling og sparte penger, noe som gjorde utviklingen vår raskere og mer pålitelig.