diff --git a/.gitignore b/.gitignore index 0119322..fb1031f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ .idea # intended for per-machine config -vagrant.config.yml \ No newline at end of file +vagrant.config.yml +docker/certificates/* +!docker/certificates/.gitkeep diff --git a/Vagrantfile b/Vagrantfile index 844774c..6676c85 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -99,35 +99,6 @@ Vagrant.configure("2") do |config| config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig" end - config.vm.define "docs" do |docs| - docs.vm.hostname = "docs.pterodactyl.test" - docs.vm.synced_folder ".", "/vagrant", disabled: true - - docs.vm.network "forwarded_port", guest: 80, host: 9090 - docs.vm.network "forwarded_port", guest: 9091, host: 9091 - - docs.ssh.insert_key = true - docs.ssh.username = "vagrant" - docs.ssh.password = "vagrant" - - docs.vm.provider "docker" do |d| - d.image = "ghcr.io/pterodactyl/development/base" - d.create_args = ["-it", "--add-host=host.pterodactyl.test:172.17.0.1"] - d.ports = ["9090:80", "9091:9091"] - d.name = "pterodev_docs" - - d.volumes = ["#{vagrant_root}/code/documentation:/home/vagrant/docs:cached"] - - d.remains_running = true - d.has_ssh = true - d.privileged = true - end - - docs.vm.provision "deploy_files", type: "file", source: "#{vagrant_root}/build/configs", destination: "/tmp/.deploy" - docs.vm.provision "setup_documentation", type: "shell", privileged: false, path: "#{vagrant_root}/scripts/deploy_docs.sh" - end - - # Configure a mysql docker container. config.vm.define "mysql" do |mysql| mysql.vm.hostname = "mysql.pterodactyl.test" @@ -156,37 +127,6 @@ Vagrant.configure("2") do |config| end end - config.vm.define "chromedriver" do |chrome| - chrome.vm.hostname = "chromedriver.pterodactyl.test" - chrome.vm.synced_folder ".", "/vagrant", disabled: true - - chrome.vm.network "forwarded_port", guest: 4444, host: 4444 - chrome.vm.network "forwarded_port", guest: 5900, host: 5900 - - chrome.vm.provider "docker" do |d| - d.image = "selenium/standalone-chrome-debug:3.12.0-boron" - d.ports = ["5900:5900", "4444:4444"] - d.create_args = ["--add-host=pterodactyl.test:172.17.0.1"] - d.remains_running = true - end - end - - # Create a docker container for mailhog which providers a local SMTP environment that avoids actually - # sending emails to the address. - config.vm.define "mailhog" do |mh| - mh.vm.hostname = "mailhog.pterodactyl.test" - mh.vm.synced_folder ".", "/vagrant", disabled: true - - mh.vm.network "forwarded_port", guest: 1025, host: 1025 - mh.vm.network "forwarded_port", guest: 8025, host: 8025 - - mh.vm.provider "docker" do |d| - d.image = "mailhog/mailhog" - d.ports = ["1025:1025", "8025:8025"] - d.remains_running = true - end - end - # Create a docker container for the redis server. config.vm.define "redis" do |redis| redis.vm.hostname = "redis.pterodactyl.test" diff --git a/build/Dockerfile-base b/build/Dockerfile-base deleted file mode 100644 index 10317d8..0000000 --- a/build/Dockerfile-base +++ /dev/null @@ -1,27 +0,0 @@ -FROM ubuntu:20.04 - -LABEL maintainer="dane@daneeveritt.com" \ - description="Base image used by Pterodactyl's development environments to provide SSH support for vagrant." \ - org.opencontainers.image.source=https://github.com/pterodactyl/development - -ENV DEBIAN_FRONTEND=noninteractive \ - NOTVISIBLE="in users profile" \ - LANG=en_US.UTF-8 \ - LANGUAGE=en_US:en \ - LC_ALL=en_US.UTF-8 - -RUN apt -y update \ - && apt -y upgrade \ - && apt -y --no-install-recommends install software-properties-common gpg-agent sudo openssh-server locales curl iproute2 iputils-ping lsb-release git \ - && sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ - && locale-gen \ - && useradd -m -s /bin/bash -p $(echo "vagrant" | openssl passwd -1 -stdin) vagrant \ - && echo 'ALL ALL = (ALL) NOPASSWD: ALL' > /etc/sudoers \ - && sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd \ - && echo "export VISIBLE=now" >> /etc/profile \ - && rm -rf /var/lib/apt/lists/* - -EXPOSE 22 -USER vagrant - -ENTRYPOINT sudo su -c "service ssh start && /bin/bash" diff --git a/build/Dockerfile-panel b/build/Dockerfile-panel deleted file mode 100644 index 199fe29..0000000 --- a/build/Dockerfile-panel +++ /dev/null @@ -1,42 +0,0 @@ -FROM ghcr.io/pterodactyl/development/base - -LABEL maintainer="dane@daneeveritt.com" \ - description="Docker image allowing Pterodactyl Panel to run using Vagrant." \ - org.opencontainers.image.source=https://github.com/pterodactyl/development - -RUN curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - \ - && curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - \ - && echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list \ - && sudo add-apt-repository -y ppa:ondrej/php \ - && sudo apt -y update \ - && sudo apt -y upgrade \ - && sudo apt -y --no-install-recommends install software-properties-common \ - php8.0 \ - php8.0-cli \ - php8.0-common \ - php8.0-gd \ - php8.0-mysql \ - php8.0-mbstring \ - php8.0-bcmath \ - php8.0-xml \ - php8.0-fpm \ - php8.0-curl \ - php8.0-zip \ - php8.0-xdebug \ - nginx \ - tar \ - unzip \ - git \ - supervisor \ - cron \ - nodejs \ - yarn \ - nano \ - && curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer \ - && sudo apt autoremove -y \ - && sudo rm -rf /var/lib/apt/lists/* - -EXPOSE 80 -USER vagrant - -ENTRYPOINT sudo su -c "/usr/bin/supervisord && service ssh start && service cron start && /bin/bash" diff --git a/build/configs/nginx/pterodocs.test.conf b/build/configs/nginx/pterodocs.test.conf deleted file mode 100644 index 4b129d1..0000000 --- a/build/configs/nginx/pterodocs.test.conf +++ /dev/null @@ -1,23 +0,0 @@ -server { - listen 80; - - index index.html; - server_name docs.pterodactyl.test; - root /srv/documentation/.vuepress/dist; - - location / { - proxy_pass http://127.0.0.1:8080; - } - - # security headers - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-XSS-Protection "1; mode=block" always; - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "same-origin" always; - add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always; - - # . files - location ~ /\. { - deny all; - } -} \ No newline at end of file diff --git a/build/configs/supervisor/pterodocs.conf b/build/configs/supervisor/pterodocs.conf deleted file mode 100644 index 5e750de..0000000 --- a/build/configs/supervisor/pterodocs.conf +++ /dev/null @@ -1,7 +0,0 @@ -[program:nginx] -command=/usr/sbin/nginx -g 'daemon off;' -autostart=true -autorestart=true -priority=10 -stdout_events_enabled=true -stderr_events_enabled=true \ No newline at end of file diff --git a/build/panel/Dockerfile b/build/panel/Dockerfile new file mode 100644 index 0000000..9208ff2 --- /dev/null +++ b/build/panel/Dockerfile @@ -0,0 +1,72 @@ +FROM debian:11-slim + +LABEL maintainer="dane@daneeveritt.com" \ + description="Docker image allowing Pterodactyl Panel to run using Vagrant." \ + org.opencontainers.image.source=https://github.com/pterodactyl/development + +ENV DEBIAN_FRONTEND noninteractive \ + LANG C.UTF-8 + +USER root +RUN apt -y update \ + && apt -y --no-install-recommends install lsb-release ca-certificates apt-transport-https software-properties-common gnupg2 curl sudo \ + && curl -sL https://deb.nodesource.com/setup_14.x | bash - \ + && curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ + && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \ + && echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/sury-php.list \ + && curl -sL https://packages.sury.org/php/apt.gpg | apt-key add - \ + && apt -y update \ + && apt -y upgrade \ + && apt -y --no-install-recommends install \ + locales \ + iproute2 \ + iputils-ping \ + lsb-release \ + nginx \ + tar \ + unzip \ + git \ + supervisor \ + cron \ + nodejs \ + yarn \ + nano \ + && apt -y --no-install-recommends install php8.0 \ + php8.0-cli \ + php8.0-common \ + php8.0-gd \ + php8.0-mysql \ + php8.0-mbstring \ + php8.0-bcmath \ + php8.0-xml \ + php8.0-fpm \ + php8.0-curl \ + php8.0-zip \ + php8.0-xdebug \ + && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \ + && apt autoremove -y \ + && rm -rf /var/lib/apt/lists/* + +COPY entrypoint /usr/local/bin/entrypoint +COPY setup /usr/local/bin/setup +COPY configs/supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY configs/pterodactyl.conf /etc/nginx/sites-available/pterodactyl.conf + +RUN useradd -m pterodactyl \ + && usermod -a -g www-data -G sudo pterodactyl \ + && echo "pterodactyl ALL=(ALL) NOPASSWD:ALL" | tee /etc/sudoers.d/pterodactyl \ + && chmod +x /usr/local/bin/setup \ + && chmod +x /usr/local/bin/entrypoint \ + && rm -rf /etc/nginx/sites-enabled/* \ + && ln -s /etc/nginx/sites-available/pterodactyl.conf /etc/nginx/sites-enabled/ \ + && phpdismod -s cli xdebug \ + && mkdir -p /var/run/php \ + && mkdir -p /var/www/html \ + && (crontab -l 2>/dev/null; echo "* * * * * php /var/www/html/artisan schedule:run >> /dev/null 2>&1") | crontab - + +WORKDIR /var/www/html + +EXPOSE 80 +USER pterodactyl + +ENTRYPOINT ["entrypoint"] diff --git a/build/configs/nginx/pterodactyl.test.conf b/build/panel/configs/pterodactyl.conf similarity index 51% rename from build/configs/nginx/pterodactyl.test.conf rename to build/panel/configs/pterodactyl.conf index 5731c45..0f198fc 100644 --- a/build/configs/nginx/pterodactyl.test.conf +++ b/build/panel/configs/pterodactyl.conf @@ -1,14 +1,8 @@ server { listen 80; server_name pterodactyl.test; - return 301 https://$server_name$request_uri; -} -server { - listen 443 ssl http2; - server_name pterodactyl.test; - - root /srv/www/public; + root /var/www/html/public; index index.html index.htm index.php; charset utf-8; @@ -20,21 +14,13 @@ server { location = /robots.txt { access_log off; log_not_found off; } access_log off; - error_log /var/log/nginx/pterodactyl.test-error.log error; + error_log /var/log/nginx/error.log error; client_max_body_size 100m; client_body_timeout 120s; sendfile off; - # SSL Configuration - ssl_certificate /etc/ssl/private/pterodactyl.test.pem; - ssl_certificate_key /etc/ssl/private/pterodactyl.test-key.pem; - ssl_session_cache shared:SSL:10m; - ssl_protocols TLSv1.2; - ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; - ssl_prefer_server_ciphers on; - add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header X-Robots-Tag none; @@ -62,26 +48,3 @@ server { deny all; } } - -server { - listen 80; - - index index.html; - server_name docs.pterodactyl.test; - - location / { - proxy_pass http://host.pterodactyl.test:9090; - } - - # security headers - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-XSS-Protection "1; mode=block" always; - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "same-origin" always; - add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always; - - # . files - location ~ /\. { - deny all; - } -} diff --git a/build/configs/supervisor/pterodactyl.conf b/build/panel/configs/supervisord.conf similarity index 62% rename from build/configs/supervisor/pterodactyl.conf rename to build/panel/configs/supervisord.conf index 90c3837..5cdfdc9 100644 --- a/build/configs/supervisor/pterodactyl.conf +++ b/build/panel/configs/supervisord.conf @@ -1,12 +1,19 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + [program:pteroq] process_name=%(program_name)s_%(process_num)02d -command=/usr/bin/php /srv/www/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3 +command=/usr/bin/php /var/www/html/artisan queue:work --sleep=3 --tries=3 autostart=true autorestart=true +startretries=5 user=www-data numprocs=2 redirect_stderr=true -stdout_logfile=/srv/www/storage/logs/supervisor-worker.log +stdout_logfile=/var/www/html/storage/logs/supervisor-worker.log [program:php-fpm] command=/usr/sbin/php-fpm8.0 -F diff --git a/build/panel/entrypoint b/build/panel/entrypoint new file mode 100644 index 0000000..1fee639 --- /dev/null +++ b/build/panel/entrypoint @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -x +if [ -d "/etc/php/mods-available"]; then + if [ -d "/etc/php/mods-available/cli" ]; then + sudo ln -s /etc/php/mods-available/cli/* /etc/php/8.0/cli/conf.d + fi + if [ -d "/etc/php/mods-available/fpm" ]; then + sudo ln -s /etc/php/mods-available/fpm/* /etc/php/8.0/fpm/conf.d + fi + find . -maxdepth 1 -type f -print0 | while read -d $'\0' file + do + sudo ln -s "$file" /etc/php/8.0/cli/conf.d/ + sudo ln -s "$file" /etc/php/8.0/fpm/conf.d/ + done +fi + +cd /var/www/html || exit 1 +#sudo chown -R pterodactyl:pterodactyl * +#sudo chown -R www-data:pterodactyl storage +#sudo chmod -R 775 storage/* bootstrap/cache + +if [ $# -gt 0 ]; then + sudo su -c "/bin/bash" +else + sudo service cron start + sudo /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf +fi diff --git a/build/panel/setup b/build/panel/setup new file mode 100644 index 0000000..8ab92a1 --- /dev/null +++ b/build/panel/setup @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +cd /var/www/html || exit 1 + +if [ ! -f ".env" ]; then + cp .env.example .env +fi + +sed -i "s/APP_ENV=.*/APP_ENV=local/" .env +sed -i "s/APP_DEBUG=.*/APP_DEBUG=true/" .env + +composer install --no-interaction --prefer-dist --no-scripts --no-progress +php artisan config:clear +yarn install --no-progress + +sudo chown -R pterodactyl:pterodactyl * +sudo chown -R www-data:pterodactyl storage +sudo chmod -R 775 storage/* bootstrap/cache + +sudo supervisorctl reread +sudo supervisorctl update +sudo supervisorctl start pteroq:* +sudo supervisorctl restart nginx diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..194c94c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,98 @@ +version: '3.8' + +services: + traefik: + image: traefik:2.6 + restart: always + networks: + - pterodactyl + ports: + - "443:443" + - "8080:8080" + security_opt: + - no-new-privileges=true + volumes: + - ./traefik:/etc/traefik:ro + - ./.data/certificates:/etc/certs:ro + - /var/run/docker.sock:/var/run/docker.sock:ro + app: + build: + context: ./build/panel + dockerfile: Dockerfile + networks: + pterodactyl: + aliases: + - pterodactyl.test + volumes: + - ./code/panel:/var/www/html:cached + - ./docker/certificates:/etc/ssl/private:ro + - ./docker/php:/etc/php/mods-available:ro + labels: + - "traefik.enable=true" + - "traefik.http.routers.app.tls=true" + - "traefik.http.routers.app.rule=Host(`pterodactyl.test`)" + - "traefik.http.routers.app.entrypoints=https" + - "traefik.http.services.app.loadbalancer.server.port=80" + mysql: + image: mariadb:10.7 + restart: unless-stopped + ports: + - "3306:3306" + command: + - --innodb-buffer-pool-size=1G + - --innodb-log-file-size=256M + - --innodb-flush-log-at-trx-commit=0 + - --lower-case-table-names=1 + volumes: + - mysql:/var/lib/mysql:delegated + - ./docker/mysql:/docker-entrypoint-initdb.d:ro + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: panel + MYSQL_USER: pterodactyl + MYSQL_PASSWORD: pterodactyl + networks: + - pterodactyl + redis: + image: redis:alpine + restart: unless-stopped + networks: + - pterodactyl + minio: + image: minio/minio:RELEASE.2022-02-05T04-40-59Z + restart: unless-stopped + command: server --console-address ":9001" /var/lib/minio + environment: + MINIO_ROOT_USER: minio + MINIO_ROOT_PASSWORD: password + expose: + - 9000 + - 9001 + networks: + pterodactyl: + aliases: + - s3.minio.pterodactyl.test + volumes: + - minio:/var/lib/minio:delegated + labels: + - "traefik.enable=true" + - "traefik.http.routers.minio.tls=true" + - "traefik.http.routers.minio.rule=Host(`s3.minio.pterodactyl.test`)" + - "traefik.http.routers.minio.entrypoints=https" + - "traefik.http.routers.minio.service=minio" + - "traefik.http.routers.minio-console.tls=true" + - "traefik.http.routers.minio-console.rule=Host(`minio.pterodactyl.test`)" + - "traefik.http.routers.minio-console.entrypoints=https" + - "traefik.http.routers.minio-console.service=minio-console" + - "traefik.http.services.minio.loadbalancer.server.port=9000" + - "traefik.http.services.minio-console.loadbalancer.server.port=9001" + +networks: + pterodactyl: + driver: bridge + +volumes: + mysql: + driver: local + minio: + driver: local diff --git a/docker/certificates/.gitkeep b/docker/certificates/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docker/mysql/00-setup.sql b/docker/mysql/00-setup.sql new file mode 100644 index 0000000..5f9334b --- /dev/null +++ b/docker/mysql/00-setup.sql @@ -0,0 +1,3 @@ +create database if not exists panel_test; +grant all on panel_test.* TO 'pterodactyl'@'%'; +flush privileges; diff --git a/docker/php/99-pterodactyl.ini b/docker/php/99-pterodactyl.ini new file mode 100644 index 0000000..6c5f90f --- /dev/null +++ b/docker/php/99-pterodactyl.ini @@ -0,0 +1,13 @@ +[opcache] +opcache.revalidate_freq = 0 +opcache.max_accelerated_files = 11003 +opcache.memory_consumption = 192 +opcache.interned_strings_buffer = 16 +opcache.fast_shutdown = 1 +opcache.enable = 1 +opcache.enable_cli = 1 + +[xdebug] +xdebug.mode=debug +xdebug.client_host=host.docker.internal +xdebug.client_port=9003 diff --git a/traefik/dynamic.yml b/traefik/dynamic.yml new file mode 100644 index 0000000..4178cbe --- /dev/null +++ b/traefik/dynamic.yml @@ -0,0 +1,8 @@ +http: + middlewares: + compress: + compress: +tls: + certificates: + - certFile: /etc/certs/pterodactyl.test.pem + keyFile: /etc/certs/pterodactyl.test-key.pem diff --git a/traefik/traefik.yml b/traefik/traefik.yml new file mode 100644 index 0000000..3521754 --- /dev/null +++ b/traefik/traefik.yml @@ -0,0 +1,17 @@ +global: + sendAnonymousUsage: false +api: + insecure: true + dashboard: true +entryPoints: + https: + address: ":443" +providers: + file: + filename: /etc/traefik/dynamic.yml + watch: true + docker: + endpoint: unix:///var/run/docker.sock + exposedByDefault: false + network: pterodactyl +