266 lines
8.4 KiB
Bash
266 lines
8.4 KiB
Bash
#!/bin/bash
|
|
|
|
# 🍋 LemonLink Deployment Script
|
|
# Automated deployment for Docker/Portainer environments
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
INSTALL_DIR="/opt/lemonlink"
|
|
CONTAINER_NAME="lemonlink-landing"
|
|
PORT="8080"
|
|
|
|
# Functions
|
|
print_banner() {
|
|
echo -e "${YELLOW}"
|
|
echo " ██╗ ███████╗███╗ ███╗ ██████╗ ███╗ ██╗██╗ ██╗███╗ ██╗██╗ ██╗"
|
|
echo " ██║ ██╔════╝████╗ ████║██╔═══██╗████╗ ██║██║ ██║████╗ ██║██║ ██╔╝"
|
|
echo " ██║ █████╗ ██╔████╔██║██║ ██║██╔██╗ ██║██║ ██║██╔██╗ ██║█████╔╝ "
|
|
echo " ██║ ██╔══╝ ██║╚██╔╝██║██║ ██║██║╚██╗██║██║ ██║██║╚██╗██║██╔═██╗ "
|
|
echo " ███████╗███████╗██║ ╚═╝ ██║╚██████╔╝██║ ╚████║███████╗██║██║ ╚████║██║ ██╗"
|
|
echo " ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝"
|
|
echo -e "${NC}"
|
|
echo -e "${BLUE}Deployment Script v1.0${NC}"
|
|
echo ""
|
|
}
|
|
|
|
print_status() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
print_success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
print_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
print_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
check_docker() {
|
|
print_status "Checking Docker installation..."
|
|
if ! command -v docker &> /dev/null; then
|
|
print_error "Docker is not installed!"
|
|
echo "Install Docker first: https://docs.docker.com/get-docker/"
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v docker-compose &> /dev/null; then
|
|
print_error "Docker Compose is not installed!"
|
|
exit 1
|
|
fi
|
|
|
|
print_success "Docker is installed"
|
|
}
|
|
|
|
create_directory() {
|
|
print_status "Creating installation directory..."
|
|
if [ -d "$INSTALL_DIR" ]; then
|
|
print_warning "Directory $INSTALL_DIR already exists"
|
|
read -p "Overwrite existing files? (y/N): " confirm
|
|
if [[ $confirm != [yY] && $confirm != [yY][eE][sS] ]]; then
|
|
print_status "Using existing directory"
|
|
return
|
|
fi
|
|
else
|
|
sudo mkdir -p "$INSTALL_DIR"
|
|
fi
|
|
|
|
sudo chown "$USER:$USER" "$INSTALL_DIR"
|
|
print_success "Directory created: $INSTALL_DIR"
|
|
}
|
|
|
|
copy_files() {
|
|
print_status "Copying website files..."
|
|
|
|
# Check if files exist in current directory
|
|
if [ ! -f "index.html" ] || [ ! -f "styles.css" ] || [ ! -f "script.js" ]; then
|
|
print_error "Website files not found in current directory!"
|
|
echo "Make sure you're running this script from the lemonlink directory."
|
|
exit 1
|
|
fi
|
|
|
|
cp index.html styles.css script.js nginx.conf "$INSTALL_DIR/"
|
|
print_success "Files copied to $INSTALL_DIR"
|
|
}
|
|
|
|
create_compose_file() {
|
|
print_status "Creating docker-compose.yml..."
|
|
|
|
cat > "$INSTALL_DIR/docker-compose.yml" << EOF
|
|
version: '3.8'
|
|
|
|
services:
|
|
lemonlink:
|
|
image: nginx:alpine
|
|
container_name: $CONTAINER_NAME
|
|
restart: unless-stopped
|
|
volumes:
|
|
- $INSTALL_DIR/index.html:/usr/share/nginx/html/index.html:ro
|
|
- $INSTALL_DIR/styles.css:/usr/share/nginx/html/styles.css:ro
|
|
- $INSTALL_DIR/script.js:/usr/share/nginx/html/script.js:ro
|
|
- $INSTALL_DIR/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
|
networks:
|
|
- lemonlink-network
|
|
ports:
|
|
- "$PORT:80"
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 10s
|
|
labels:
|
|
- "com.lemonlink.description=LemonLink Landing Page"
|
|
- "com.lemonlink.version=1.0"
|
|
|
|
networks:
|
|
lemonlink-network:
|
|
driver: bridge
|
|
name: lemonlink-network
|
|
EOF
|
|
|
|
print_success "Docker Compose file created"
|
|
}
|
|
|
|
deploy_container() {
|
|
print_status "Deploying LemonLink container..."
|
|
|
|
cd "$INSTALL_DIR"
|
|
|
|
# Stop existing container if running
|
|
if docker ps -q -f name="$CONTAINER_NAME" | grep -q .; then
|
|
print_warning "Stopping existing container..."
|
|
docker-compose down
|
|
fi
|
|
|
|
# Start new container
|
|
docker-compose up -d
|
|
|
|
# Wait for container to be healthy
|
|
print_status "Waiting for container to be ready..."
|
|
sleep 3
|
|
|
|
if docker ps | grep -q "$CONTAINER_NAME"; then
|
|
print_success "Container is running!"
|
|
else
|
|
print_error "Container failed to start"
|
|
docker-compose logs
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
show_info() {
|
|
echo ""
|
|
echo -e "${GREEN}╔════════════════════════════════════════════════════════╗${NC}"
|
|
echo -e "${GREEN}║ 🍋 LemonLink Deployed Successfully! 🍋 ║${NC}"
|
|
echo -e "${GREEN}╚════════════════════════════════════════════════════════╝${NC}"
|
|
echo ""
|
|
|
|
# Get IP addresses
|
|
IP_ADDRESSES=$(hostname -I 2>/dev/null | tr ' ' '\n' | grep -v '^$' | head -3)
|
|
|
|
echo -e "${YELLOW}Access your website at:${NC}"
|
|
echo ""
|
|
|
|
while IFS= read -r ip; do
|
|
echo -e " ${BLUE}➜${NC} http://$ip:$PORT"
|
|
done <<< "$IP_ADDRESSES"
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}Files location:${NC} $INSTALL_DIR"
|
|
echo -e "${YELLOW}Container name:${NC} $CONTAINER_NAME"
|
|
echo ""
|
|
echo -e "${BLUE}Useful commands:${NC}"
|
|
echo " View logs: docker logs -f $CONTAINER_NAME"
|
|
echo " Stop: cd $INSTALL_DIR && docker-compose down"
|
|
echo " Restart: cd $INSTALL_DIR && docker-compose restart"
|
|
echo " Update files: Edit files in $INSTALL_DIR (changes are instant)"
|
|
echo ""
|
|
echo -e "${YELLOW}To use with a reverse proxy (Traefik/NPM):${NC}"
|
|
echo " 1. Remove the 'ports' section from docker-compose.yml"
|
|
echo " 2. Connect to your reverse proxy network"
|
|
echo " 3. Add appropriate labels"
|
|
echo ""
|
|
}
|
|
|
|
update_files() {
|
|
print_status "Updating website files..."
|
|
|
|
if [ ! -d "$INSTALL_DIR" ]; then
|
|
print_error "Installation directory not found!"
|
|
echo "Run: $0 --install"
|
|
exit 1
|
|
fi
|
|
|
|
cp index.html styles.css script.js nginx.conf "$INSTALL_DIR/"
|
|
print_success "Files updated!"
|
|
|
|
# Reload nginx inside container
|
|
docker exec "$CONTAINER_NAME" nginx -s reload 2>/dev/null || true
|
|
|
|
print_success "Changes are now live!"
|
|
}
|
|
|
|
uninstall() {
|
|
print_warning "This will remove the LemonLink container and files!"
|
|
read -p "Are you sure? (y/N): " confirm
|
|
|
|
if [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]]; then
|
|
print_status "Stopping and removing container..."
|
|
cd "$INSTALL_DIR" && docker-compose down 2>/dev/null || true
|
|
|
|
print_status "Removing files..."
|
|
sudo rm -rf "$INSTALL_DIR"
|
|
|
|
print_success "LemonLink has been removed!"
|
|
else
|
|
print_status "Uninstall cancelled"
|
|
fi
|
|
}
|
|
|
|
# Main script
|
|
print_banner
|
|
|
|
case "${1:-}" in
|
|
--update|-u)
|
|
check_docker
|
|
update_files
|
|
;;
|
|
--uninstall|-r)
|
|
uninstall
|
|
;;
|
|
--help|-h)
|
|
echo "Usage: $0 [OPTION]"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " (no option) Full installation"
|
|
echo " --update, -u Update website files only"
|
|
echo " --uninstall, -r Remove LemonLink completely"
|
|
echo " --help, -h Show this help message"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " $0 # Fresh install"
|
|
echo " $0 --update # Update after editing files"
|
|
echo " $0 --uninstall # Remove everything"
|
|
;;
|
|
*)
|
|
check_docker
|
|
create_directory
|
|
copy_files
|
|
create_compose_file
|
|
deploy_container
|
|
show_info
|
|
;;
|
|
esac
|