Create the following function in your ~/.bashrc and then either:
- logout and login
source ~/.bashrc(I don't prefer this as sometimes it works sometimes it does not)
function dev() {
local docker_cmd="sudo docker run -it --rm -v $PWD:/work -w /work"
# Check for incorrect usage (more than one argument or invalid format)
if [ "$#" -gt 1 ] || ( [ "$#" -eq 1 ] && ! [[ $1 =~ ^.+/+.+$ ]] ); then
echo "Usage: dev [<project-name>/<stage>]"
return 1
fi
# Append PORTUNUS_TOKEN if it's set and exactly one correctly formatted argument is provided
if [ -n "$PORTUNUS_TOKEN" ] && [ "$#" -eq 1 ]; then
docker_cmd+=" -e PORTUNUS_TOKEN=${PORTUNUS_TOKEN}/$1"
fi
# Name the container dev-<project>-<stage> (or dev-<dirname>) so it can be found with docker ps / docker exec
local base name n=1
if [ "$#" -eq 1 ]; then
base="dev-${1%%/*}-${1#*/}"
else
base="dev-$(basename "$PWD")"
fi
base=${base//[^a-zA-Z0-9_.-]/-}
name=$base
while sudo docker ps --format '{{.Names}}' | grep -qx "$name"; do n=$((n+1)); name="$base-$n"; done
docker_cmd+=" --name $name --hostname $name"
docker_cmd+=" --entrypoint /script.sh ashishjullia19/docker-dev-env"
eval $docker_cmd
}Each container is named dev-<project>-<stage> (or dev-<dirname> when run without a project). If that name is already running, -2, -3 and so on are added. The name is also the hostname, so the shell prompt shows which container you are in.
docker ps --filter name=dev-
docker exec -it <name> /script.shA plain docker exec -it <name> bash does not see the Portunus variables, because script.sh exports them only into the shell it starts. Run /script.sh through docker exec to get the same environment. It asks for the MFA code again when the project has AWS_MFA_SERIAL.
For PORTUNUS_TOKEN make sure to grab this from portunus ui portunus.ashishjullia.com and you'll get the token in format:
PORTUNUS_TOKEN=<TOKEN>/<PORTUNUS_TEAM>/<PORTUNUS_PROJECT>/<PORTUNUS_STAGE>. Then<PORTUNUS_TEAM>will not be same as you'll see in ui, it will be a random value.- by default, you can set the token on your host system under PORTUNUS_TOKEN until
<TOKEN>/<PORTUNUS_TEAM>.
Notes:
- If you run it with just
devon terminal then nothing fromscript.shwill be installed/configured - the utilities specified in the
script.shwill only work if portunus integration is used and correct key names are used on portunus side that matches to env variables specified inscript.sh - to run with portunus integration
dev <portunus-project>/<portunus-stage> - if more you specify something like
dev <portunus-project>/<portunus-stage> argument2-> it will throw error
devdev <project>/<stage> loads whatever that Portunus project defines. Nothing here is tied to one account or role.
If that project has AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_ROLE_TO_ASSUME, the container assumes that role before the shell opens. The IAM user keys are not put in the environment or the default AWS profile. Commands use the assumed role, and if that role cannot be assumed the container exits instead of running as the IAM user.
If that same project also has AWS_MFA_SERIAL, startup asks for an MFA code before the assume. The serial stays in Portunus. The code is typed each time. A different project or stage can omit any of these variables.
Without AWS_ROLE_TO_ASSUME, a project that has AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_MFA_SERIAL also asks for an MFA code at startup. The session token is written to ~/.aws/credentials and exported in the shell, the same as running mfa <code> yourself.
dev with no project does not load Portunus, so that container does not assume a role. Keys without AWS_ROLE_TO_ASSUME still configure the default profile as the IAM user.
Inside the container, after AWS credentials are configured:
mfa 123456123456 is the code from your authenticator app. That command sources /usr/local/bin/mfa.sh, writes a session token to ~/.aws/credentials, and exports AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN in the current shell.
source ./mfa.sh does not work here. dev mounts the project on /work, so a script copied into the project is hidden or left behind in that repository. mfa stays in the image, outside that mount.
Wrangler is installed in the image. dev <project>/<stage> leaves CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID in the environment when that Portunus project sets them. Wrangler reads both itself.
Startup does not call wrangler whoami. That command lists account memberships, and an account API token cannot do that even when CLOUDFLARE_ACCOUNT_ID is set. A bad token fails the Wrangler command you run. A project without CLOUDFLARE_API_TOKEN still opens a shell, and Wrangler commands in that shell are not authenticated. dev with no project does not load Portunus, so it does not authenticate Wrangler either.