diff --git a/.env b/.env new file mode 100644 index 0000000..a3d3649 --- /dev/null +++ b/.env @@ -0,0 +1,19 @@ +# Project +PROJECT_NAME=ktvcentral +APP_DOMAIN=https://ktvcentral.test +LETSENCRYPT_EMAIL=you@example.com + +# Git +GIT_REPO_URL=http://47.251.18.130:3000/Leecheng/KTVCentral.git + +# Database +DB_DATABASE=Karaoke-Kingpin +DB_USERNAME=Karaoke-Kingpin +DB_PASSWORD=ESM7yTPMnavFmbBH + +# Redis +REDIS_HOST=redis +REDIS_PORT=6379 +QUEUE_CONNECTION=redis +CACHE_DRIVER=redis +SESSION_DRIVER=redis \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..a3d3649 --- /dev/null +++ b/.env.example @@ -0,0 +1,19 @@ +# Project +PROJECT_NAME=ktvcentral +APP_DOMAIN=https://ktvcentral.test +LETSENCRYPT_EMAIL=you@example.com + +# Git +GIT_REPO_URL=http://47.251.18.130:3000/Leecheng/KTVCentral.git + +# Database +DB_DATABASE=Karaoke-Kingpin +DB_USERNAME=Karaoke-Kingpin +DB_PASSWORD=ESM7yTPMnavFmbBH + +# Redis +REDIS_HOST=redis +REDIS_PORT=6379 +QUEUE_CONNECTION=redis +CACHE_DRIVER=redis +SESSION_DRIVER=redis \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..12b8a46 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM php:8.3-fpm + +RUN apt-get update && apt-get install -y \ + git unzip zip curl libpng-dev libjpeg62-turbo-dev libfreetype6-dev \ + libonig-dev libxml2-dev libzip-dev libpq-dev libicu-dev libxslt-dev \ + libsqlite3-dev sqlite3 cron supervisor && \ + curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \ + apt-get install -y nodejs && \ + npm install -g npm && \ + docker-php-ext-configure gd --with-freetype --with-jpeg && \ + docker-php-ext-install gd pdo_mysql zip bcmath intl xsl pcntl sockets + + +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + +WORKDIR /var/www + +COPY ./docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY ./docker/entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +CMD ["/usr/local/bin/entrypoint.sh"] \ No newline at end of file diff --git a/docker-compose.letsencrypt.yaml b/docker-compose.letsencrypt.yaml new file mode 100644 index 0000000..7d08621 --- /dev/null +++ b/docker-compose.letsencrypt.yaml @@ -0,0 +1,20 @@ +services: + letsencrypt: + image: jrcs/letsencrypt-nginx-proxy-companion + container_name: ${PROJECT_NAME}_letsencrypt + environment: + NGINX_PROXY_CONTAINER: ${PROJECT_NAME}_nginx_proxy + DEFAULT_EMAIL: ${LETSENCRYPT_EMAIL} + volumes_from: + - nginx-proxy + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - ./certs:/etc/nginx/certs:rw + - ./vhost.d:/etc/nginx/vhost.d + - ./html:/usr/share/nginx/html + networks: + - nginx_proxy + +networks: + nginx_proxy: + external: true \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..23c4e8e --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,77 @@ +services: + app: + build: + context: . + dockerfile: Dockerfile + container_name: ${PROJECT_NAME}_app + volumes: + - ./data:/var/www + depends_on: + - mariadb + environment: + VIRTUAL_HOST: ${APP_DOMAIN} + LETSENCRYPT_HOST: ${APP_DOMAIN} + LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL} + networks: + - nginx_proxy + expose: + - "80" + + mariadb: + image: mariadb:10.6 + container_name: ${PROJECT_NAME}_db + restart: always + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: ${DB_DATABASE} + MYSQL_USER: ${DB_USERNAME} + MYSQL_PASSWORD: ${DB_PASSWORD} + volumes: + - dbdata:/var/lib/mysql + ports: + - "3306:3306" + networks: + - nginx_proxy + + redis: + image: redis:alpine + container_name: ${PROJECT_NAME}_redis + ports: + - "6379:6379" + restart: unless-stopped + volumes: + - redisdata:/data + networks: + - nginx_proxy + + redisinsight: + image: redislabs/redisinsight:latest + container_name: ${PROJECT_NAME}_redisinsight + ports: + - "8001:8001" + networks: + - nginx_proxy + depends_on: + - redis + + nginx-proxy: + image: jwilder/nginx-proxy + container_name: ${PROJECT_NAME}_nginx_proxy + ports: + - "80:80" + - "443:443" + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./certs:/etc/nginx/certs + - ./vhost.d:/etc/nginx/vhost.d + - ./html:/usr/share/nginx/html + networks: + - nginx_proxy + +volumes: + dbdata: + redisdata: + +networks: + nginx_proxy: + name: nginx_proxy \ No newline at end of file diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100644 index 0000000..c9dfc6e --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +cd /var/www + +# Remove trailing slash from APP_DOMAIN if exists +APP_DOMAIN="${APP_DOMAIN%/}" + +# 預設 Redis 設定 +: "${REDIS_HOST:=redis}" +: "${REDIS_PORT:=6379}" + +# Clone 專案(只有第一次) +if [ ! -d "html" ]; then + echo "🔧 Cloning project from ${GIT_REPO_URL}..." + git clone "$GIT_REPO_URL" html +fi + +cd html + +# Composer install +echo "📦 Running composer install..." +composer install --no-interaction --prefer-dist + +# 複製 .env +if [ ! -f ".env" ]; then + echo "⚙️ Copying .env.example to .env" + cp .env.example .env +fi + +# 更新 .env 設定 +echo "🛠 Updating .env configurations..." + +update_env_var() { + local key=$1 + local value=$2 + grep -q "^${key}=" .env && \ + sed -i "s|^${key}=.*|${key}=${value}|" .env || \ + echo "${key}=${value}" >> .env +} + +update_env_var "APP_URL" "$APP_DOMAIN" +update_env_var "L5_SWAGGER_CONST_HOST" "$APP_DOMAIN" +update_env_var "DB_DATABASE" "$DB_DATABASE" +update_env_var "DB_USERNAME" "$DB_USERNAME" +update_env_var "DB_PASSWORD" "$DB_PASSWORD" +update_env_var "REDIS_HOST" "$REDIS_HOST" +update_env_var "REDIS_PORT" "$REDIS_PORT" +update_env_var "QUEUE_CONNECTION" "$QUEUE_CONNECTION" +update_env_var "CACHE_DRIVER" "$CACHE_DRIVER" +update_env_var "SESSION_DRIVER" "$SESSION_DRIVER" + +# Laravel 初始化 +echo "🔑 Generating Laravel app key..." +php artisan key:generate + +echo "🧱 Running migrations..." +php artisan config:clear && cache:clear +php artisan migrate --force + +# 安裝 Node 套件與建構前端 +echo "🌐 Installing npm packages..." +[ ! -d "node_modules" ] && npm install + +echo "🛠 Building front-end assets..." +npm run build + +# 加入 Laravel Schedule 到 crontab(避免重複) +echo "⏱ Adding schedule:run to crontab..." +crontab -l 2>/dev/null | grep -q 'schedule:run' || \ + (echo "* * * * * cd /var/www/html && php artisan schedule:run >> /dev/null 2>&1" | crontab -) + +# 啟動 supervisord(同時啟動 queue + cron + php-fpm) +echo "🚀 Starting supervisord..." +exec supervisord -n \ No newline at end of file diff --git a/docker/supervisord.conf b/docker/supervisord.conf new file mode 100644 index 0000000..b4088f9 --- /dev/null +++ b/docker/supervisord.conf @@ -0,0 +1,23 @@ +[supervisord] +nodaemon=true + +[program:php-fpm] +command=docker-php-entrypoint php-fpm +autostart=true +autorestart=true +priority=1 + +[program:queue-worker] +directory=/var/www/html +command=php artisan queue:work redis --daemon --timeout=3600 --tries=1 --queue=default +autostart=true +autorestart=true +priority=2 +stdout_logfile=/var/www/html/storage/logs/queue.log +stderr_logfile=/var/www/html/storage/logs/queue_error.log + +[program:schedule-run] +command=cron -f +autostart=true +autorestart=true +priority=3 \ No newline at end of file