generated from oci/template
build daily
All checks were successful
Build Docker Image on Commit and Schedule / build-and-publish (push) Successful in 2m38s
All checks were successful
Build Docker Image on Commit and Schedule / build-and-publish (push) Successful in 2m38s
This commit is contained in:
parent
c2281e28e4
commit
53e074c7cf
5 changed files with 260 additions and 42 deletions
|
@ -1,4 +1,4 @@
|
||||||
name: Build Docker Image on Commit
|
name: Build Docker Image on Commit and Schedule
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
@ -6,6 +6,9 @@ on:
|
||||||
- main
|
- main
|
||||||
tags:
|
tags:
|
||||||
- '!' # Exclude tags
|
- '!' # Exclude tags
|
||||||
|
schedule:
|
||||||
|
# Run daily at 2:00 AM UTC to pick up base image updates
|
||||||
|
- cron: '0 2 * * *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-publish:
|
build-and-publish:
|
||||||
|
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/home
|
||||||
|
/workspace
|
106
Dockerfile
106
Dockerfile
|
@ -4,51 +4,75 @@ USER root
|
||||||
|
|
||||||
# Set environment variables
|
# Set environment variables
|
||||||
ENV DEFAULT_WORKSPACE=/workspace
|
ENV DEFAULT_WORKSPACE=/workspace
|
||||||
ENV DOCKER_USER=code
|
# Use the existing coder user from base image instead of non-existent 'code' user
|
||||||
|
ENV DOCKER_USER=coder
|
||||||
|
|
||||||
# Define persistent volumes for /home and /workspace
|
# Define persistent volumes for /home and /workspace
|
||||||
VOLUME ["/home", "/workspace"]
|
VOLUME ["/home", "/workspace"]
|
||||||
|
|
||||||
# Add Docker command support to image
|
# Layer 0: Base system update (foundation layer)
|
||||||
RUN apt-get update && apt-get install ca-certificates curl \
|
|
||||||
&& install -m 0755 -d /etc/apt/keyrings \
|
|
||||||
&& curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc \
|
|
||||||
&& chmod a+r /etc/apt/keyrings/docker.asc
|
|
||||||
RUN echo \
|
|
||||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
|
|
||||||
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
|
|
||||||
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
|
||||||
&& sudo apt-get update
|
|
||||||
|
|
||||||
RUN apt-get install -y --no-install-recommends \
|
|
||||||
docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
|
||||||
|
|
||||||
# Install development tools with optimization for minimal package installs
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get upgrade -y
|
||||||
git \
|
|
||||||
curl \
|
# Layer 1: Docker repository setup (changes rarely)
|
||||||
wget \
|
RUN apt-get install -y --no-install-recommends \
|
||||||
vim \
|
ca-certificates \
|
||||||
zsh \
|
gnupg \
|
||||||
tmux \
|
lsb-release && \
|
||||||
htop \
|
# Add Docker's official GPG key
|
||||||
tree \
|
install -m 0755 -d /etc/apt/keyrings && \
|
||||||
jq \
|
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc && \
|
||||||
unzip \
|
chmod a+r /etc/apt/keyrings/docker.asc && \
|
||||||
zip \
|
# Add Docker repository
|
||||||
gcc \
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
|
||||||
g++ \
|
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
|
||||||
make \
|
tee /etc/apt/sources.list.d/docker.list > /dev/null && \
|
||||||
cmake \
|
apt-get update
|
||||||
python3 \
|
|
||||||
python3-pip \
|
# Layer 2: Docker installation (changes when Docker versions update)
|
||||||
python3-venv && \
|
RUN apt-get install -y --no-install-recommends \
|
||||||
apt-get clean && \
|
docker-ce \
|
||||||
rm -rf /var/lib/apt/lists/*
|
docker-ce-cli \
|
||||||
|
containerd.io \
|
||||||
|
docker-buildx-plugin \
|
||||||
|
docker-compose-plugin && \
|
||||||
|
# Add coder user to docker group for Docker-in-Docker
|
||||||
|
usermod -aG docker coder
|
||||||
|
|
||||||
|
# Layer 3: Homebrew prerequisites (brew.sh requirements)
|
||||||
|
RUN apt-get install -y --no-install-recommends \
|
||||||
|
sudo \
|
||||||
|
build-essential \
|
||||||
|
procps \
|
||||||
|
curl \
|
||||||
|
file \
|
||||||
|
git
|
||||||
|
|
||||||
|
# Layer 4: Code-server entrypoint (always fetch fresh during build)
|
||||||
|
RUN curl -fsSL -o /usr/bin/entrypoint-official.sh \
|
||||||
|
https://raw.githubusercontent.com/coder/code-server/main/ci/release-image/entrypoint.sh && \
|
||||||
|
chmod +x /usr/bin/entrypoint-official.sh
|
||||||
|
|
||||||
|
# Copy our custom entrypoint that chainloads the official one
|
||||||
|
COPY entrypoint.sh /usr/bin/entrypoint.sh
|
||||||
|
RUN chmod +x /usr/bin/entrypoint.sh
|
||||||
|
|
||||||
|
# Set required environment variables for code-server compatibility
|
||||||
|
ENV ENTRYPOINTD=/home/coder/entrypoint.d
|
||||||
|
ENV USER=coder
|
||||||
|
ENV HOME=/home/coder
|
||||||
|
|
||||||
|
# Layer 5: Homebrew official requirements for Debian/Ubuntu
|
||||||
|
RUN apt-get install -y --no-install-recommends \
|
||||||
|
sudo \
|
||||||
|
build-essential \
|
||||||
|
procps \
|
||||||
|
curl \
|
||||||
|
file \
|
||||||
|
git
|
||||||
|
|
||||||
|
# Final cleanup: Remove package lists and temporary files
|
||||||
|
RUN apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
## Workaround as above somehow removed the entrypoint.sh
|
|
||||||
RUN curl -o /usr/bin/entrypoint.sh https://raw.githubusercontent.com/coder/code-server/main/ci/release-image/entrypoint.sh && \
|
|
||||||
chmod +x /usr/bin/entrypoint.sh
|
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/bin/entrypoint.sh", "--bind-addr", "0.0.0.0:8080", "/workspace"]
|
ENTRYPOINT ["/usr/bin/entrypoint.sh", "--bind-addr", "0.0.0.0:8080", "/workspace"]
|
||||||
|
|
14
docker-compose.yml
Normal file
14
docker-compose.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
services:
|
||||||
|
code-server:
|
||||||
|
#image: git.merith.xyz/oci/code-server:nightly
|
||||||
|
build: .
|
||||||
|
container_name: code-server
|
||||||
|
restart: no
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
- ./workspace:/workspace
|
||||||
|
- ./home:/home
|
||||||
|
environment:
|
||||||
|
PASSWORD: "TestPassword"
|
||||||
|
DEFAULT_WORKSPACE: "/workspace"
|
175
entrypoint.sh
Normal file
175
entrypoint.sh
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Custom entrypoint for code-server with additional setup
|
||||||
|
# Supports both rooted Docker containers and rootless Podman containers
|
||||||
|
CURRENT_USER=$(whoami)
|
||||||
|
CURRENT_UID=$(id -u)
|
||||||
|
echo "🚀 Starting custom code-server entrypoint (running as $CURRENT_USER, UID: $CURRENT_UID)..."
|
||||||
|
|
||||||
|
# Detect if we're running as root or not
|
||||||
|
IS_ROOT=false
|
||||||
|
if [ "$CURRENT_UID" -eq 0 ]; then
|
||||||
|
IS_ROOT=true
|
||||||
|
echo "🔐 Running in rooted container mode - will perform system setup"
|
||||||
|
else
|
||||||
|
echo "👤 Running in rootless container mode - assuming permissions already granted"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure proper home directory structure (critical for volume mounts)
|
||||||
|
echo "🏠 Setting up home directory structure..."
|
||||||
|
|
||||||
|
# Create home directory for coder user if it doesn't exist
|
||||||
|
if [ ! -d "/home/coder" ]; then
|
||||||
|
echo "📁 Creating /home/coder directory..."
|
||||||
|
mkdir -p /home/coder
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set ownership only if running as root
|
||||||
|
if [ "$IS_ROOT" = true ]; then
|
||||||
|
chown coder:coder /home/coder
|
||||||
|
chmod 755 /home/coder
|
||||||
|
else
|
||||||
|
# In rootless mode, just ensure it's accessible
|
||||||
|
chmod 755 /home/coder 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set up essential dotfiles and shell configuration
|
||||||
|
if [ ! -f "/home/coder/.bashrc" ]; then
|
||||||
|
echo "⚙️ Creating default .bashrc..."
|
||||||
|
cat > /home/coder/.bashrc << 'EOF'
|
||||||
|
# ~/.bashrc: executed by bash(1) for non-login shells.
|
||||||
|
|
||||||
|
# If not running interactively, don't do anything
|
||||||
|
case $- in
|
||||||
|
*i*) ;;
|
||||||
|
*) return;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Load Homebrew environment if available
|
||||||
|
if [ -d "/home/linuxbrew/.linuxbrew" ]; then
|
||||||
|
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Some useful aliases
|
||||||
|
alias ll='ls -alF'
|
||||||
|
alias la='ls -A'
|
||||||
|
alias l='ls -CF'
|
||||||
|
|
||||||
|
# Enable color support
|
||||||
|
if [ -x /usr/bin/dircolors ]; then
|
||||||
|
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
|
||||||
|
alias ls='ls --color=auto'
|
||||||
|
alias grep='grep --color=auto'
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
# Set ownership only if running as root
|
||||||
|
if [ "$IS_ROOT" = true ]; then
|
||||||
|
chown coder:coder /home/coder/.bashrc
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set up .profile for login shells
|
||||||
|
if [ ! -f "/home/coder/.profile" ]; then
|
||||||
|
echo "⚙️ Creating default .profile..."
|
||||||
|
cat > /home/coder/.profile << 'EOF'
|
||||||
|
# ~/.profile: executed by the command interpreter for login shells.
|
||||||
|
|
||||||
|
# Load Homebrew environment if available
|
||||||
|
if [ -d "/home/linuxbrew/.linuxbrew" ]; then
|
||||||
|
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set PATH to include user's private bin if it exists
|
||||||
|
if [ -d "$HOME/bin" ] ; then
|
||||||
|
PATH="$HOME/bin:$PATH"
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
# Set ownership only if running as root
|
||||||
|
if [ "$IS_ROOT" = true ]; then
|
||||||
|
chown coder:coder /home/coder/.profile
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install/Setup Homebrew if not already present
|
||||||
|
echo "🍺 Setting up Homebrew..."
|
||||||
|
if [ ! -d "/home/linuxbrew/.linuxbrew" ] || [ ! -f "/home/linuxbrew/.linuxbrew/bin/brew" ]; then
|
||||||
|
echo "📦 Installing Homebrew..."
|
||||||
|
|
||||||
|
# Create linuxbrew user directory structure
|
||||||
|
mkdir -p /home/linuxbrew/.linuxbrew
|
||||||
|
|
||||||
|
# Clone Homebrew repository
|
||||||
|
git clone --depth=1 https://github.com/Homebrew/brew /home/linuxbrew/.linuxbrew/Homebrew
|
||||||
|
|
||||||
|
# Create bin directory and symlink
|
||||||
|
mkdir -p /home/linuxbrew/.linuxbrew/bin
|
||||||
|
ln -sf /home/linuxbrew/.linuxbrew/Homebrew/bin/brew /home/linuxbrew/.linuxbrew/bin/brew
|
||||||
|
|
||||||
|
# Set proper ownership only if running as root
|
||||||
|
if [ "$IS_ROOT" = true ]; then
|
||||||
|
chown -R coder:coder /home/linuxbrew
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Homebrew installed successfully!"
|
||||||
|
else
|
||||||
|
echo "✅ Homebrew already installed, ensuring proper ownership..."
|
||||||
|
# Ensure ownership is correct only if running as root (important for volume mounts)
|
||||||
|
if [ "$IS_ROOT" = true ]; then
|
||||||
|
chown -R coder:coder /home/linuxbrew
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create workspace directory if it doesn't exist
|
||||||
|
if [ ! -d "/workspace" ]; then
|
||||||
|
echo "📁 Creating workspace directory..."
|
||||||
|
mkdir -p /workspace
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure proper ownership of workspace only if running as root
|
||||||
|
if [ "$IS_ROOT" = true ]; then
|
||||||
|
chown coder:coder /workspace
|
||||||
|
chmod 755 /workspace
|
||||||
|
else
|
||||||
|
# In rootless mode, just ensure it's accessible
|
||||||
|
chmod 755 /workspace 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set up any workspace-specific initialization
|
||||||
|
if [ -f "/workspace/.devcontainer/init.sh" ]; then
|
||||||
|
echo "🛠️ Running workspace initialization script..."
|
||||||
|
chmod +x /workspace/.devcontainer/init.sh
|
||||||
|
if [ "$IS_ROOT" = true ]; then
|
||||||
|
# Run as coder user when root
|
||||||
|
su - coder -c "/workspace/.devcontainer/init.sh"
|
||||||
|
else
|
||||||
|
# Run directly when not root
|
||||||
|
/workspace/.devcontainer/init.sh
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure the coder user has access to docker if docker group exists (only when root)
|
||||||
|
if [ "$IS_ROOT" = true ] && getent group docker > /dev/null 2>&1; then
|
||||||
|
echo "🐳 Ensuring coder user is in docker group..."
|
||||||
|
usermod -aG docker coder
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Setup complete, chainloading official entrypoint..."
|
||||||
|
|
||||||
|
# Switch to coder user and chainload the official code-server entrypoint
|
||||||
|
if [ "$IS_ROOT" = true ]; then
|
||||||
|
echo "🔄 Switching to coder user and launching code-server..."
|
||||||
|
# Use su with proper environment setup when running as root
|
||||||
|
# Set required environment variables for code-server
|
||||||
|
export ENTRYPOINTD="/home/coder/entrypoint.d"
|
||||||
|
export USER="coder"
|
||||||
|
export HOME="/home/coder"
|
||||||
|
exec su - coder -c "export ENTRYPOINTD=\"/home/coder/entrypoint.d\" && export USER=\"coder\" && export HOME=\"/home/coder\" && cd /workspace && exec /usr/bin/entrypoint-official.sh $*"
|
||||||
|
else
|
||||||
|
echo "🔄 Launching code-server directly..."
|
||||||
|
# Run directly when not root (rootless mode)
|
||||||
|
export ENTRYPOINTD="${HOME}/entrypoint.d"
|
||||||
|
export USER="${USER:-$(whoami)}"
|
||||||
|
cd /workspace
|
||||||
|
exec /usr/bin/entrypoint-official.sh "$@"
|
||||||
|
fi
|
Loading…
Add table
Add a link
Reference in a new issue