title: connect nodejs app to localstack s3 using docker compose
body: <p>I am unable to bring up my app. it always fails with missing credentials. How do I connect localstack s3 to my application. I've tried setting the args and running aws configure in my dockerfile, it still fails with missing credentials.
  I mounted the volume by copying my local credentials from <code>.aws/credential</code> file, but that is not ideal since i want localstack credentials set up.
  always failing with error <code>unable to download: CredentialsError: Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1</code></p>
  <p>Dockerfile</p>
  <pre><code>FROM node:9.2
  
  #install AWS CLI
  RUN apt-get update &amp;&amp; apt-get install -y python python-dev python-pip python-setuptools groff less &amp;&amp; pip install awscli
  
  
  WORKDIR /migration-ui
  
  COPY migration-ui/package.json /migration-ui
  
  RUN npm install
  
  COPY migration-ui /migration-ui
  
  EXPOSE 8080
  
  CMD [&quot;npm&quot;,&quot;start&quot;]
  </code></pre>
  <p>docker compose</p>
  <pre><code>version: '3.7'
  services:
    s3:
      image: localstack/localstack:latest
      container_name: 'localstack'
      ports:
        - '4563-4599:4563-4599'
        - '8082:8081'
      environment:
        - SERVICES=s3
        - DEBUG=1
        - DATA_DIR=/tmp/localstack/data
      volumes:
        - './.localstack:/tmp/localstack'
        - '/var/run/docker.sock:/var/run/docker.sock'
  
    bmo-ui:
      depends_on:
        - s3
      build: .
  </code></pre>
  <p>s3.js</p>
  <pre><code>const s3Params = {
    Bucket: process.env.BMO_BUCKET || 'dev-csi-assets',
    Key: 'bmo-migration/bmo-migration-db.json'
  }
  
  const awsConfig = require('aws-config')
  const AWS = require('aws-sdk')
  const s3 = require('s3')
  
  const awsContainerCredentialsRelativeUri = !!process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
  console.log(&quot;-----ENVIRONMENTS----&quot;, awsContainerCredentialsRelativeUri)
  console.log(&quot;VALUES-----&quot;, process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI)
  const s3Options = {
    region: 'us-east-1',                 // explicitly set AWS region
    sslEnabled: true,                    // override whether SSL is enabled
    maxRetries: 3,                       // override the number of retries for a request
    profile: 'assumed_role',             // name of profile from ~/.aws/credentials
    timeout: 15000                       // optional timeout in ms. Will use AWS_TIMEOUT
  }
  
  let s3Client = new AWS.S3(awsConfig(s3Options))
  
  if (awsContainerCredentialsRelativeUri) {
    AWS.config.credentials = new AWS.ECSCredentials()
    s3Client = new AWS.S3()
  }
  
  const client = s3.createClient({s3Client})
  
  const download = (path, cb = () =&gt; {}) =&gt; {
    try {
      const params = {
        localFile: path,
        s3Params: s3Params
      }
      const downloader = client.downloadFile(params)
      downloader.on('end', () =&gt; {
        console.log('done downloading')
        cb()
      })
      downloader.on('error', err =&gt; {
        console.error('unable to download:', err.stack)
        cb(err)
      })
    } catch (e) {
      console.error(e)
      cb(e)
    }
  }
  
  const upload = (path, cb = () =&gt; {}) =&gt; {
    try {
      const params = {
        localFile: path,
        s3Params: s3Params
      }
      const uploader = client.uploadFile(params)
      uploader.on('error', err =&gt; {
        console.log('unable to upload:', err.stack)
        cb(err)
      })
      uploader.on('progress', () =&gt; {
        console.log('progress', uploader.progressMd5Amount, uploader.progressAmount, uploader.progressTotal)
      })
      uploader.on('end', () =&gt; {
        console.log('done uploading')
        cb()
      })
    } catch (e) {
      console.error(e)
      cb(e)
    }
  }
  
  module.exports = { download, upload }
  </code></pre>