diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..d7021869b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,46 @@ +FROM dunglas/frankenphp:1-php8.4 + +RUN apt-get update && apt-get install -y \ + cron \ + supervisor \ + libicu-dev \ + libtidy-dev \ + libjpeg-dev \ + libpng-dev \ + libfreetype6-dev \ + libxml2-dev \ + libzip-dev \ + libonig-dev \ + && docker-php-ext-install -j$(nproc) \ + mysqli \ + mbstring \ + gd \ + bcmath \ + intl \ + tidy \ + xml \ + xmlwriter \ + zip \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + +WORKDIR /app + +COPY composer.json composer.lock ./ +RUN composer install --prefer-dist --no-dev --optimize-autoloader --no-scripts + +COPY . /app + +RUN php _cleanup.php && rm _cleanup.php + +RUN echo "*/10 * * * * php /app/cron.php >> /proc/1/fd/1 2>&1" > /etc/cron.d/app-cron \ + && chmod 0644 /etc/cron.d/app-cron \ + && crontab /etc/cron.d/app-cron + +COPY install/docker/Caddyfile /etc/caddy/Caddyfile +COPY install/docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf + +EXPOSE 80 443 + +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] diff --git a/README.md b/README.md index 8d28859d9..2a666542b 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,24 @@ and go from there. The documentation will be translated to English in the near f For the installation, select one of the installation variants below: -### Quick (Clean install) 🚀 +### Quick Start with Docker 🚀 + +1. Select the folder where you want TorrentPier installed + ```shell + cd /path/to/www + ``` +2. Download the latest version of TorrentPier + ```shell + git clone --branch v2.4 --depth 1 https://github.com/torrentpier/torrentpier.git . + ``` +3. Setup Docker + ```shell + chmod +x setup-docker.sh + ./setup-docker.sh + ``` +4. Voila! ✨ + +### Quick (Installation script) 🚀 Check out our [autoinstall](https://github.com/torrentpier/autoinstall) repository with detailed instructions. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..e6abf4028 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,38 @@ +services: + torrentpier-app: + build: + context: . + dockerfile: Dockerfile + container_name: torrentpier-app + ports: + - "${TP_PORT:-80}:${TP_PORT:-80}" + env_file: + - .env + volumes: + - ./internal_data:/app/internal_data + - ./data:/app/data + - ./sitemap:/app/sitemap + - caddy_data:/data + - caddy_config:/config + depends_on: + - torrentpier-db + + torrentpier-db: + image: mariadb:10.11 + container_name: torrentpier-db + restart: always + env_file: + - .env + environment: + MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} + MYSQL_DATABASE: ${DB_DATABASE} + MYSQL_USER: ${DB_USERNAME} + MYSQL_PASSWORD: ${DB_PASSWORD} + volumes: + - db_data:/var/lib/mysql + - ./install/sql/mysql.sql:/docker-entrypoint-initdb.d/mysql.sql:ro + +volumes: + db_data: + caddy_data: + caddy_config: diff --git a/install/docker/Caddyfile b/install/docker/Caddyfile new file mode 100644 index 000000000..37088543c --- /dev/null +++ b/install/docker/Caddyfile @@ -0,0 +1,24 @@ +# Caddy configuration for TorrentPier (Docker) + +{$TP_HOST}:{$TP_PORT:80} { + root * /app + encode gzip zstd + php_server + try_files {path} {path}/ /index.php?{query} + file_server + + @blocked { + path /install/* /internal_data/* /library/* + path /.ht* /.en* /.git* /.docker* + path *.sql *.tpl *.db *.inc *.log *.md + path /docker-compose.yml /Dockerfile /.env* + } + respond @blocked 404 + + redir /sitemap.xml /sitemap/sitemap.xml 301 + + @html_css_js { + path *.html *.css *.js *.json *.xml *.txt + } + header @html_css_js Content-Type "{mime}; charset=utf-8" +} diff --git a/install/docker/supervisord.conf b/install/docker/supervisord.conf new file mode 100644 index 000000000..76e02f365 --- /dev/null +++ b/install/docker/supervisord.conf @@ -0,0 +1,24 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:cron] +command=cron -f +autostart=true +autorestart=true +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 + +[program:frankenphp] +command=frankenphp run --config /etc/caddy/Caddyfile +directory=/app +autostart=true +autorestart=true +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 diff --git a/setup-docker.sh b/setup-docker.sh new file mode 100644 index 000000000..10a8add0b --- /dev/null +++ b/setup-docker.sh @@ -0,0 +1,130 @@ +#!/bin/bash +set -e + +echo "đŸŗ Setting up TorrentPier for Docker..." +echo "" + +if [ ! -f .env ]; then + if [ -f .env.example ]; then + cp .env.example .env + echo "✅ Created .env from .env.example" + else + echo "❌ Error: .env.example not found!" + exit 1 + fi +else + echo "â„šī¸ .env file already exists, updating for Docker..." +fi + +cp .env .env.backup +echo "💾 Backup created: .env.backup" + +# Enable server-side cron +if grep -q "^APP_CRON_ENABLED=true" .env; then + sed -i 's/^APP_CRON_ENABLED=true/APP_CRON_ENABLED=false/' .env +fi + +if grep -q "^DB_HOST=localhost" .env; then + sed -i 's/^DB_HOST=localhost/DB_HOST=torrentpier-db/' .env + echo "✅ Updated DB_HOST for Docker" +fi + +if grep -q "^DB_USERNAME=root" .env; then + sed -i 's/^DB_USERNAME=root/DB_USERNAME=torrentpier_user/' .env + echo "✅ Updated DB_USERNAME to torrentpier_user" +fi + +echo "" +read -s -p "🔐 Enter database password for 'torrentpier_user': " DB_PASSWORD +echo "" + +if [ -z "$DB_PASSWORD" ]; then + echo "❌ Error: Database password cannot be empty!" + exit 1 +fi + +# More robust password escaping for sed +ESCAPED_PASSWORD=$(printf '%s\n' "$DB_PASSWORD" | sed 's/[[\.*^$()+?{|]/\\&/g') + +if grep -q "^DB_PASSWORD=" .env; then + sed -i "s/^DB_PASSWORD=.*/DB_PASSWORD=$ESCAPED_PASSWORD/" .env + echo "✅ Updated DB_PASSWORD in .env" +else + echo "DB_PASSWORD=$DB_PASSWORD" >> .env + echo "✅ Added DB_PASSWORD to .env" +fi + +echo "" +read -p "🌐 Enter your host (IP or domain, e.g. 192.168.1.100 or example.com): " TP_HOST +echo "" + +if [ -z "$TP_HOST" ]; then + echo "❌ Error: Host cannot be empty!" + exit 1 +fi + +# Basic validation for host format +if [[ ! "$TP_HOST" =~ ^[a-zA-Z0-9.-]+$ ]]; then + echo "❌ Error: Invalid host format! Use only letters, numbers, dots, and hyphens." + exit 1 +fi + +TP_HOST=$(echo "$TP_HOST" | sed -E 's|^https?://||') +TP_HOST=$(echo "$TP_HOST" | sed 's|/||g') +ESCAPED_HOST=$(printf '%s\n' "$TP_HOST" | sed 's/[[\.*^$()+?{|]/\\&/g') + +if grep -q "^TP_HOST=" .env; then + sed -i "s/^TP_HOST=.*/TP_HOST=$ESCAPED_HOST/" .env + echo "✅ Updated TP_HOST to $TP_HOST" +else + echo "TP_HOST=$TP_HOST" >> .env + echo "✅ Added TP_HOST to .env" +fi + +echo "" +echo "âš ī¸ SSL Notes:" +echo " - SSL requires a real domain (not localhost/IP)" +echo " - Caddy will automatically get Let's Encrypt certificates" +echo " - Port 80 and 443 must be accessible from the internet" +echo "" + +read -p "🔐 Do you want to enable SSL (HTTPS)? [y/N]: " ENABLE_SSL +ENABLE_SSL=$(echo "$ENABLE_SSL" | tr '[:upper:]' '[:lower:]') + +if [ "$ENABLE_SSL" = "y" ] || [ "$ENABLE_SSL" = "yes" ]; then + SSL_ENABLED="on" + if grep -q "^TP_PORT=" .env; then + sed -i "s/^TP_PORT=.*/TP_PORT=443/" .env + else + echo "TP_PORT=443" >> .env + fi +else + SSL_ENABLED="off" + if grep -q "^TP_PORT=" .env; then + sed -i "s/^TP_PORT=.*/TP_PORT=80/" .env + else + echo "TP_PORT=80" >> .env + fi +fi + +if grep -q "^SSL_ENABLED=" .env; then + sed -i "s/^SSL_ENABLED=.*/SSL_ENABLED=$SSL_ENABLED/" .env + echo "✅ Updated SSL_ENABLED to $SSL_ENABLED" +else + echo "" >> .env + echo "# Docker-specific configuration" >> .env + echo "SSL_ENABLED=$SSL_ENABLED" >> .env + echo "✅ Added Docker SSL configuration (SSL_ENABLED=$SSL_ENABLED)" +fi + +echo "" +echo "🎉 Docker setup complete!" +echo "" +echo "📋 Next steps:" +echo " 1. Run: docker-compose up" +if [ "$SSL_ENABLED" = "on" ]; then + echo " 2. Open: https://$TP_HOST" +else + echo " 2. Open: http://$TP_HOST" +fi +echo ""