Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
FROM ubuntu:20.04
# Wrangler requires glibc 2.35. Ubuntu 20.04 ships 2.31.
FROM ubuntu:22.04

ENV NVM_DIR=/usr/local/nvm

# Install dependencies, AWS CLI, kubectl, Helm, tfenv, NVM, and GitHub CLI.
# Node itself is installed at runtime by script.sh when NODE_VERSION is set.
# Install dependencies, AWS CLI, kubectl, Helm, tfenv, NVM, GitHub CLI, and Wrangler.
# A project Node version is installed at runtime by script.sh when NODE_VERSION is set.
# The Node under /opt/node exists only so Wrangler can run when NODE_VERSION is unset.
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
git \
jq \
Expand All @@ -14,10 +16,11 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
openssl \
python3 \
python3-pip \
python3-yaml \
&& arch=$(dpkg --print-architecture) \
&& case "$arch" in \
amd64) aws_cli_url="https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip"; kubectl_arch="amd64" ;; \
arm64) aws_cli_url="https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip"; kubectl_arch="arm64" ;; \
amd64) aws_cli_url="https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip"; kubectl_arch="amd64"; node_arch="x64" ;; \
arm64) aws_cli_url="https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip"; kubectl_arch="arm64"; node_arch="arm64" ;; \
*) echo "Unsupported architecture: $arch" >&2; exit 1 ;; \
esac \
&& curl -fsSL "$aws_cli_url" -o awscliv2.zip \
Expand All @@ -29,7 +32,8 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
&& chmod 700 get_helm.sh \
&& ./get_helm.sh \
&& git clone https://github.com/tfutils/tfenv.git /root/.tfenv \
&& pip3 install urllib3==1.26.7 print-env \
&& pip3 install 'urllib3==1.26.7' 'requests>=2,<3' 'click>=7,<8' 'python-dotenv==0.19.2' 'python-gnupg==0.4.8' \
&& pip3 install print-env --no-deps \
&& mkdir -p "$NVM_DIR" \
&& curl -fsSL -o /tmp/nvm-install.sh https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh \
&& bash /tmp/nvm-install.sh \
Expand All @@ -38,8 +42,15 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list \
&& apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y gh \
&& curl -fsSL -o node.tar.gz "https://nodejs.org/dist/v22.23.3/node-v22.23.3-linux-${node_arch}.tar.gz" \
&& mkdir -p /opt/node \
&& tar -xzf node.tar.gz -C /opt/node --strip-components=1 \
&& PATH="/opt/node/bin:$PATH" npm install -g wrangler@4.141.0 \
&& printf '%s\n' '#!/bin/sh' 'exec /opt/node/bin/node /opt/node/lib/node_modules/wrangler/bin/wrangler.js "$@"' > /usr/local/bin/wrangler \
&& chmod 755 /usr/local/bin/wrangler \
&& wrangler --version \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* awscliv2.zip aws kubectl get_helm.sh
&& rm -rf /var/lib/apt/lists/* awscliv2.zip aws kubectl get_helm.sh node.tar.gz

# tfenv is a real binary path. nvm is a shell function loaded by script.sh,
# so a node version directory cannot be added here.
Expand Down
6 changes: 6 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,9 @@ mfa 123456
`123456` 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.

## Cloudflare CLI

Wrangler is installed in the image. `dev <project>/<stage>` authenticates it when that Portunus project sets `CLOUDFLARE_API_TOKEN`. Wrangler reads that variable itself. An optional `CLOUDFLARE_ACCOUNT_ID` on the same project is passed through the same way.

Startup runs `wrangler whoami`. A token that Cloudflare rejects stops the container. 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.
9 changes: 9 additions & 0 deletions script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,15 @@ EOF
echo "GH_CLI_TOKEN is not set. Skipping GitHub CLI authentication."
fi

# Wrangler reads CLOUDFLARE_API_TOKEN from the environment. Portunus exports it
# when this project defines it. Run whoami outside /work so it cannot write into the mounted project.
if [ -n "${CLOUDFLARE_API_TOKEN:-}" ]; then
echo "Authenticating Cloudflare CLI..."
( cd /tmp && CI=true WRANGLER_SEND_METRICS=false wrangler whoami ) || error_exit "Failed to authenticate the Cloudflare CLI. Check CLOUDFLARE_API_TOKEN on this Portunus project."
else
echo "CLOUDFLARE_API_TOKEN is not set. Skipping Cloudflare CLI authentication."
fi

fi

# Exit to a bash prompt
Expand Down
Loading