# 🚀 LemonLink Deployment Guide Deploy your stunning landing page using Docker in Portainer or Proxmox! --- ## 📋 Prerequisites - Docker VM running in Proxmox - Portainer (CE or EE) installed and accessible - (Optional) Reverse proxy (Traefik/Nginx Proxy Manager) for HTTPS --- ## 🎯 Option 1: Portainer Stack (Recommended - Easiest) ### Step 1: Upload Files to Your VM SSH into your Docker VM and create the project directory: ```bash ssh root@your-docker-vm-ip mkdir -p /opt/lemonlink cd /opt/lemonlink ``` Upload these 5 files to `/opt/lemonlink/`: - `index.html` - `styles.css` - `script.js` - `docker-compose.yml` - `nginx.conf` You can use SCP, SFTP, or Portainer's file browser (if available). ### Step 2: Deploy via Portainer 1. Open Portainer in your browser (`http://your-vm-ip:9000`) 2. Click **Stacks** in the left sidebar 3. Click **+ Add Stack** 4. Configure: - **Name**: `lemonlink` - **Build method**: Select "Web editor" - Paste the contents of `docker-compose.yml`: ```yaml version: '3.8' services: lemonlink: image: nginx:alpine container_name: lemonlink-landing restart: unless-stopped volumes: - /opt/lemonlink/index.html:/usr/share/nginx/html/index.html:ro - /opt/lemonlink/styles.css:/usr/share/nginx/html/styles.css:ro - /opt/lemonlink/script.js:/usr/share/nginx/html/script.js:ro - /opt/lemonlink/nginx.conf:/etc/nginx/conf.d/default.conf:ro networks: - lemonlink-network ports: - "8080: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" networks: lemonlink-network: driver: bridge ``` 5. Click **Deploy the stack** 6. Wait for deployment (green indicator) ### Step 3: Access Your Site Visit: `http://your-docker-vm-ip:8080` --- ## 🐳 Option 2: Direct Docker (No Portainer) If you prefer command line: ```bash # SSH to your Docker VM ssh root@your-docker-vm-ip # Create directory mkdir -p /opt/lemonlink cd /opt/lemonlink # Upload files (from your local machine) scp index.html styles.css script.js docker-compose.yml nginx.conf root@your-docker-vm-ip:/opt/lemonlink/ # Run the container docker-compose up -d # Check status docker-compose ps docker-compose logs -f ``` --- ## 🔒 Option 3: With HTTPS (Traefik Reverse Proxy) If you have Traefik running in Portainer: ### Step 1: Create Network In Portainer: 1. Go to **Networks** 2. Click **+ Add Network** 3. Name: `traefik-public` 4. Driver: `bridge` 5. Click **Create the network** ### Step 2: Deploy with Traefik Labels Update the `docker-compose.yml` in Portainer: ```yaml version: '3.8' services: lemonlink: image: nginx:alpine container_name: lemonlink-landing restart: unless-stopped volumes: - /opt/lemonlink/index.html:/usr/share/nginx/html/index.html:ro - /opt/lemonlink/styles.css:/usr/share/nginx/html/styles.css:ro - /opt/lemonlink/script.js:/usr/share/nginx/html/script.js:ro - /opt/lemonlink/nginx.conf:/etc/nginx/conf.d/default.conf:ro networks: - traefik-public # Connect to Traefik network # NO PORTS EXPOSED - Traefik handles routing labels: # Enable Traefik - "traefik.enable=true" # Router configuration - "traefik.http.routers.lemonlink.rule=Host(`lemonlink.eu`)" - "traefik.http.routers.lemonlink.entrypoints=websecure" - "traefik.http.routers.lemonlink.tls.certresolver=letsencrypt" # Service configuration - "traefik.http.services.lemonlink.loadbalancer.server.port=80" # Middleware (optional - for security headers) - "traefik.http.routers.lemonlink.middlewares=security-headers" networks: traefik-public: external: true ``` ### Step 3: Update DNS Point your domain `lemonlink.eu` to your Docker VM's public IP. ### Step 4: Access Visit: `https://lemonlink.eu` 🎉 --- ## 🔄 Option 4: Using Nginx Proxy Manager If you use Nginx Proxy Manager: ### Deploy without exposed ports: ```yaml version: '3.8' services: lemonlink: image: nginx:alpine container_name: lemonlink-landing restart: unless-stopped volumes: - /opt/lemonlink/index.html:/usr/share/nginx/html/index.html:ro - /opt/lemonlink/styles.css:/usr/share/nginx/html/styles.css:ro - /opt/lemonlink/script.js:/usr/share/nginx/html/script.js:ro - /opt/lemonlink/nginx.conf:/etc/nginx/conf.d/default.conf:ro networks: - npm-network # Your NPM network # NO PORTS - NPM will route to it networks: npm-network: external: true ``` ### In Nginx Proxy Manager: 1. Go to **Proxy Hosts** 2. Click **Add Proxy Host** 3. Configure: - **Domain Names**: `lemonlink.eu` - **Scheme**: `http` - **Forward Hostname/IP**: `lemonlink-landing` - **Forward Port**: `80` 4. Enable **Block Common Exploits** 5. Go to **SSL** tab: - Request a new SSL certificate - Enable **Force SSL** - Enable **HTTP/2 Support** 6. Click **Save** --- ## 🖥️ Option 5: Proxmox LXC Container (Alternative) If you prefer an LXC container instead of Docker: ### Step 1: Create LXC Container In Proxmox: 1. Click **Create CT** 2. Template: `debian-12-standard` 3. Resources: 1 CPU, 512MB RAM, 8GB Disk (minimum) 4. Network: DHCP or static IP 5. Start container after creation ### Step 2: Install Nginx ```bash # Enter the container (or SSH into it) pct exec -- bash # Update and install nginx apt update && apt install -y nginx # Remove default site rm /var/www/html/index.nginx-debian.html ``` ### Step 3: Upload Files From your computer: ```bash scp index.html styles.css script.js root@lxc-container-ip:/var/www/html/ ``` ### Step 4: Configure Nginx ```bash # Edit nginx config cat > /etc/nginx/sites-available/default << 'EOF' server { listen 80; listen [::]:80; root /var/www/html; index index.html; server_name lemonlink.eu; location / { try_files $uri $uri/ =404; } # Gzip gzip on; gzip_types text/css application/javascript; } EOF # Test and reload nginx -t systemctl reload nginx ``` --- ## 📁 File Structure on Server After deployment, your server should have: ``` /opt/lemonlink/ ├── index.html # Main website ├── styles.css # Styling ├── script.js # JavaScript ├── docker-compose.yml # Docker configuration ├── nginx.conf # Nginx configuration ├── DEPLOY.md # This guide └── README.md # Website documentation ``` --- ## 🔄 Updating Your Website ### Method 1: Direct File Edit Edit files directly on the server: ```bash ssh root@your-docker-vm-ip nano /opt/lemonlink/index.html # Edit, save, and changes reflect immediately! ``` ### Method 2: Re-upload Files ```bash scp index.html styles.css script.js root@your-docker-vm-ip:/opt/lemonlink/ ``` No restart needed - changes are live instantly! ### Method 3: Using Portainer 1. Go to **Containers** 2. Find `lemonlink-landing` 3. Click **Console** → **/bin/sh** 4. Edit files in `/usr/share/nginx/html/` --- ## 🛠️ Troubleshooting ### Container won't start ```bash # Check logs docker logs lemonlink-landing # Verify files exist ls -la /opt/lemonlink/ # Restart container docker restart lemonlink-landing ``` ### Permission denied ```bash # Fix permissions chmod 644 /opt/lemonlink/*.{html,css,js,conf} ``` ### Can't access the site ```bash # Check if container is running docker ps | grep lemonlink # Check ports docker port lemonlink-landing # Test from VM curl http://localhost:8080 # Check firewall ufw status iptables -L ``` ### SSL/HTTPS issues Make sure: 1. DNS A record points to your server IP 2. Port 443 is open in firewall 3. Traefik/NPM is properly configured --- ## 🌐 Domain & DNS Setup ### For External Access: 1. **Get your public IP**: ```bash curl ifconfig.me ``` 2. **Create A Record** at your DNS provider: - Type: `A` - Name: `@` (or `www`) - Value: `YOUR_PUBLIC_IP` - TTL: `3600` 3. **Port Forward** on your router: - External 80 → Internal `your-vm-ip:8080` - External 443 → Internal `your-vm-ip:443` (if using HTTPS) ### For Internal Only: Add to your local DNS (Pi-hole, AdGuard, or `/etc/hosts`): ``` your-docker-vm-ip lemonlink.eu ``` --- ## 🎉 Success! Your jaw-dropping landing page should now be live! 🍋 - **Without HTTPS**: `http://your-vm-ip:8080` - **With HTTPS**: `https://lemonlink.eu` --- ## 💡 Pro Tips 1. **Auto-updates**: Set up a Git repository for version control 2. **Backups**: Use Proxmox backup for the entire VM 3. **Monitoring**: Add the site to Uptime Kuma or your monitoring stack 4. **Analytics**: Add Plausible or Umami for privacy-focused analytics Need help? Check the logs or ask! 🚀