Docker Images sBeacon with Atlantis, Portainer and Nginx
2.7K
This Dockerfile creates a specialized container image for running Atlantis with AWS integration, Python 3.12 support, and Docker-in-Docker capabilities. It uses a multi-stage build process to optimize image size and enhance security while providing all necessary tools for modern DevOps workflows.
Deployment tested under Amazon EKS (Kubernetes) Atlantis sBeacon
devopsxti/atlantis-sbeacon:latestatlantis-sbeacon:20250501# syntax=docker/dockerfile:1@sha256:865e5dd094beca432e8c0a1d5e1c465db5f998dca4e439981029b3b81fb39ed5
# Base image arguments
ARG ALPINE_TAG=3.20.3@sha256:1e42bbe2508154c9126d48c2b8a75420c3544343bf86fd041fb7527e017a4b4a
ARG DEBIAN_TAG=12.8-slim@sha256:ca3372ce30b03a591ec573ea975ad8b0ecaf0eb17a354416741f8001bbcae33d
ARG GOLANG_TAG=1.23.3-alpine@sha256:c694a4d291a13a9f9d94933395673494fc2cc9d4777b85df3a7e70b3492d3574
# Tool versions
ARG DEFAULT_TERRAFORM_VERSION=1.9.8
ARG DEFAULT_OPENTOFU_VERSION=1.8.6
ARG DEFAULT_CONFTEST_VERSION=0.56.0
# Stage 1: Get Artifact Atlantis
FROM ghcr.io/runatlantis/atlantis:latest@sha256:f9e0b6ff14b1313b169e4ca128a578fc719745f61114e468afab0d4cbcda575e as builder
WORKDIR /atlantis/src
# Stage 2: Install Dependencies
FROM debian:${DEBIAN_TAG} AS debian-base
# Install base packages
RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
git \
unzip \
openssh-server \
dumb-init \
gnupg \
openssl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Stage 3: Setup Dependencies
FROM debian-base AS deps
# Install git-lfs
ENV GIT_LFS_VERSION=3.6.0
ENV TARGETPLATFORM=linux/amd64
WORKDIR /tmp/build
RUN case ${TARGETPLATFORM} in \
"linux/amd64") GIT_LFS_ARCH=amd64 ;; \
"linux/arm64") GIT_LFS_ARCH=arm64 ;; \
"linux/arm/v7") GIT_LFS_ARCH=arm ;; \
esac && \
curl -L -s --output git-lfs.tar.gz "https://github.com/git-lfs/git-lfs/releases/download/v${GIT_LFS_VERSION}/git-lfs-linux-${GIT_LFS_ARCH}-v${GIT_LFS_VERSION}.tar.gz" && \
tar --strip-components=1 -xf git-lfs.tar.gz && \
chmod +x git-lfs && \
mv git-lfs /usr/bin/git-lfs && \
git-lfs --version
# Install terraform binaries
ARG DEFAULT_TERRAFORM_VERSION
ENV DEFAULT_TERRAFORM_VERSION=${DEFAULT_TERRAFORM_VERSION:-1.9.8}
ARG DEFAULT_OPENTOFU_VERSION
ENV DEFAULT_OPENTOFU_VERSION=${DEFAULT_OPENTOFU_VERSION:-1.8.6}
COPY scripts/download-release.sh download-release.sh
RUN ./download-release.sh \
"terraform" \
"${TARGETPLATFORM}" \
"${DEFAULT_TERRAFORM_VERSION}" \
"1.6.6 1.7.5 1.8.5 ${DEFAULT_TERRAFORM_VERSION} 1.10.5 1.11.4" \
&& ./download-release.sh \
"tofu" \
"${TARGETPLATFORM}" \
"${DEFAULT_OPENTOFU_VERSION}" \
"${DEFAULT_OPENTOFU_VERSION}"
# Final Stage: Build sBeacon-Atlantis
FROM public.ecr.aws/sam/build-python3.12:latest-x86_64
# Switch to root for installations
USER root
# Set locale environment variables
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
LANGUAGE=C.UTF-8
# Install core dependencies and development tools
RUN dnf update -y --allowerasing && \
dnf install -y --allowerasing \
wget \
curl \
git \
jq \
tar \
docker \
gcc \
gcc-c++ \
make \
cmake \
vim \
openssl-devel \
libcurl-devel \
bzip2-devel \
libffi-devel \
xz-devel \
autoconf \
intltool \
glibc-langpack-en \
zlib-devel && \
dnf clean all && \
rm -rf /var/cache/dnf/*
# Setup Docker environment
RUN mkdir -p /etc/docker && \
echo '{"storage-driver": "overlay2", "features": {"buildkit": true}}' > /etc/docker/daemon.json && \
mkdir -p /var/lib/docker && \
mkdir -p /var/run/docker && \
chmod 2777 /var/run/docker
# Install Python 3.12
RUN cd /tmp && \
wget https://www.python.org/ftp/python/3.12.0/Python-3.12.0.tgz && \
tar xzf Python-3.12.0.tgz && \
cd Python-3.12.0 && \
./configure --enable-optimizations && \
make altinstall && \
cd .. && \
rm -rf Python-3.12.0* && \
ln -sf /usr/local/bin/python3.12 /usr/bin/python && \
ln -sf /usr/local/bin/python3.12 /usr/bin/python3 && \
ln -sf /usr/local/bin/pip3.12 /usr/bin/pip && \
ln -sf /usr/local/bin/pip3.12 /usr/bin/pip3
# Create system users and groups
RUN echo "docker:x:999:" >> /etc/group && \
mkdir -p /home/atlantis && \
echo "atlantis:x:100:100:atlantis:/home/atlantis:/bin/bash" >> /etc/passwd && \
echo "atlantis:x:100:" >> /etc/group && \
sed -i 's/docker:x:999:/docker:x:999:100/' /etc/group && \
chown -R 100:100 /home/atlantis
# Setup directory structure with proper permissions
RUN mkdir -p /home/atlantis/.aws && \
mkdir -p /home/atlantis/.docker && \
mkdir -p /home/atlantis/.local/share/pnpm && \
mkdir -p /atlantis-data && \
mkdir -p /atlantis && \
chown -R 100:100 /home/atlantis/.aws && \
chown -R 100:100 /home/atlantis/.docker && \
chown -R 100:100 /home/atlantis/.local && \
chown -R 100:100 /atlantis-data && \
chown -R 100:100 /atlantis && \
chmod 700 /home/atlantis/.aws && \
chmod 700 /home/atlantis/.docker && \
chmod 700 /home/atlantis/.local
# Install dumb-init
RUN pip install --no-cache-dir dumb-init && \
chmod +x /var/lang/bin/dumb-init && \
ln -s /var/lang/bin/dumb-init /usr/local/bin/dumb-init
# Install Terraform
RUN wget https://releases.hashicorp.com/terraform/1.9.4/terraform_1.9.4_linux_amd64.zip && \
unzip terraform_1.9.4_linux_amd64.zip -d /usr/bin/ && \
rm terraform_1.9.4_linux_amd64.zip && \
chmod +x /usr/bin/terraform
# Copy binaries and setup environment
COPY --from=builder /usr/local/bin/atlantis /usr/local/bin/atlantis
COPY --from=deps /usr/local/bin/terraform/terraform* /usr/local/bin/
COPY --from=deps /usr/local/bin/tofu/tofu* /usr/local/bin/
COPY --from=deps /usr/bin/git-lfs /usr/bin/git-lfs
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
# Set correct permissions
RUN chmod +x /usr/local/bin/docker-entrypoint.sh && \
chmod +x /usr/local/bin/atlantis && \
chown -R 100:100 /usr/local/bin/atlantis && \
# Ensure atlantis user can access required directories
mkdir -p /atlantis-data && \
chown -R 100:100 /atlantis-data
RUN mkdir -p /home/atlantis/{.ssh,.aws,.local,.nvm,.docker,.config,.pyenv,.npm,.pnpm,.atlantis} && \
chown -R 100:100 /home/atlantis/{.ssh,.aws,.local,.nvm,.docker,.config,.pyenv,.npm,.pnpm,.atlantis}
COPY config/docker/home /home
COPY config/docker/etc /etc
COPY docker-entrypoint.sh /home/atlantis
# Switch to atlantis user
USER 100
# Setup Node.js environment variables
ENV NODE_VERSION=20
ENV NVM_DIR="/home/atlantis/.nvm"
ENV PNPM_HOME="/home/atlantis/.local/share/pnpm"
ENV PATH="/home/atlantis/.local/bin:${PNPM_HOME}:${PATH}:/home/atlantis/.nvm/versions/node/v${NODE_VERSION}/bin"
# Install Node.js, npm, and pnpm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash && \
. "$NVM_DIR/nvm.sh" && \
nvm install ${NODE_VERSION} && \
nvm use ${NODE_VERSION} && \
nvm alias default ${NODE_VERSION} && \
npm install -g pnpm
# Install Python requirements
COPY requirements.txt ./
RUN pip install --upgrade pip && \
pip install -r requirements.txt
# Set the exposed port
EXPOSE ${ATLANTIS_PORT:-4141}
# Health check
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost:${ATLANTIS_PORT:-4141}/healthz || exit 1
WORKDIR /home/atlantis
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["server"]
docker-compose.ymlversion: '3.8'
#================================================================================================
# NETWORK SETUP
#================================================================================================
networks:
atlantis_net:
name: atlantis_net
driver: bridge
ipam:
config:
- subnet: 172.149.0.0/16
#================================================================================================
# VOLUME SETUP
#================================================================================================
volumes:
vol_atlantis:
driver: ${VOLUMES_DRIVER:-local}
driver_opts:
o: bind
type: none
device: ${DATA_ATLANTIS:-/opt/data/docker/atlantis}
vol_atlantis_aws:
driver: ${VOLUMES_DRIVER:-local}
driver_opts:
o: bind
type: none
device: ${DATA_ATLANTIS_AWS:-/opt/data/docker/atlantis/aws}
vol_atlantis_src:
driver: ${VOLUMES_DRIVER:-local}
driver_opts:
o: bind
type: none
device: ${DATA_ATLANTIS_AWS:-/opt/data/docker/atlantis/src}
#================================================================================================
# SERVICES
#================================================================================================
services:
#================================================================================================
# PORTAINER
#================================================================================================
portainer:
# image: dockerframework/portainer:${PORTAINER_VERSION:-2.9}
image: portainer/portainer-ce:${PORTAINER_VERSION:-2.20.3-alpine}
container_name: ${CONTAINER_PORTAINER:-devopsxti_portainer}
restart: unless-stopped
ports:
- "${PORT_PORTAINER:-5212}:9000"
volumes:
# - /etc/localtime:/etc/localtime:ro ## Do not use it in mac
- /var/run/docker.sock:/var/run/docker.sock ## Do not use it in k8s
- /opt/data/docker/portainer2.20:/data
environment:
- PORTAINER_TEMPLATE=generic
- PORTAINER_VERSION=${PORTAINER_VERSION:-2.20.3-alpine}
privileged: true
networks:
atlantis_net:
ipv4_address: ${CONTAINER_IP_PORTAINER:-172.149.149.5}
#================================================================================================
# ATLANTIS TERRAFORM
#================================================================================================
atlantis:
build:
context: .
dockerfile: Dockerfile
args:
PYTHON_VERSION: 3.12
image: ${ATLANTIS_IMAGE:-devopsxti/atlantis-sbeacon}:${ATLANTIS_VERSION:-latest}
container_name: ${CONTAINER_ATLANTIS:-devopsxti_atlantis}
restart: unless-stopped
ports:
- "${PORT_ATLANTIS:-4141}:4141"
volumes:
# System mounts
- /var/run/docker.sock:/var/run/docker.sock
# Project data
- vol_atlantis_src:/atlantis/src:ro
# AWS credentials with correct permissions
- ${DATA_ATLANTIS_AWS:-/opt/data/docker/atlantis/aws}/credentials:/home/atlantis/.aws/credentials:ro
- ${DATA_ATLANTIS_AWS:-/opt/data/docker/atlantis/aws}/config:/home/atlantis/.aws/config:ro
# Atlantis configuration
- ${DATA_ATLANTIS:-/opt/data/docker/atlantis}/atlantis.yaml:/atlantis/atlantis.yaml:ro
# Additional project directories
- ${DATA_ATLANTIS:-/opt/data/docker/atlantis}/data:/atlantis-data
environment:
# GitHub Configuration
- ATLANTIS_GH_HOSTNAME=github.com
- ATLANTIS_GH_USER=${ATLANTIS_GH_USER:-devopsxti}
- ATLANTIS_GH_TOKEN=${ATLANTIS_GH_TOKEN}
- ATLANTIS_GH_WEBHOOK_SECRET=${ATLANTIS_GH_WEBHOOK_SECRET}
# Web Configuration
- ATLANTIS_WEB_HOSTNAME=${ATLANTIS_WEB_HOSTNAME:-atlantis.devopsxti.id}
- ATLANTIS_PORT=${PORT_ATLANTIS:-4141}
# AWS Configuration
- AWS_REGION=${AWS_REGION:-ap-southeast-3}
- AWS_SHARED_CREDENTIALS_FILE=/home/atlantis/.aws/credentials
- AWS_CONFIG_FILE=/home/atlantis/.aws/config
# Project Configuration
- ATLANTIS_CONFIG=/atlantis/atlantis.yaml
- ATLANTIS_ALLOW_COMMANDS=version,plan,apply,unlock,approve_policies
- ATLANTIS_REPO_ALLOWLIST=${ATLANTIS_REPO_ALLOWLIST:-github.com/devopsxti/*}
# Other Configuration
- DEFAULT_CONFTEST_VERSION=${CONFTEST_VERSION:-0.56.0}
- TZ=Asia/Jakarta
- PYTHONPATH=/usr/local/lib/python3.12/site-packages
user: "100:100"
privileged: true
networks:
atlantis_net:
ipv4_address: ${CONTAINER_IP_ATLANTIS:-172.149.149.6}
docker-entrypoint.sh#!/usr/bin/env -S dumb-init --single-child /bin/bash
set -e
# Function to check if we have docker socket access
check_docker_socket() {
if [ -S /var/run/docker.sock ]; then
# Test docker socket access
if docker info >/dev/null 2>&1; then
echo "Docker socket is accessible and working"
return 0
else
echo "Docker socket exists but not accessible"
return 1
fi
else
echo "No Docker socket found"
return 1
fi
}
# Setup environment
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
export PNPM_HOME="/home/atlantis/.local/share/pnpm"
export PATH="${PNPM_HOME}:${PATH}"
# Source profile and bashrc if they exist
[ -f $HOME/.bash_profile ] && source $HOME/.bash_profile
[ -f $HOME/.bashrc ] && source $HOME/.bashrc
# If we're trying to run atlantis directly with some arguments, then
# pass them to atlantis.
if [ "${1:0:1}" = '-' ]; then
set -- atlantis "$@"
fi
# Check if running a atlantis subcommand
if atlantis help "$1" 2>&1 | grep -q "atlantis $1"; then
set -- atlantis "$@"
fi
# Create user in /etc/passwd if running without user
if ! whoami &> /dev/null; then
if [ -w /etc/passwd ]; then
echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:/home/atlantis:/sbin/nologin" >> /etc/passwd
fi
fi
# Check for scripts in /docker-entrypoint.d/
if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then
echo "/docker-entrypoint.d/ is not empty, executing scripts"
find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do
case "$f" in
*.sh)
if [ -x "$f" ]; then
echo "Executing $f"
"$f"
else
echo "Ignoring $f, not executable"
fi
;;
*) echo "Ignoring $f";;
esac
done
else
echo "No files found in /docker-entrypoint.d/, skipping"
fi
# Verify Docker socket access
if check_docker_socket; then
echo "Docker is available and working"
else
echo "WARNING: Docker socket not accessible. Some features may be limited."
fi
# Verify environment
echo "Verifying environment..."
echo ""
echo "==========================================================="
echo " Atlantis Server: "
echo " $(atlantis version) "
echo "==========================================================="
echo " Node version: $(node --version 2>/dev/null || echo 'Not available')"
echo " NPM version: $(npm --version 2>/dev/null || echo 'Not available')"
echo " PNPM version: $(pnpm --version 2>/dev/null || echo 'Not available')"
echo " Python version: $(python --version 2>&1 || echo 'Not available')"
echo " Terraform version: $(terraform --version 2>/dev/null | head -n1 || echo 'Not available')"
if check_docker_socket; then
echo " Docker version: $(docker --version 2>/dev/null || echo 'Not available')"
else
echo " Docker version: Not available (no socket access)"
fi
echo "==========================================================="
# Execute the main command
exec "$@"
#================================================================================================
# CORE CONFIGURATION
#================================================================================================
# Environment
TZ=Asia/Jakarta
PYTHONPATH=/usr/local/lib/python3.12/site-packages
#================================================================================================
# VOLUME CONFIGURATION
#================================================================================================
# Volume Driver
VOLUMES_DRIVER=local
# Base Data Paths
DATA_PATH=/opt/data/docker
DATA_ATLANTIS=${DATA_PATH}/atlantis
DATA_ATLANTIS_AWS=${DATA_ATLANTIS}/aws
DATA_ATLANTIS_SRC=${DATA_ATLANTIS}/src
#================================================================================================
# CONTAINER CONFIGURATION
#================================================================================================
# Atlantis Container
CONTAINER_ATLANTIS=devopsxti_atlantis
CONTAINER_IP_ATLANTIS=172.149.149.6
PORT_ATLANTIS=4141
# Portainer Container
CONTAINER_PORTAINER=devopsxti_portainer
CONTAINER_IP_PORTAINER=172.149.149.5
PORT_PORTAINER=5212
#================================================================================================
# IMAGE CONFIGURATION
#================================================================================================
# Atlantis
ATLANTIS_VERSION=latest
ATLANTIS_IMAGE=devopsxti/atlantis-sbeacon
# Portainer
PORTAINER_VERSION=2.20.3-alpine
PORTAINER_TEMPLATE=generic
#================================================================================================
# GITHUB CONFIGURATION
#================================================================================================
ATLANTIS_GH_HOSTNAME=github.com
ATLANTIS_GH_USER=devopsxti
ATLANTIS_WEB_HOSTNAME=atlantis.devopsxti.id
ATLANTIS_REPO_ALLOWLIST=github.com/devopsxti/*
# Security Secrets (DO NOT COMMIT - Set these in .env.local)
# ATLANTIS_GH_TOKEN=your-github-token
# ATLANTIS_GH_WEBHOOK_SECRET=your-webhook-secret
#================================================================================================
# AWS CONFIGURATION
#================================================================================================
# Region
AWS_REGION=ap-southeast-3
#================================================================================================
# TOOL VERSIONS
#================================================================================================
CONFTEST_VERSION=0.56.0
PYTHON_VERSION=3.12
package.json{
"license": "Apache-2.0",
"type": "module",
"devDependencies": {
"@playwright/test": "^1.44.0",
"@types/node": "^20.12.12",
"@vueuse/core": "^10.9.0",
"markdown-it-footnote": "^4.0.0",
"markdownlint-cli": "^0.40.0",
"mermaid": "^10.9.1",
"sitemap-ts": "^1.7.3",
"vitepress": "^1.2.3",
"vitepress-plugin-mermaid": "^2.0.16",
"vue": "^3.4.27"
},
"scripts": {
"website:dev": "vitepress dev --host localhost --port 8080 runatlantis.io",
"website:lint": "markdownlint runatlantis.io",
"website:lint-fix": "markdownlint --fix runatlantis.io",
"website:build": "vitepress build runatlantis.io",
"e2e": "playwright test"
}
}
Content type
Image
Digest
sha256:a961f24b7…
Size
1.6 GB
Last updated
about 1 year ago
docker pull devopsxti/atlantis-gxc