digital-ocean-spaces

DigitalOcean > SPACES : delivery static assets of Rails app


I spent all day trying to use spaces to delivery static assets.

Tutorial1 with Cloudfront

Tutorial2 with Cloudfront

And it took me only 5 minutes to make it work on Cloudfront without any configuration except the domain name ... (l). Here is the configuration file on Cloudfront.

{
    "ETag": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "Distribution": {
        "Id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "ARN": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "Status": "Deployed",
        "LastModifiedTime": "2021-12-18T16:45:54.406000+00:00",
        "InProgressInvalidationBatches": 0,
        "DomainName": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.cloudfront.net",
        "ActiveTrustedSigners": {
            "Enabled": false,
            "Quantity": 0
        },
        "ActiveTrustedKeyGroups": {
            "Enabled": false,
            "Quantity": 0
        },
        "DistributionConfig": {
            "CallerReference": "9670d28a-cfff-4dd5-9d98-0d377018507b",
            "Aliases": {
                "Quantity": 0
            },
            "DefaultRootObject": "",
            "Origins": {
                "Quantity": 1,
                "Items": [
                    {
                        "Id": "tiredoftrying - staging",
                        "DomainName": "tiredoftrying.digitaloceanspaces.com",
                        "OriginPath": "",
                        "CustomHeaders": {
                            "Quantity": 0
                        },
                        "CustomOriginConfig": {
                            "HTTPPort": 80,
                            "HTTPSPort": 443,
                            "OriginProtocolPolicy": "https-only",
                            "OriginSslProtocols": {
                                "Quantity": 3,
                                "Items": [
                                    "TLSv1",
                                    "TLSv1.1",
                                    "TLSv1.2"
                                ]
                            },
                            "OriginReadTimeout": 30,
                            "OriginKeepaliveTimeout": 5
                        },
                        "ConnectionAttempts": 3,
                        "ConnectionTimeout": 10,
                        "OriginShield": {
                            "Enabled": false
                        }
                    }
                ]
            },
            "OriginGroups": {
                "Quantity": 0
            },
            "DefaultCacheBehavior": {
                "TargetOriginId": "tiredoftrying - staging",
                "TrustedSigners": {
                    "Enabled": false,
                    "Quantity": 0
                },
                "TrustedKeyGroups": {
                    "Enabled": false,
                    "Quantity": 0
                },
                "ViewerProtocolPolicy": "allow-all",
                "AllowedMethods": {
                    "Quantity": 2,
                    "Items": [
                        "HEAD",
                        "GET"
                    ],
                    "CachedMethods": {
                        "Quantity": 2,
                        "Items": [
                            "HEAD",
                            "GET"
                        ]
                    }
                },
                "SmoothStreaming": false,
                "Compress": true,
                "LambdaFunctionAssociations": {
                    "Quantity": 0
                },
                "FunctionAssociations": {
                    "Quantity": 0
                },
                "FieldLevelEncryptionId": "",
                "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6"
            },
            "CacheBehaviors": {
                "Quantity": 0
            },
            "CustomErrorResponses": {
                "Quantity": 0
            },
            "Comment": "",
            "Logging": {
                "Enabled": false,
                "IncludeCookies": false,
                "Bucket": "",
                "Prefix": ""
            },
            "PriceClass": "PriceClass_All",
            "Enabled": true,
            "ViewerCertificate": {
                "CloudFrontDefaultCertificate": true,
                "MinimumProtocolVersion": "TLSv1",
                "CertificateSource": "cloudfront"
            },
            "Restrictions": {
                "GeoRestriction": {
                    "RestrictionType": "none",
                    "Quantity": 0
                }
            },
            "WebACLId": "",
            "HttpVersion": "http2",
            "IsIPV6Enabled": true
        }
    }
}

DEBUG

curl -H "origin: https://supersite.com" -v "https://supersite-cnd.sfo3.digitaloceanspaces.com/assets/about/about-1-b4e60057ce55fa40b823e6403edc2b3cd1d1b2703fbebb4090eef64e3c09a64b.png"

OUTPUT :

*   Trying ...
* TCP_NODELAY set
* Connected to supersite-cnd.sfo3.digitaloceanspaces.com (5.101.109.44) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: C=US; ST=New York; L=New York; O=DigitalOcean, LLC; CN=*.sfo3.digitaloceanspaces.com
*  start date: Mar 17 00:00:00 2021 GMT
*  expire date: Apr 17 23:59:59 2022 GMT
*  subjectAltName: host "supersite-cnd.sfo3.digitaloceanspaces.com" matched cert's "*.sfo3.digitaloceanspaces.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS RSA SHA256 2020 CA1
*  SSL certificate verify ok.
> GET /assets/about/about-1-b4e60057ce55fa40b823e6403edc2b3cd1d1b2703fbebb4090eef64e3c09a64b.png HTTP/1.1
> Host: supersite-cnd.sfo3.digitaloceanspaces.com
> User-Agent: curl/7.68.0
> Accept: */*
> origin: https://supersite.com
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
< content-length: 230
< x-amz-request-id: tx0000000000000a3cdaece-0061be2b23-25a411a1-sfo3b
< access-control-allow-origin: https://supersite.com
< vary: Origin
< access-control-allow-methods: GET
< access-control-max-age: 31536000
< accept-ranges: bytes
< content-type: application/xml
< date: Sat, 18 Dec 2021 18:40:35 GMT
< strict-transport-security: max-age=15552000; includeSubDomains; preload
< vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
< cache-control: max-age=60
< 
* Connection #0 to host supersite-cnd.sfo3.digitaloceanspaces.com left intact
<?xml version="1.0" encoding="UTF-8"?><Error><Code>AccessDenied</Code><BucketName>supersite-cnd</BucketName><RequestId>tx0000000000000a3cdaece-0061be2b23-25a411a1-sfo3b</RequestId><HostId>25a411a1-sfo3b-sfo3-zg02</HostId></Error>

successful attempt on Cloudfront :

*   Trying ...
* TCP_NODELAY set
* Connected to supersite-cnd.cloudfront.net (52.85.216.96) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=*.cloudfront.net
*  start date: Mar 19 00:00:00 2021 GMT
*  expire date: Mar 17 23:59:59 2022 GMT
*  subjectAltName: host "supersite-cnd.cloudfront.net" matched cert's "*.cloudfront.net"
*  issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x56506ff23e30)
> GET /assets/about/about-1-b4e60057ce55fa40b823e6403edc2b3cd1d1b2703fbebb4090eef64e3c09a64b.png HTTP/2
> Host: supersite-cnd.cloudfront.net
> user-agent: curl/7.68.0
> accept: */*
> origin: https://supersite.com
> 
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200 
< content-type: image/png
< content-length: 46219
< server: nginx/1.18.0 (Ubuntu)
< date: Sat, 18 Dec 2021 19:18:19 GMT
< last-modified: Thu, 16 Dec 2021 08:28:28 GMT
< etag: "61baf8ac-b48b"
< expires: Thu, 31 Dec 2037 23:55:55 GMT
< cache-control: max-age=315360000
< cache-control: public
< accept-ranges: bytes
< x-cache: Miss from cloudfront
< via: 1.1 d51c589e5c767f633277e1c42d3e5c0a.cloudfront.net (CloudFront)
< x-amz-cf-pop: JNB50-C1
< x-amz-cf-id: sznV_e7hZKxQ-fWggvY5LsFDlFCNQDMGOIlIELoL5hWN0ABdLpluUw==
< 
Warning: Binary output can mess up your terminal. Use "--output -" to tell 
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: <FILE>" to save to a file.
* Failed writing body (0 != 8595)
* stopped the pause stream!
* Connection #0 to host supersite-cnd.cloudfront.net left intact

Since the same file exists and works for Cloudfront ... it is not a configuration problem (on Nginx or Puma). I presume a CORS issue on DigitalOcean but I have no idea how to find it ...

Any idea? Help.


Solution

  • After days, speaking with the support, the answer is simple : Spaces is not a CDN, it is a Storage Service (as S3) with a CDN free feature. So don't except any fancy feature with it.