Salesforce CLI with Docker in AWS

Auth was the tricky part as the normal auth requires a browser session rather than taking it from the CLI prompt.

Step 1. Create Dockerfile

FROM node:9.9.0-alpine
RUN npm install sfdx-cli --global
RUN sfdx --version
RUN sfdx plugins --core

Step 2. Generate auth URL from your laptop and push into SSM
sfdx force:auth:web:login -r -a <alias>
sfdx force:org:display -u <alias> --verbose

Step 3. Push the auth URL into SSM
Note: Auth URL looks like – force://……
aws ssm put-parameter --name /SF/dev --value <auth_URL_here> --description 'some description' --type SecureString --key-id <KMS_key_id_here> --region <region_here> --overwrite

To list all the keys in the path:
aws ssm get-parameters-by-path --path /SF/ --query 'Parameters[*].Name'

Step 4. Run auth within the docker container
aws ssm get-parameters --name <name_here> --with-decryption --output text --query 'Parameters[*].Value' --region ap-southeast-2 > auth.txt"
sfdx force:auth:sfdxurl:store -f auth.txt -a <alias_here>

you probably don’t need to worry about auth.txt if you’re using docker –rm or similar.

Pooq Proxy

This is my current setup for watching Pooq in Australia for anyone interested.
With local proxy, below 4k streaming (UHD) seems alright with NBN via AussieBB.
TPG might have better throughput as they have PPC-1 submarine cable.

Architecture Diagram

1. Nginx installed host in Korea – AWS LightSail costs USD 3.5/month~
2. DNS dmasquerading – this can be any dns server running from your router or NAS
3. Pooq subscription – Can be paid via Korean credit card or Apple store credit

Dnsmasq Config

address=/ current IP address of the host here to exclude them from the below_
address=/ Nginx host IP here_

Nginx Config

stream {
  upstream pooq_http {
    server max_fails=3 fail_timeout=1s;
  upstream pooq_https {
    server max_fails=3 fail_timeout=1s;
  server {
    listen    80;
    proxy_pass pooq_http;
    proxy_connect_timeout 1s;
    proxy_timeout 3s;
  server {
    listen     443;
    proxy_pass pooq_https;
    proxy_connect_timeout 1s;
    proxy_timeout 3s;

Note: need libnginx-mod-stream package installed

(Optional) Pooq Local Proxy
Need to reroute * traffic to the proxy using DNS server.
Don’t forget to set config.js file to point the nginx host.

Generate custom x509 certificate in Okta

* Requires API key with admin access, least for the target app

Obtain app name & label using app ID

curl -v -X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: SSWS ${api_token}" \

Generate custom certificate and capture ‘kid’ value from response

curl -v -X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: SSWS ${api_token}" \
-d '{
}' "https://[okta_instance][app_id]/credentials/keys/generate?validityYears=[number]"

Inject custom certificate to app

curl -v -X PUT \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: SSWS ${api_token}" \
-d '{
  "name": "[app_name]",
  "label": "[app_label]",
  "signOnMode": "SAML_2_0",
  "credentials": {
    "signing": {
      "kid": "[kid]"
}' "https://[okta_instnace][app_id]"

Selenium test with docker-compose

In case using selenium standalone during test.

docker-compose YAML

  version: '3'
          - selenium
          - E2ETEST_HOST=test
          - SELENIUM_PORT=4444
          - SELENIUM_HOST=selenium
          context: .
          dockerfile: Dockerfile
          - 80
          - 443
        image: selenium/standalone-chrome
          - 4444

nightwatch config sample

"test_settings": {
    "default": {
        "selenium_port"  : parseInt(process.env.SELENIUM_PORT) || 4444,
        "selenium_host"  : process.env.SELENIUM_HOST,
        "silent": true,
        "desiredCapabilities": {
            "browserName": "chrome",
            "javascriptEnabled": true,
            "acceptSslCerts": true,
            "chromeOptions" : {
                "args" : ["--no-sandbox"]

docker-compose down
docker-compose up --force-recreate --build --abort-on-container-exit --exit-code-from test test

AWS KMS – two liners

For binary encrypted output:

aws kms encrypt --region ap-southeast-2 --key-id alias/blah --plaintext fileb://blah --output text --query CiphertextBlob | base64 --decode > blah.enc
aws kms decrypt --ciphertext-blob fileb://blah.enc --output text --query Plaintext | base64 --decode

For base64 encrypted output:

aws kms encrypt --region ap-southeast-2 --key-id alias/blah --plaintext fileb://blah --output text --query CiphertextBlob > blah.enc
aws kms decrypt --ciphertext-blob fileb://<(cat blah.enc | base64 --decode) --output text --query Plaintext | base64 --decode

or try: