Cleanup and initial commit

This commit is contained in:
2024-01-10 17:15:41 -06:00
parent 736f325590
commit bde7e8eca7
14 changed files with 422 additions and 1 deletions

2
.dockerignore Normal file
View File

@@ -0,0 +1,2 @@
/resources
README.md

100
Dockerfile Normal file
View File

@@ -0,0 +1,100 @@
FROM alpine AS base
ENV PHP_VER="php81" \
PHPFPM_VER="php-fpm81" \
NODE_OPTIONS=--openssl-legacy-provider
RUN apk --no-cache add \
bash \
curl \
nginx \
${PHP_VER} \
${PHP_VER}-bcmath \
${PHP_VER}-common \
${PHP_VER}-ctype \
${PHP_VER}-dom \
${PHP_VER}-fileinfo \
${PHP_VER}-fpm \
${PHP_VER}-gd \
${PHP_VER}-mbstring \
${PHP_VER}-pecl-memcached \
${PHP_VER}-openssl \
${PHP_VER}-pdo \
${PHP_VER}-pdo_mysql \
${PHP_VER}-phar \
${PHP_VER}-posix \
${PHP_VER}-json \
${PHP_VER}-session \
${PHP_VER}-simplexml \
${PHP_VER}-sodium \
${PHP_VER}-tokenizer \
${PHP_VER}-xmlwriter \
${PHP_VER}-zip \
${PHP_VER}-zlib && \
mkdir -p \
/var/www/pterodactyl \
/run/nginx \
/run/php-fpm && \
ln -s /etc/${PHP_VER} /etc/php && \
ln -s /usr/bin/${PHP_VER} /usr/bin/php && \
ln -s /usr/sbin/${PHPFPM_VER} /usr/sbin/php-fpm && \
ln -s /var/log/${PHP_VER} /var/log/php
FROM base AS build
WORKDIR /var/www/pterodactyl
# Download latest Panel build from project repository: https://github.com/pterodactyl/panel
ADD https://github.com/pterodactyl/panel/releases/latest/download/panel.tar.gz panel.tar.gz
# Install dependencies, perform Panel installation process
RUN apk --no-cache add yarn && \
tar -xf panel.tar.gz && \
rm panel.tar.gz && \
chmod -R 755 storage/* bootstrap/cache && \
find storage -type d > .storage.tmpl && \
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer && \
cp .env.example .env && \
composer install --ansi --no-dev --optimize-autoloader && \
chown -R nginx:nginx * && \
yarn install --production && \
yarn add cross-env && \
yarn run build:production && \
rm -rf node_modules .env ./storage
FROM base AS release
WORKDIR /var/www/pterodactyl
ENV S6_BEHAVIOUR_IF_STAGE2_FAILS="2"
# Copy built Panel from Build stage
COPY --from=build --chown=nginx:nginx /var/www /var/www
COPY root/ /
# Download latest S6-Overlay build from project repository: https://github.com/just-containers/s6-overlay
ADD https://github.com/just-containers/s6-overlay/releases/download/v2.2.0.3/s6-overlay-amd64-installer /tmp/s6-overlay
# Download latest Wait-For-It script from project repository: https://github.com/vishnubob/wait-for-it
ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /usr/local/bin/wait-for-it
# Download common tools
ADD https://bitbucket.org/Gethec/projecttools/raw/master/DockerUtilities/ContainerTools /usr/bin/ContainerTools
# Install S6-Overlay and Wait-For-It
RUN chmod u+x /tmp/s6-overlay /usr/local/bin/wait-for-it && \
/tmp/s6-overlay / && \
# Remove preinstalled conf files
rm -rf \
/tmp/* \
/etc/nginx/http.d/default.conf \
/etc/${PHP_VER}/php-fpm.d/www.conf && \
# Symlink storage and conf file
ln -s /config/storage storage && \
ln -s /config/pterodactyl.conf .env
# Expose HTTP port
EXPOSE 80
# Persistent storage directory
VOLUME [ "/config" ]
# Set entrypoint to S6-Overlay
ENTRYPOINT [ "/init" ]

View File

@@ -1,2 +1,58 @@
# Pterodactyl-Panel # Pterodactyl-Panel #
## **NOTICE:**
S6-Overlay released V3 at the start of the year, and with it came fundamental changes to how containers are built and services are handled. I will, in the near future, be moving this container to the new system, which will require some changes to how the container is configured and run. To allow users who do not wish to make these changes to continue to use the container, I have created the `s6-v2` branch and tag that will continue to be built with the final release of S6 before the version jump. For those who want to jump straight into the new, untested, but probably working S6 V3 version, check out the `s6-v3` tag. If you run into any questions or problems, please open an issue!
## Disclaimer ##
As with anything else, exposing your system to the Internet incurs risks! This container does its best to be as secure as possible, but makes no guarantees to being completely impenetrable. Use at your own risk, and feel free to suggest changes that can further increase security.
## About ##
The Pterodactyl project is an impressive one to me, but I wanted a way to make use of it in Unraid without installing it to the system. Thus, this set of containers was born. Panel uses uses Alpine's official image to keep the footprint small.
## Configuration ##
The configuration of the Panel container is much less complicated than the Wings container. Most of the configuration occurs through environment variables. Simply define them to enable that component.
### Variables ###
This container uses [vishnubob's wait-for-it](https://github.com/vishnubob/wait-for-it) script to allow you to have startup wait for the SQL and Redis servers to become available before continuing. Simply set the HOST values to the correct hostname or IP address, and specific a port number, if you are not using the services' default option. You can also set `TESTTIME` to change the wait period from the default 30 seconds to whatever you desire.
It's also worth noting that, since this container is developed for use in Unraid, which has several excelent reverse proxy options, not much attention has been given to making the HTTPS option work. It should work in theory, but please submit a bug report if you encounter any issues. To enable, set `HTTPS` to "true", then map the location of your `fullchain.pem` and `privkey.pem` files to `/le-ssl`.
| Variable | Default | Example |
|----------|---------|---------|
| DBHOST | `NULL` | `-e DBHOST="MariaDB"` |
| DBPORT | `3306` | `-e DBPORT=3306` |
| REDISHOST | `NULL` | `-e REDISHOST="Redis"` |
| REDISPORT | `6379` | `-e REDISPORT=6379` |
| TESTTIME | `30` | `-e TESTTIME=30` |
| HTTPS | `NULL` | `-e HTTPS="true"` |
### Volumes ###
| Volume | Note | Example |
|--------|------|---------|
| /config | Required for persistence | `-v "/mnt/user/appdata/panel":"/config"` |
| /le-ssl | Expected location for SSL certs, if HTTPS is enabled | `-v "/letsencrypt/cert/directory":"/le-ssl":ro` |
### Ports ###
| Port | Note | Example |
|------|------|---------|
| 80 | Default port if HTTPS is disabled. Redirects to 443 otherwise | `-p 80:80` |
| 443 | Web interface if HTTPS is enabled | `- p 443:443` |
## Setup ##
**IMPORTANT:** While this container automates as much as possible, manual setup of the environment is still required to finish installation. For instructions, complete the Environmental Configuration, Database Setup and Add The First User sections in [Pterodactyl's "Getting Started" guide](https://pterodactyl.io/panel/1.0/getting_started.html#environment-configuration).
Example run command:
docker run \
--name="Panel" \
-e DBHOST="MariaDB" \
-e DBPORT=3306 \
-e REDISHOST="Redis" \
-e REDISPORT=6379 \
-e TESTTIME=30 \
-e HTTPS=false \
-v "/mnt/user/appdata/panel":"/config" \
-v "/mnt/user/appdata/swag/etc/letsencrypt/live/<example.com>":"/le-ssl":ro \
-p 80:80 \
gethec/pterodactyl-panel

View File

@@ -0,0 +1,49 @@
# HTTP config file, copied from https://pterodactyl.io/panel/1.0/webserver_configuration.html#nginx-without-ssl
# Last updated: 01/10/2024
server {
# Replace the example <domain> with your domain name or IP address
listen 80 default;
server_name _;
root /var/www/pterodactyl/public;
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/pterodactyl.app-error.log error;
# allow larger file uploads and longer script runtimes
client_max_body_size 100m;
client_body_timeout 120s;
sendfile off;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_PROXY "";
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
}
location ~ /\.ht {
deny all;
}
}

View File

@@ -0,0 +1,69 @@
# HTTP config file, copied from https://pterodactyl.io/panel/1.0/webserver_configuration.html#nginx-with-ssl
# Last updated: 01/10/2024
server_tokens off;
server {
listen 80;
server_name _;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name _;
root /var/www/pterodactyl/public;
index index.php;
access_log /var/log/nginx/pterodactyl.app-access.log;
error_log /var/log/nginx/pterodactyl.app-error.log error;
# allow larger file uploads and longer script runtimes
client_max_body_size 100m;
client_body_timeout 120s;
sendfile off;
# SSL Configuration - Replace the example <domain> with your domain
ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
ssl_prefer_server_ciphers on;
# See https://hstspreload.org/ before uncommenting the line below.
# add_header Strict-Transport-Security "max-age=15768000; preload;";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header Content-Security-Policy "frame-ancestors 'self'";
add_header X-Frame-Options DENY;
add_header Referrer-Policy same-origin;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_PROXY "";
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
include /etc/nginx/fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}

View File

@@ -0,0 +1,69 @@
#!/usr/bin/with-contenv bash
source ContainerTools
SNAME=${BASH_SOURCE##*/}
# If DBHOST value is present, pause boot until target container is up.
if [ -n "$DBHOST" ]; then
log "Waiting for SQL at $DBHOST:${DBPORT:=3306}"
if wait-for-it $DBHOST:$DBPORT -q -t ${TESTTIME:=30}; then
log "SQL found, continuing"
else
log "SQL could not be reached! Exiting..."
exit 1
fi
fi
# If REDISHOST value is present, pause boot until target container is up.
if [ -n "$REDISHOST" ]; then
log "Waiting for Redis at $REDISHOST:${REDISPORT:=6379}"
if wait-for-it $REDISHOST:$REDISPORT -q -t ${TESTTIME:=30}; then
log "Redis found, continuing"
else
log "Redis could not be reached! Exiting..."
exit 1
fi
fi
# Check for persistent storage directory, create file structure if not present.
if [ ! -d "/config/storage" ]; then
log "Creating storage directory"
cat .storage.tmpl | while read line; do
mkdir -p "/config/${line}"
done
fi
# Check for persistent logging directory, create file path if not present.
if [ ! -d "/config/log/nginx" ]; then
log "Creating log directory."
mkdir -p "/config/log/nginx"
fi
# Check for config file, create template if not present.
if [ ! -e /config/pterodactyl.conf ]; then
log "Config file does not exist, creating template"
log "[WARN] Connect to container and finish setup process"
cp .env.example /config/pterodactyl.conf
log "Generating unique Pterodactyl key"
log "$(php artisan key:generate --force --no-interaction)"
fi
# Clear views and autogenerated configs on launch. This is necessary for updates, and doesn't affect non-update launches.
log "$(php artisan view:clear)"
log "$(php artisan config:clear)"
log "Checking for database updates, preparing cache"
log "[NOTE] This will fail if the database connection has not yet been configured"
log "$(php artisan migrate --seed --force)"
chown -R nginx:nginx /config/
# Load selected Nginx conf.
if [ "$HTTPS" == "true" ]; then
if [ ! -e "/etc/nginx/http.d/pterodactyl.conf" ]; then
log "Symlinking Nginx config file for HTTPS"
ln -s /defaults/nginx/https.conf /etc/nginx/http.d/pterodactyl.conf
fi
else
if [ ! -e "/etc/nginx/http.d/pterodactyl.conf" ]; then
log "Symlinking Nginx config file for HTTP"
ln -s /defaults/nginx/http.conf /etc/nginx/http.d/pterodactyl.conf
fi
fi

1
root/etc/crontabs/nginx Normal file
View File

@@ -0,0 +1 @@
* * * * * php /var/www/pterodactyl/artisan schedule:run >> /dev/null 2>&1

44
root/etc/nginx/nginx.conf Normal file
View File

@@ -0,0 +1,44 @@
user nginx;
worker_processes auto;
pcre_jit on;
error_log /var/log/nginx/error.log warn;
include /etc/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_tokens off;
client_max_body_size 1m;
sendfile on;
tcp_nopush on;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:2m;
ssl_session_timeout 5M;
ssl_session_tickets off;
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
gzip_disable "MSIE [1-6]\.";
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
include /etc/nginx/http.d/*.conf;
}

View File

@@ -0,0 +1,5 @@
[global]
pid = /run/php-fpm/php-fpm.pid
error_log = /var/log/php/error.log
log_level = warning
include=/etc/php/php-fpm.d/*.conf

View File

@@ -0,0 +1,17 @@
[nginx]
user = nginx
group = nginx
listen = /run/php-fpm/php-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0750
pm = ondemand
pm.max_children = 9
pm.process_idle_timeout = 10s
pm.max_requests = 200
slowlog = /dev/stdout
request_slowlog_timeout = 60s
catch_workers_output = yes

View File

@@ -0,0 +1,2 @@
#!/usr/bin/execlineb -P
/usr/sbin/crond -fL /dev/null

View File

@@ -0,0 +1,2 @@
#!/usr/bin/execlineb -P
/usr/sbin/nginx -g "daemon off;"

View File

@@ -0,0 +1,2 @@
#!/usr/bin/execlineb -P
/usr/sbin/php-fpm -Fc /etc/php

View File

@@ -0,0 +1,3 @@
#!/usr/bin/execlineb -P
s6-setuidgid nginx
/usr/bin/php /var/www/pterodactyl/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3