Travis

S3 Deployment

This page documents deployments using the dpl v2. Please see our blog post for details. You can check previous dpl v1 documentation here.

Travis CI can automatically upload your build to Amazon S3 after a successful build.

For a minimal configuration, add the following to your .travis.yml:

deploy:
  provider: s3
  access_key_id: <encrypted access_key_id>
  secret_access_key: <encrypted secret_access_key>
  bucket: <bucket>
  edge: true # opt in to dpl v2

You can find your AWS Access Keys in your Amazon Console.

Note that deploying to S3 only adds files to your bucket, it does not remove them. If you need to remove outdated files you can do that manually in your Amazon S3 console.

Status #

Support for deployments to AWS S3 is stable.

Known options #

Use the following options to further configure the deployment.

access_key_id AWS access key id — required, secret, type: string
secret_access_key AWS secret key — required, secret, type: string
bucket S3 bucket — required, type: string
region S3 region — type: string, default: us-east-1
endpoint S3 endpoint — type: string
upload_dir S3 directory to upload to — type: string
local_dir Local directory to upload from — type: string, default: ., e.g.: ~/travis/build (absolute path) or ./build (relative path)
glob Files to upload — type: string, default: **/*
dot_match Upload hidden files starting with a dot — type: boolean
acl Access control for the uploaded objects — type: string, default: private, known values: private, public_read, public_read_write, authenticated_read, bucket_owner_read, bucket_owner_full_control
detect_encoding HTTP header Content-Encoding for files compressed with gzip and compress utilities — type: boolean
cache_control HTTP header Cache-Control to suggest that the browser cache the file — type: string or array of strings, default: no-cache, known values: /^no-cache.*/, /^no-store.*/, /^max-age=\d+.*/, /^s-maxage=\d+.*/, /^no-transform/, /^public/, /^private/, note: accepts mapping values to globs
expires Date and time that the cached object expires — type: string or array of strings, format: /^"?\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} .+"?.*$/, note: accepts mapping values to globs
default_text_charset Default character set to append to the content-type of text files — type: string
storage_class S3 storage class to upload as — type: string, default: STANDARD, known values: STANDARD, STANDARD_IA, REDUCED_REDUNDANCY
server_side_encryption Use S3 Server Side Encryption (SSE-AES256) — type: boolean
index_document_suffix Index document suffix of a S3 website — type: string
overwrite Whether or not to overwrite existing files — type: boolean, default: true
force_path_style Whether to force keeping the bucket name on the path — type: boolean
max_threads The number of threads to use for S3 file uploads — type: integer, default: 5, max: 15
verbose Be verbose about uploading files — type: boolean

Shared options #

cleanup Clean up build artifacts from the Git working directory before the deployment — type: boolean
run Commands to execute after the deployment finished successfully — type: string or array of strings

Environment variables #

All options can be given as environment variables if prefixed with AWS_ or S3_.

For example, access_key_id can be given as

  • AWS_ACCESS_KEY_ID=<access_key_id> or
  • S3_ACCESS_KEY_ID=<access_key_id>

Securing secrets #

Secret option values should be given as either encrypted strings in your build configuration (.travis.yml file) or environment variables in your repository settings.

Environment variables can be set on the settings page of your repository, or using travis env set:

travis env set AWS_ACCESS_KEY_ID <access_key_id>

In order to encrypt option values when adding them to your .travis.yml file use travis encrypt:

travis encrypt <access_key_id>

Or use --add to directly add it to your .travis.yml file. Note that this command has to be run in your repository’s root directory:

travis encrypt --add deploy.access_key_id <access_key_id>

Set an ACL #

You can set the acl of your uploaded files via the acl option like this:

deploy:
  provider: s3
  acl: public_read
  # ⋮

See Known options for valid ACL values.

In order to set acl, the bucket’s policy must allow such operations via the s3:PutObjectAcl action. An example policy might look like the following. Be sure to set up the principal and resources according to your needs.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowPublicRead",
      "Effect": "Allow",
      "Principal": {
        "AWS": "PRINCIPAL_ID"
      },
      "Action": [
        "s3:AbortMultipartUpload",
        "s3:DeleteObject",
        "s3:GetObject",
        "s3:GetObjectAcl",
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Resource": "arn:aws:s3:::BUCKET_NAME/*"
    }
  ]
}

Another way to set ACL for your artifacts is via a S3 bucket policy. For example, the following policy grants the public read permission:

{
  "Version": "2014-09-25",
  "Statement":[{
    "Sid":"AllowPublicRead",
        "Effect":"Allow",
      "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::"YOUR BUCKET NAME"/*"
      ]
    }
  ]
}

S3 bucket regions #

By default the region us-east-1 is used when deploying to S3. If your bucket is hosted in a different region, deploying using the default region results in the following error.

The bucket you are attempting to access must be addressed using the specified endpoint.
Please send all future requests to this endpoint. (AWS::S3::Errors::PermanentRedirect)

This can be resolved by specifying your bucket’s region using the region configuration. For example, this example uses the eu-west-1 region.

deploy:
  provider: s3
  # ⋮
  region: eu-west-1

Deploy From Only One Folder #

Often, you don’t want to upload your entire project to S3. You can use the local_dir option to only upload a single directory to S3. For example:

deploy:
  provider: s3
  # ⋮
  local_dir: ./build

Deploy to a Specific S3 Folder #

Often, you want to upload only to a specific S3 Folder. You can use the upload-dir option to set the S3 destination folder. For example:

deploy:
  provider: s3
  # ⋮
  upload-dir: travis-builds

Deploy to Multiple Buckets #

If you want to upload to multiple buckets, use multiple deployment configurations:

deploy:
  - provider: s3
    access_key_id: <access_key_id>
    secret_access_key: <secret_access_key>
    bucket: "One S3 Bucket"
  - provider: s3
    access_key_id: <access_key_id>
    secret_access_key: <secret_access_key>
    bucket: "Another S3 Bucket"

Conditional releases #

You can deploy only when certain conditions are met. See Conditional Releases with on:.

Set the content encoding #

S3 uploads can optionally set the HTTP header Content-Encoding. This header allows files to be sent compressed while retaining file extensions and the associated MIME types.

To enable this feature, add:

deploy:
  provider: s3
  # ⋮
  detect_encoding: true

If the file is compressed with gzip or compress, it will be uploaded with the appropriate header.

Set the charset on the content type #

S3 can take a content-type header. Normally this doesn’t include a character set as well. If you would like to add a character set, add the default_text_charset option with what you want it to be. For example:

deploy:
  provider: s3
  # ⋮
  default_text_charset: utf-8

HTTP cache control #

S3 uploads can optionally set Cache-Control and Expires HTTP headers.

Set HTTP header Cache-Control to suggest that the browser cache the file. Defaults to no-cache. Valid options are no-cache, no-store, max-age=<seconds>, s-maxage=<seconds> no-transform, public, private.

Expires sets the date and time that the cached object is no longer cacheable. Defaults to not set. The date must be in the format YYYY-MM-DD HH:MM:SS -ZONE.

deploy:
  provider: s3
  # ⋮
  cache_control: max-age=31536000
  expires: "2012-12-21 00:00:00 -0000"

Fine-grained HTTP cache control #

Optionally cache controls can be set more fine-grained on a per file extension basis.

The following example allows image files, such a .png, .jpg, or .webp, to be cached, while .html are not cached at all.

deploy:
  provider: s3
  # ⋮
  cache_control: "max-age=31536000: *.jpg, *.gif, *.png, *.webp, *.css, *.js, *.ico"
  expires: "Wed, 21 Oct 2015 07:28:00 GMT: *.{jpg,gif,png,webp,css,js,ico}"

Or a more sophisticated example:

deploy:
  provider: s3
  # ⋮
  cache_control: "public, max-age=31536000: *.jpg, *.gif, *.png, *.webp, *.css, *.js, *.ico"
  expires: "$(date -u +'%Y-%m-%d %H:%M:%S -0000' --date 'next Year'): *.{jpg,gif,png,webp,css,js,ico}" # for Linux

Please note that the example given works on Linux. On macOS, which uses the BSD version of date this would be an equivalent solution:

date -j -f "%s" $(( $(date -u +"%s") + 365*24*60*60 )) +"%Y-%m-%d %H:%M:%S -0000"

Upload files starting with a dot #

S3 uploads can be set to upload all files starting with a .

deploy:
  provider: s3
  # ⋮
  dot_match: true

Use S3-compatible Object Storage #

You can use S3-compatible object storage such as Digital Ocean Spaces by setting the endpoint key.

deploy:
  provider: s3
  # ⋮
  endpoint: https://nyc3.digitaloceanspaces.com

Pull Requests #

Note that pull request builds skip the deployment step altogether.

See also #