Skip to content

Instantly share code, notes, and snippets.

@davydmaker
Last active January 15, 2026 04:59
Show Gist options
  • Select an option

  • Save davydmaker/78d0e5d58b2cdaeacb9f63576e7188d0 to your computer and use it in GitHub Desktop.

Select an option

Save davydmaker/78d0e5d58b2cdaeacb9f63576e7188d0 to your computer and use it in GitHub Desktop.
Setup Colima + Portainer for macOS - Lightweight Docker setup with manual initialization
#!/bin/bash
export PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:$PATH"
echo "Configuring Colima + Portainer..."
echo ""
if ! command -v brew &> /dev/null; then
echo "Error: Homebrew not found. Install from: https://brew.sh"
exit 1
fi
if ! command -v docker &> /dev/null; then
echo "Installing Docker CLI..."
brew install docker
echo "Docker CLI installed"
else
echo "Docker CLI already installed"
docker --version
fi
if ! brew list docker-compose &> /dev/null; then
echo "Installing Docker Compose V2..."
brew install docker-compose
fi
echo "Configuring Docker Compose V2 as plugin..."
mkdir -p ~/.docker/cli-plugins
DOCKER_COMPOSE_PATH=$(brew --prefix)/opt/docker-compose/bin/docker-compose
if [ -f "$DOCKER_COMPOSE_PATH" ]; then
ln -sfn "$DOCKER_COMPOSE_PATH" ~/.docker/cli-plugins/docker-compose
echo "Docker Compose V2 configured"
elif command -v docker-compose &> /dev/null; then
ln -sfn "$(which docker-compose)" ~/.docker/cli-plugins/docker-compose
echo "Docker Compose configured"
fi
if ! command -v colima &> /dev/null; then
echo "Installing Colima..."
brew install colima
echo "Colima installed"
else
echo "Colima already installed"
colima --version
fi
echo ""
echo "Checking for QEMU (required for x86_64 emulation)..."
if ! command -v qemu-img &> /dev/null; then
echo "QEMU not found. Installing QEMU..."
brew install qemu
echo "QEMU installed"
else
echo "QEMU already installed"
fi
echo ""
echo "Checking for Lima additional guest agents (required for x86_64)..."
if ! brew list lima-additional-guestagents &> /dev/null; then
echo "Lima additional guest agents not found. Installing..."
brew install lima-additional-guestagents
echo "Lima additional guest agents installed"
else
echo "Lima additional guest agents already installed"
fi
echo ""
echo "Configuring Docker to not use credential helper..."
mkdir -p ~/.docker
cat > ~/.docker/config.json << 'DOCKERCONFIG'
{
"auths": {},
"currentContext": "colima",
"credsStore": ""
}
DOCKERCONFIG
echo "Docker configuration updated"
echo ""
echo "Configuring Colima..."
if colima status &> /dev/null; then
echo "Colima is already running"
echo "Stopping to reconfigure..."
colima stop
fi
echo "Starting Colima with AMD64 emulation support..."
echo "CPU: 1 core | RAM: 1GB | Disk: 40GB"
echo "This may take a few minutes on first run..."
if ! colima start --cpu 1 --memory 1 --disk 40 --arch x86_64; then
echo ""
echo "Error: Failed to start Colima with x86_64 architecture"
echo "This might be because:"
echo " 1. QEMU is not properly installed (run: brew install qemu)"
echo " 2. Lima additional guest agents not installed (run: brew install lima-additional-guestagents)"
echo " 3. Insufficient resources"
echo " 4. Colima instance already exists with different configuration"
echo ""
echo "Trying to delete existing instance and retry..."
colima delete 2>/dev/null || true
echo "Retrying Colima start..."
if ! colima start --cpu 1 --memory 1 --disk 40 --arch x86_64; then
echo ""
echo "Error: Still failed to start Colima"
echo "Please check the error messages above and try:"
echo " colima delete"
echo " brew install qemu lima-additional-guestagents"
echo " ./setup-colima.sh"
exit 1
fi
fi
echo "Waiting for Colima to initialize..."
sleep 5
if ! colima status &> /dev/null; then
echo "Error: Colima started but is not running"
echo "Check status with: colima status"
exit 1
fi
echo ""
echo "Configuring AMD64 emulation support..."
export DOCKER_HOST="unix://$HOME/.colima/default/docker.sock"
colima ssh -- docker run --privileged --rm tonistiigi/binfmt --install all 2>/dev/null || {
echo "Warning: Could not configure emulation now"
echo " Run manually: colima ssh -- docker run --privileged --rm tonistiigi/binfmt --install all"
}
echo "Configuring Docker Buildx..."
colima ssh -- docker buildx version &> /dev/null && {
colima ssh -- docker buildx create --name multiarch --use 2>/dev/null || true
colima ssh -- docker buildx inspect --bootstrap &> /dev/null || true
echo "Buildx configured"
} || echo "Buildx not available (normal)"
echo ""
echo "Testing Docker..."
sleep 3
if docker ps &> /dev/null; then
echo "Docker is working!"
else
echo "Docker not responding yet. Waiting a few seconds..."
sleep 5
if docker ps &> /dev/null; then
echo "Docker is working!"
else
echo "Warning: Docker not responding immediately"
echo "This is normal on first start. Docker should be ready soon."
echo "Check status with: colima status"
echo "Or try: docker ps"
fi
fi
echo ""
echo "Configuring Portainer..."
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^portainer$"; then
echo "Portainer already installed and running!"
LOCAL_IP=$(ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null || echo "your-local-ip")
echo ""
echo "Portainer accessible at:"
echo " - Local: http://localhost:9000"
echo " - Network: http://${LOCAL_IP}:9000"
else
if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "^portainer$"; then
echo "Removing old Portainer container..."
docker rm -f portainer 2>/dev/null || true
fi
if docker volume ls --format '{{.Name}}' 2>/dev/null | grep -q "^portainer_data$"; then
echo "Removing old Portainer volume to avoid timeout issues..."
docker volume rm portainer_data 2>/dev/null || true
sleep 1
fi
echo "Creating volume for Portainer data..."
docker volume create portainer_data
echo "Installing Portainer..."
docker run -d \
-p 0.0.0.0:9000:9000 \
--name=portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v portainer_data:/data \
--privileged \
portainer/portainer-ce:latest
echo "Waiting for Portainer to initialize..."
sleep 5
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^portainer$"; then
echo "Portainer installed and running!"
LOCAL_IP=$(ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null || echo "your-local-ip")
echo ""
echo "Portainer accessible at:"
echo " - Local: http://localhost:9000"
echo " - Network: http://${LOCAL_IP}:9000"
else
echo "Error starting Portainer. Check logs:"
echo " docker logs portainer"
exit 1
fi
fi
echo ""
echo "Configuring aliases..."
SHELL_RC=""
if [ -f "$HOME/.zshrc" ]; then
SHELL_RC="$HOME/.zshrc"
elif [ -f "$HOME/.bash_profile" ]; then
SHELL_RC="$HOME/.bash_profile"
elif [ -f "$HOME/.bashrc" ]; then
SHELL_RC="$HOME/.bashrc"
fi
if [ -n "$SHELL_RC" ]; then
if ! grep -q "docker-start.*colima" "$SHELL_RC" 2>/dev/null; then
echo "Adding aliases to $SHELL_RC..."
cat >> "$SHELL_RC" << 'ALIASES'
# Docker aliases (Colima - manual initialization)
alias docker-start='colima start --cpu 1 --memory 1 --disk 40 --arch x86_64 && sleep 2 && export DOCKER_HOST="unix://$HOME/.colima/default/docker.sock" && echo "Docker started"'
alias docker-stop='colima stop && echo "Docker stopped"'
alias docker-status='colima status'
# Docker host for Colima
export DOCKER_HOST="unix://$HOME/.colima/default/docker.sock"
# Portainer aliases
alias portainer-start='docker start portainer 2>/dev/null || docker run -d -p 0.0.0.0:9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock:ro -v portainer_data:/data --privileged portainer/portainer-ce:latest && echo "Portainer started" && echo " Local: http://localhost:9000" && echo " Network: http://$(ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null || echo "your-local-ip"):9000"'
alias portainer-stop='docker stop portainer && echo "Portainer stopped"'
alias portainer-status='docker ps -f name=portainer --format "{{.Status}}"'
alias portainer-open='open http://localhost:9000'
alias portainer-ip='echo "Local IP: $(ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null || echo "Not found")" && echo "Access: http://$(ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null || echo "your-local-ip"):9000"
ALIASES
echo "Aliases added!"
else
echo "Aliases already configured"
fi
fi
echo ""
echo "Configuration complete!"
echo ""
echo "Available commands:"
echo ""
echo "Docker:"
echo " docker-start - Start Docker (Colima)"
echo " docker-stop - Stop Docker"
echo " docker-status - Check status"
echo ""
echo " docker ps - List containers"
echo " docker compose up - Start services"
echo ""
echo "Portainer:"
echo " portainer-start - Start Portainer"
echo " portainer-stop - Stop Portainer"
echo " portainer-status - Check status"
echo " portainer-open - Open in browser"
echo " portainer-ip - Show local IP"
echo ""
echo "Important:"
echo " - Docker does NOT start automatically"
echo " - Run 'docker-start' when needed"
echo " - Run 'docker-stop' when not needed"
echo ""
echo "Portainer: http://localhost:9000"
echo ""
echo "Configure environment in Portainer:"
echo " 1. Access http://localhost:9000"
echo " 2. Create password (if first time)"
echo " 3. Go to Settings → Environments"
echo " 4. Add environment → Docker"
echo " 5. Socket path: /var/run/docker.sock"
echo " 6. Connect"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment