Fixed several issues and made some enhancement to make it more robust. now pushing to both gitea server and github.
This commit is contained in:
4
.dockerignore
Normal file
4
.dockerignore
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.git
|
||||||
|
build.sh
|
||||||
|
README.md
|
||||||
|
.dockerignore
|
||||||
14
Dockerfile
14
Dockerfile
@@ -2,7 +2,7 @@ ARG UBUNTU_VER=24.04
|
|||||||
|
|
||||||
FROM ubuntu:${UBUNTU_VER}
|
FROM ubuntu:${UBUNTU_VER}
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
# Enable autocompletion and install packages in optimized layers
|
# Enable autocompletion and install packages in optimized layers
|
||||||
RUN rm /etc/apt/apt.conf.d/docker-* && \
|
RUN rm /etc/apt/apt.conf.d/docker-* && \
|
||||||
@@ -30,11 +30,10 @@ RUN apt update && apt install -y \
|
|||||||
# Remote access
|
# Remote access
|
||||||
openssh-server \
|
openssh-server \
|
||||||
# Localization
|
# Localization
|
||||||
locales
|
locales \
|
||||||
|
# Install Node.js using official NodeSource repository
|
||||||
# Install Node.js using official NodeSource repository
|
&& curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - \
|
||||||
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - && \
|
&& apt-get install -y nodejs
|
||||||
apt-get install -y nodejs
|
|
||||||
|
|
||||||
# Configure locales
|
# Configure locales
|
||||||
ENV LC_ALL=en_US.UTF-8
|
ENV LC_ALL=en_US.UTF-8
|
||||||
@@ -63,9 +62,6 @@ RUN chmod +x /entrypoint.sh
|
|||||||
|
|
||||||
ENV LOG_FILE=/dev/null
|
ENV LOG_FILE=/dev/null
|
||||||
|
|
||||||
# Reset DEBIAN_FRONTEND
|
|
||||||
ENV DEBIAN_FRONTEND=""
|
|
||||||
|
|
||||||
EXPOSE 22
|
EXPOSE 22
|
||||||
|
|
||||||
CMD ["/entrypoint.sh"]
|
CMD ["/entrypoint.sh"]
|
||||||
|
|||||||
87
README.md
Normal file
87
README.md
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
# Ubuntu Dev Environment
|
||||||
|
|
||||||
|
Multi-arch (`amd64`/`arm64`) Ubuntu Docker images with pre-installed networking, development, and debugging tools. Built for use as a general-purpose dev environment.
|
||||||
|
|
||||||
|
## Available Images
|
||||||
|
|
||||||
|
| Version | Gitea | GitHub |
|
||||||
|
|---------|-------|--------|
|
||||||
|
| 24.04 (latest) | `gitea.ahkhan.me/docker/ubuntu-24.04` | `ghcr.io/ahkhan03/ubuntu-24.04` |
|
||||||
|
| 22.04 | `gitea.ahkhan.me/docker/ubuntu-22.04` | `ghcr.io/ahkhan03/ubuntu-22.04` |
|
||||||
|
| 20.04 | `gitea.ahkhan.me/docker/ubuntu-20.04` | `ghcr.io/ahkhan03/ubuntu-20.04` |
|
||||||
|
|
||||||
|
The `ubuntu:latest` tag points to Ubuntu 24.04.
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
### SSH
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `ENABLE_SSH` | `true` | Start the SSH server on port 22. Set to `false` to disable. |
|
||||||
|
|
||||||
|
### Startup / Shutdown Commands
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `COMMAND_INIT` | — | Command to run on container startup. The last init command runs in the background to allow signal handling. |
|
||||||
|
| `COMMAND_INIT01`..`COMMAND_INIT99` | — | Additional numbered init commands, executed in order after `COMMAND_INIT`. |
|
||||||
|
| `COMMAND_EXIT` | — | Command to run on container shutdown (before processes are terminated). |
|
||||||
|
| `COMMAND_EXIT01`..`COMMAND_EXIT99` | — | Additional numbered exit commands, executed in order after `COMMAND_EXIT`. |
|
||||||
|
|
||||||
|
### Logging
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `LOG_FILE` | `/dev/null` | Path to a log file to tail. When set, the container's stdout will stream this file. |
|
||||||
|
|
||||||
|
### Mirrors (China)
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `USE_CHINA_MIRRORS` | `false` | Switch apt, pip, and npm to Aliyun mirrors on startup. |
|
||||||
|
|
||||||
|
### Package Updates
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `UPDATE_APT` | `false` | Run `apt update` on startup (with network check). |
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
Basic:
|
||||||
|
```bash
|
||||||
|
docker run -d ghcr.io/ahkhan03/ubuntu-24.04
|
||||||
|
```
|
||||||
|
|
||||||
|
With a startup command and SSH:
|
||||||
|
```bash
|
||||||
|
docker run -d -p 2222:22 \
|
||||||
|
-e COMMAND_INIT="echo 'hello from init'" \
|
||||||
|
ghcr.io/ahkhan03/ubuntu-24.04
|
||||||
|
```
|
||||||
|
|
||||||
|
Multiple init/exit commands:
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
-e COMMAND_INIT01="echo 'first'" \
|
||||||
|
-e COMMAND_INIT02="python3 -m http.server 8080" \
|
||||||
|
-e COMMAND_EXIT01="echo 'shutting down'" \
|
||||||
|
ghcr.io/ahkhan03/ubuntu-24.04
|
||||||
|
```
|
||||||
|
|
||||||
|
Without SSH, with China mirrors:
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
-e ENABLE_SSH=false \
|
||||||
|
-e USE_CHINA_MIRRORS=true \
|
||||||
|
ghcr.io/ahkhan03/ubuntu-24.04
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
See `./build.sh --help` for configuration options.
|
||||||
40
build.sh
40
build.sh
@@ -3,8 +3,10 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
REGISTRY="${REGISTRY:-gitea.ahkhan.me}"
|
REGISTRY="${REGISTRY:-gitea2.ahkhan.me}" # pushed through gitea2 because gitea is behind CF tunnel and has issues with large image pushes.
|
||||||
REGISTRY_PATH="${REGISTRY_PATH:-docker}"
|
REGISTRY_PATH="${REGISTRY_PATH:-packages}"
|
||||||
|
GITHUB_REGISTRY="${GITHUB_REGISTRY:-ghcr.io}"
|
||||||
|
GITHUB_USER="${GITHUB_USER:-ahkhan03}"
|
||||||
REPO_PREFIX="${REPO_PREFIX:-ubuntu}"
|
REPO_PREFIX="${REPO_PREFIX:-ubuntu}"
|
||||||
PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}"
|
PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}"
|
||||||
DATE_TAG=$(date +%Y-%m-%d)
|
DATE_TAG=$(date +%Y-%m-%d)
|
||||||
@@ -43,15 +45,18 @@ build_ubuntu_version() {
|
|||||||
|
|
||||||
log "Building Ubuntu ${version}..."
|
log "Building Ubuntu ${version}..."
|
||||||
|
|
||||||
# Build tags for this version
|
# Build tags for this version (Gitea + GitHub)
|
||||||
local tags=(
|
local tags=(
|
||||||
"${REGISTRY}/${REGISTRY_PATH}/${repo_name}:latest"
|
"${REGISTRY}/${REGISTRY_PATH}/${repo_name}:latest"
|
||||||
"${REGISTRY}/${REGISTRY_PATH}/${repo_name}:${DATE_TAG}"
|
"${REGISTRY}/${REGISTRY_PATH}/${repo_name}:${DATE_TAG}"
|
||||||
|
"${GITHUB_REGISTRY}/${GITHUB_USER}/${repo_name}:latest"
|
||||||
|
"${GITHUB_REGISTRY}/${GITHUB_USER}/${repo_name}:${DATE_TAG}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add ubuntu:latest tag only for the latest version
|
# Add ubuntu:latest tag only for the latest version
|
||||||
if [[ "$version" == "$LATEST_VERSION" ]]; then
|
if [[ "$version" == "$LATEST_VERSION" ]]; then
|
||||||
tags+=("${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}:latest")
|
tags+=("${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}:latest")
|
||||||
|
tags+=("${GITHUB_REGISTRY}/${GITHUB_USER}/${REPO_PREFIX}:latest")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Build tag arguments
|
# Build tag arguments
|
||||||
@@ -124,7 +129,8 @@ validate_setup() {
|
|||||||
# Function to show build summary
|
# Function to show build summary
|
||||||
show_summary() {
|
show_summary() {
|
||||||
log "Build Summary:"
|
log "Build Summary:"
|
||||||
echo "Registry: $REGISTRY"
|
echo "Gitea registry: $REGISTRY/$REGISTRY_PATH"
|
||||||
|
echo "GitHub registry: $GITHUB_REGISTRY/$GITHUB_USER"
|
||||||
echo "Date tag: $DATE_TAG"
|
echo "Date tag: $DATE_TAG"
|
||||||
echo "Platforms: $PLATFORMS"
|
echo "Platforms: $PLATFORMS"
|
||||||
echo "Ubuntu versions: ${UBUNTU_VERSIONS[*]}"
|
echo "Ubuntu versions: ${UBUNTU_VERSIONS[*]}"
|
||||||
@@ -132,11 +138,14 @@ show_summary() {
|
|||||||
|
|
||||||
echo "Images that will be built:"
|
echo "Images that will be built:"
|
||||||
for version in "${UBUNTU_VERSIONS[@]}"; do
|
for version in "${UBUNTU_VERSIONS[@]}"; do
|
||||||
echo " ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}-${version}:latest"
|
echo " Gitea: ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}-${version}:latest"
|
||||||
echo " ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}-${version}:${DATE_TAG}"
|
echo " Gitea: ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}-${version}:${DATE_TAG}"
|
||||||
echo " ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}-${version}:buildcache (cache)"
|
echo " GitHub: ${GITHUB_REGISTRY}/${GITHUB_USER}/${REPO_PREFIX}-${version}:latest"
|
||||||
|
echo " GitHub: ${GITHUB_REGISTRY}/${GITHUB_USER}/${REPO_PREFIX}-${version}:${DATE_TAG}"
|
||||||
|
echo " Cache: ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}-${version}:buildcache"
|
||||||
if [[ "$version" == "$LATEST_VERSION" ]]; then
|
if [[ "$version" == "$LATEST_VERSION" ]]; then
|
||||||
echo " ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}:latest"
|
echo " Gitea: ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}:latest"
|
||||||
|
echo " GitHub: ${GITHUB_REGISTRY}/${GITHUB_USER}/${REPO_PREFIX}:latest"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
done
|
done
|
||||||
@@ -169,10 +178,13 @@ main() {
|
|||||||
|
|
||||||
log "Available images:"
|
log "Available images:"
|
||||||
for version in "${UBUNTU_VERSIONS[@]}"; do
|
for version in "${UBUNTU_VERSIONS[@]}"; do
|
||||||
echo " ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}-${version}:latest"
|
echo " Gitea: ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}-${version}:latest"
|
||||||
echo " ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}-${version}:${DATE_TAG}"
|
echo " Gitea: ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}-${version}:${DATE_TAG}"
|
||||||
|
echo " GitHub: ${GITHUB_REGISTRY}/${GITHUB_USER}/${REPO_PREFIX}-${version}:latest"
|
||||||
|
echo " GitHub: ${GITHUB_REGISTRY}/${GITHUB_USER}/${REPO_PREFIX}-${version}:${DATE_TAG}"
|
||||||
done
|
done
|
||||||
echo " ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}:latest (→ Ubuntu ${LATEST_VERSION})"
|
echo " Gitea: ${REGISTRY}/${REGISTRY_PATH}/${REPO_PREFIX}:latest (→ Ubuntu ${LATEST_VERSION})"
|
||||||
|
echo " GitHub: ${GITHUB_REGISTRY}/${GITHUB_USER}/${REPO_PREFIX}:latest (→ Ubuntu ${LATEST_VERSION})"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Help function
|
# Help function
|
||||||
@@ -182,8 +194,10 @@ show_help() {
|
|||||||
echo "Usage: $0 [OPTIONS]"
|
echo "Usage: $0 [OPTIONS]"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Environment Variables:"
|
echo "Environment Variables:"
|
||||||
echo " REGISTRY Docker registry (default: gitea.ahkhan.me)"
|
echo " REGISTRY Gitea registry (default: gitea.ahkhan.me)"
|
||||||
echo " REGISTRY_PATH Registry path (default: docker)"
|
echo " REGISTRY_PATH Gitea registry path (default: docker)"
|
||||||
|
echo " GITHUB_REGISTRY GitHub registry (default: ghcr.io)"
|
||||||
|
echo " GITHUB_USER GitHub username (default: ahkhan03)"
|
||||||
echo " REPO_PREFIX Repository prefix (default: ubuntu)"
|
echo " REPO_PREFIX Repository prefix (default: ubuntu)"
|
||||||
echo " PLATFORMS Target platforms (default: linux/amd64,linux/arm64)"
|
echo " PLATFORMS Target platforms (default: linux/amd64,linux/arm64)"
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
@@ -8,10 +8,16 @@ set -e
|
|||||||
echo "Configuring Chinese mirrors (Aliyun) for apt, pip, and npm..."
|
echo "Configuring Chinese mirrors (Aliyun) for apt, pip, and npm..."
|
||||||
|
|
||||||
# Replace Ubuntu sources with Aliyun mirror
|
# Replace Ubuntu sources with Aliyun mirror
|
||||||
|
# Ubuntu 24.04+ uses DEB822 format in sources.list.d/ubuntu.sources
|
||||||
if [[ -f /etc/apt/sources.list.d/ubuntu.sources ]]; then
|
if [[ -f /etc/apt/sources.list.d/ubuntu.sources ]]; then
|
||||||
sudo sed -i 's|http://archive.ubuntu.com/ubuntu/|https://mirrors.aliyun.com/ubuntu/|g' /etc/apt/sources.list.d/ubuntu.sources
|
sudo sed -i 's|http://archive.ubuntu.com/ubuntu/|https://mirrors.aliyun.com/ubuntu/|g' /etc/apt/sources.list.d/ubuntu.sources
|
||||||
sudo sed -i 's|http://security.ubuntu.com/ubuntu/|https://mirrors.aliyun.com/ubuntu/|g' /etc/apt/sources.list.d/ubuntu.sources
|
sudo sed -i 's|http://security.ubuntu.com/ubuntu/|https://mirrors.aliyun.com/ubuntu/|g' /etc/apt/sources.list.d/ubuntu.sources
|
||||||
echo "Updated Ubuntu apt sources to use Aliyun mirrors"
|
echo "Updated Ubuntu apt sources (DEB822 format) to use Aliyun mirrors"
|
||||||
|
# Ubuntu 22.04 and older use the traditional sources.list format
|
||||||
|
elif [[ -f /etc/apt/sources.list ]]; then
|
||||||
|
sudo sed -i 's|http://archive.ubuntu.com/ubuntu|https://mirrors.aliyun.com/ubuntu|g' /etc/apt/sources.list
|
||||||
|
sudo sed -i 's|http://security.ubuntu.com/ubuntu|https://mirrors.aliyun.com/ubuntu|g' /etc/apt/sources.list
|
||||||
|
echo "Updated Ubuntu apt sources (sources.list format) to use Aliyun mirrors"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Configure npm registry to use Chinese mirror (npmmirror.com is the recommended mirror)
|
# Configure npm registry to use Chinese mirror (npmmirror.com is the recommended mirror)
|
||||||
|
|||||||
@@ -3,14 +3,19 @@
|
|||||||
# Setup home directory for the current user
|
# Setup home directory for the current user
|
||||||
# Useful for attaching vscode with container
|
# Useful for attaching vscode with container
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
user_name=$(whoami)
|
user_name=$(whoami)
|
||||||
user_home="/home/$user_name"
|
|
||||||
|
# Root's home is /root, not /home/root
|
||||||
|
if [[ "$user_name" == "root" ]]; then
|
||||||
|
user_home="/root"
|
||||||
|
else
|
||||||
|
user_home="/home/$user_name"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Setting up home directory for user: $user_name"
|
echo "Setting up home directory for user: $user_name"
|
||||||
sudo mkdir -p "$user_home"
|
sudo mkdir -p "$user_home"
|
||||||
sudo chown -R "$(id -u):$(id -g)" "$user_home"
|
sudo chown -R "$(id -u):$(id -g)" "$user_home"
|
||||||
cp -r /etc/skel/. "$user_home" 2>/dev/null || true
|
# Use -n (no-clobber) to avoid overwriting existing dotfiles (e.g. from mounted volumes)
|
||||||
|
cp -rn /etc/skel/. "$user_home" 2>/dev/null || true
|
||||||
|
|
||||||
echo "Home directory setup completed: $user_home"
|
echo "Home directory setup completed: $user_home"
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ term_handler() {
|
|||||||
# Kill any still-running background processes if they didn't shut down gracefully
|
# Kill any still-running background processes if they didn't shut down gracefully
|
||||||
if [[ -n "$INIT_PID" ]]; then
|
if [[ -n "$INIT_PID" ]]; then
|
||||||
if kill -0 "$INIT_PID" 2>/dev/null; then
|
if kill -0 "$INIT_PID" 2>/dev/null; then
|
||||||
echo "Init process still running, force killing: $INIT_PID"
|
echo "Init process still running, sending SIGTERM: $INIT_PID"
|
||||||
kill "$INIT_PID" 2>/dev/null
|
kill "$INIT_PID" 2>/dev/null
|
||||||
else
|
else
|
||||||
echo "Init process already terminated gracefully"
|
echo "Init process already terminated gracefully"
|
||||||
@@ -49,9 +49,11 @@ term_handler() {
|
|||||||
kill "$TAIL_PID" 2>/dev/null
|
kill "$TAIL_PID" 2>/dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Stop SSH service
|
# Stop SSH service if it was started
|
||||||
|
if [[ "${ENABLE_SSH:-true}" == "true" || "$ENABLE_SSH" == "1" ]]; then
|
||||||
echo "Stopping SSH service..."
|
echo "Stopping SSH service..."
|
||||||
sudo service ssh stop 2>/dev/null || true
|
sudo service ssh stop 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Cleanup completed, exiting..."
|
echo "Cleanup completed, exiting..."
|
||||||
exit 0
|
exit 0
|
||||||
@@ -75,8 +77,13 @@ if [[ $LOG_FILE != "/dev/null" ]]; then
|
|||||||
sudo chown -R "$(id -u):$(id -g)" "$LOG_FILE"
|
sudo chown -R "$(id -u):$(id -g)" "$LOG_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Starting SSH service..."
|
# Start SSH service unless explicitly disabled
|
||||||
sudo service ssh start
|
if [[ "${ENABLE_SSH:-true}" == "true" || "$ENABLE_SSH" == "1" ]]; then
|
||||||
|
echo "Starting SSH service..."
|
||||||
|
sudo service ssh start
|
||||||
|
else
|
||||||
|
echo "SSH service disabled (ENABLE_SSH=$ENABLE_SSH)"
|
||||||
|
fi
|
||||||
|
|
||||||
# Run initialization commands (last one in background to allow signal handling)
|
# Run initialization commands (last one in background to allow signal handling)
|
||||||
# First collect all defined COMMAND_INIT variables
|
# First collect all defined COMMAND_INIT variables
|
||||||
|
|||||||
Reference in New Issue
Block a user