Sign inSign up

devopsxti/atlantis-gxc

By devopsxti

•Updated about 1 year ago

Docker Images sBeacon with Atlantis, Portainer and Nginx

Image
Developer tools
Monitoring & observability
0

2.7K

devopsxti/atlantis-gxc repository overview

⁠Atlantis sBeacon Dockerfile Documentation

⁠Overview

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

  • Docker Images: devopsxti/atlantis-sbeacon:latest

⁠Reference

⁠Dockerfile atlantis-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 docker-compose.yml

version: '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 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 "$@"

⁠Environment Variable (.env)

#================================================================================================
# 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 Javascript 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"
  }
}

  • Author: DevOps Engineer
  • Vendor: Xapiens Technology Indonesia (@xapiens.id)
  • License: Apache v2

Tag summary

Content type

Image

Digest

sha256:a961f24b7…

Size

1.6 GB

Last updated

about 1 year ago

docker pull devopsxti/atlantis-gxc