Merge pull request #1285 from parkervcp/feature/add-dockerfile

This commit is contained in:
Dane Everitt 2018-09-18 21:41:16 -07:00 committed by GitHub
commit b9c2148630
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 399 additions and 2 deletions

76
.dev/docker/README.md Normal file
View file

@ -0,0 +1,76 @@
# Pterodactyl Panel - Docker Image
This is a ready to use docker image for the panel.
## Requirements
This docker image requires some additional software to function. The software can either be provided in other containers (see the [docker-compose.yml](docker-compose.yml) as an example) or as existing instances.
A mysql database is required. We recommend the stock [MariaDB Image](https://hub.docker.com/_/mariadb/) image if you prefer to run it in a docker container. As a non-containerized option we recommend mariadb.
A caching software is required as well. We recommend the stock [Redis Image](https://hub.docker.com/_/redis/) image. You can choose any of the [supported options](#cache-drivers).
You can provide additional settings using a custom `.env` file or by setting the appropriate environment variables in the docker-compose file.
## Setup
Start the docker container and the required dependencies (either provide existing ones or start containers as well, see the [docker-compose.yml](docker-compose.yml) file as an example).
After the startup is complete you'll need to create a user.
If you are running the docker container without docker-compose, use:
```
docker exec -it <container id> php artisan p:user:make
```
If you are using docker compose use
```
docker-compose exec panel php artisan p:user:make
```
## Environment Variables
There are multiple environment variables to configure the panel when not providing your own `.env` file, see the following table for details on each available option.
Note: If your `APP_URL` starts with `https://` you need to provide an `LETSENCRYPT_EMAIL` as well so Certificates can be generated.
| Variable | Description | Required |
| ------------------- | ------------------------------------------------------------------------------ | -------- |
| `APP_URL` | The URL the panel will be reachable with (including protocol) | yes |
| `APP_TIMEZONE` | The timezone to use for the panel | yes |
| `LETSENCRYPT_EMAIL` | The email used for letsencrypt certificate generation | yes |
| `DB_HOST` | The host of the mysql instance | yes |
| `DB_PORT` | The port of the mysql instance | yes |
| `DB_DATABASE` | The name of the mysql database | yes |
| `DB_USERNAME` | The mysql user | yes |
| `DB_PASSWORD` | The mysql password for the specified user | yes |
| `CACHE_DRIVER` | The cache driver (see [Cache drivers](#cache-drivers) for detais) | yes |
| `SESSION_DRIVER` | | yes |
| `QUEUE_DRIVER` | | yes |
| `REDIS_HOST` | The hostname or IP address of the redis database | yes |
| `REDIS_PASSWORD` | The password used to secure the redis database | maybe |
| `REDIS_PORT` | The port the redis database is using on the host | maybe |
| `MAIL_DRIVER` | The email driver (see [Mail drivers](#mail-drivers) for details) | yes |
| `MAIL_FROM` | The email that should be used as the sender email | yes |
| `MAIL_HOST` | The host of your mail driver instance | maybe |
| `MAIL_PORT` | The port of your mail driver instance | maybe |
| `MAIL_USERNAME` | The username for your mail driver | maybe |
| `MAIL_PASSWORD` | The password for your mail driver | maybe |
### Cache drivers
You can choose between different cache drivers depending on what you prefer.
We recommend redis when using docker as it can be started in a container easily.
| Driver | Description | Required variables |
| -------- | ------------------------------------ | ------------------------------------------------------ |
| redis | host where redis is running | `REDIS_HOST` |
| redis | port redis is running on | `REDIS_PORT` |
| redis | redis database password | `REDIS_PASSWORD` |
### Mail drivers
You can choose between different mail drivers according to your needs.
Every driver requires `MAIL_FROM` to be set.
| Driver | Description | Required variables |
| -------- | ------------------------------------ | ------------------------------------------------------------- |
| mail | uses the installed php mail | |
| mandrill | [Mandrill](http://www.mandrill.com/) | `MAIL_USERNAME` |
| postmark | [Postmark](https://postmarkapp.com/) | `MAIL_USERNAME` |
| mailgun | [Mailgun](https://www.mailgun.com/) | `MAIL_USERNAME`, `MAIL_HOST` |
| smtp | Any SMTP server can be configured | `MAIL_USERNAME`, `MAIL_HOST`, `MAIL_PASSWORD`, `MAIL_PORT` |

51
.dev/docker/default.conf Normal file
View file

@ -0,0 +1,51 @@
# If using Ubuntu this file should be placed in:
# /etc/nginx/sites-available/
#
# If using CentOS this file should be placed in:
# /etc/nginx/conf.d/
#
server {
listen 80;
server_name _;
root /app/public;
index index.html index.htm 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)(/.+)$;
# the fastcgi_pass path needs to be changed accordingly when using CentOS
fastcgi_pass unix:/var/run/php/php-fpm7.2.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,70 @@
# If using Ubuntu this file should be placed in:
# /etc/nginx/sites-available/
#
server {
listen 80;
server_name <domain>;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name <domain>;
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;
# strengthen ssl security
ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
# See the link below for more SSL information:
# https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
#
# ssl_dhparam /etc/ssl/certs/dhparam.pem;
# Add headers to serve security related headers
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'";
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/pterodactyl.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;
}
}

46
.dev/docker/entrypoint.sh Normal file
View file

@ -0,0 +1,46 @@
#!/bin/ash
## Ensure we are in /app
cd /app
## check for .env file and generate app keys if missing
if [ -f /app/var/.env ]; then
echo "external vars exist"
rm /app/.env
ln -s /app/var/.env /app/
else
echo "external vars don't exist"
rm /app/.env
touch /app/var/.env
## manually generate a key because key generate --force fails
echo -e "Generating key"
APP_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
echo -e "Generated app key: $APP_KEY"
echo -e "APP_KEY=$APP_KEY" > /app/var/.env
ln -s /app/var/.env /app/
fi
## check for DB up before starting the panel
echo "Checking database status."
until nc -z -v -w30 $DB_HOST 3306
do
echo "Waiting for database connection..."
# wait for 5 seconds before check again
sleep 5
done
## make sure the db is set up
echo -e "Migrating and Seeding DB"
php artisan migrate --force
php artisan db:seed --force
## start cronjobs for the queue
echo -e "Starting cron jobs"
crond
echo -e "Starting supervisord"
exec "$@"

View file

@ -0,0 +1,39 @@
[unix_http_server]
file=/tmp/supervisor.sock ; path to your socket file
[supervisord]
logfile=/var/log/supervisord/supervisord.log ; supervisord log file
logfile_maxbytes=50MB ; maximum size of logfile before rotation
logfile_backups=2 ; number of backed up logfiles
loglevel=error ; info, debug, warn, trace
pidfile=/var/run/supervisord.pid ; pidfile location
nodaemon=false ; run supervisord as a daemon
minfds=1024 ; number of startup file descriptors
minprocs=200 ; number of process descriptors
user=root ; default user
childlogdir=/var/log/supervisord/ ; where child log files will live
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
[program:php-fpm]
command=/usr/sbin/php-fpm7 -F
autostart=true
autorestart=true
[program:queue-worker]
command=/usr/bin/php /app/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3
user=nginx
autostart=true
autorestart=true
[program:nginx]
command=/usr/sbin/nginx -g 'daemon off;'
autostart=true
autorestart=true
priority=10
stdout_events_enabled=true
stderr_events_enabled=true

16
.dev/docker/www.conf Normal file
View file

@ -0,0 +1,16 @@
[pterodactyl]
user = nginx
group = nginx
listen = /var/run/php/php-fpm7.2.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
clear_env = no

3
.gitignore vendored
View file

@ -20,8 +20,9 @@ sami.phar
# For local development with docker # For local development with docker
# Remove if we ever put the Dockerfile in the repo # Remove if we ever put the Dockerfile in the repo
.dockerignore .dockerignore
Dockerfile #Dockerfile
docker-compose.yml docker-compose.yml
# for image related files # for image related files
misc misc
.phpstorm.meta.php .phpstorm.meta.php

26
Dockerfile Normal file
View file

@ -0,0 +1,26 @@
FROM alpine:3.8
WORKDIR /app
RUN apk add --no-cache --update ca-certificates certbot nginx dcron curl tini php7 php7-bcmath php7-common php7-dom php7-fpm php7-gd php7-mbstring php7-openssl php7-zip php7-pdo php7-phar php7-json php7-pdo_mysql php7-session php7-ctype php7-tokenizer php7-zlib php7-simplexml supervisor \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
COPY . ./
RUN cp .env.example .env \
&& composer install --no-dev --optimize-autoloader \
&& rm .env \
&& chown -R nginx:nginx . && chmod -R 777 storage/* bootstrap/cache
RUN cp .dev/docker/default.conf /etc/nginx/conf.d/default.conf \
&& cp .dev/docker/www.conf /etc/php7/php-fpm.d/www.conf \
&& cat .dev/docker/supervisord.conf > /etc/supervisord.conf \
&& echo "* * * * * /usr/bin/php /app/pterodactyl/artisan schedule:run >> /dev/null 2>&1" >> /var/spool/cron/crontabs/root \
&& mkdir -p /var/run/php /var/run/nginx \
&& mkdir -p /var/log/supervisord/
EXPOSE 80 443
ENTRYPOINT ["/bin/ash", ".dev/docker/entrypoint.sh"]
CMD [ "supervisord", "-n", "-c", "/etc/supervisord.conf" ]

View file

@ -9,7 +9,7 @@ return [
| change this value if you are not maintaining your own internal versions. | change this value if you are not maintaining your own internal versions.
*/ */
'version' => 'canary', 'version' => '0.7.10',
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View file

@ -0,0 +1,72 @@
version: '2'
services:
database:
image: mariadb
volumes:
- "/srv/pterodactyl/database:/var/lib/mysql"
environment:
## Database settings
## change if you want it to be more secure.
- "MYSQL_ROOT_PASSWORD=apassword"
- "MYSQL_DATABASE=pterodb"
- "MYSQL_USER=ptero"
- "MYSQL_PASSWORD=pterodbpass"
cache:
image: redis:alpine
panel:
image: quay.io/pterodactyl/panel:latest
ports:
- "80:80"
- "443:443"
links:
- database
- cache
volumes:
- "/srv/pterodactyl/var/:/app/var/"
environment:
## These are defaults and should be left alone
- "APP_ENV=production"
- "APP_DEBUG=false"
- "APP_THEME=pterodactyl"
- "APP_CLEAR_TASKLOG=720"
- "APP_DELETE_MINUTES=10"
- "APP_ENVIRONMENT_ONLY=false"
- "QUEUE_HIGH=high"
- "QUEUE_STANDARD=standard"
- "QUEUE_LOW=low"
## Cache settings
- "CACHE_DRIVER=redis"
- "SESSION_DRIVER=redis"
- "QUEUE_DRIVER=redis"
- "REDIS_HOST=cache"
- "REDIS_PASSWORD=null"
- "REDIS_PORT=6379"
## Domain settings
- "APP_URL=https://your.domain.here"
## Timezone settings
- "APP_TIMEZONE=America/New_York"
## Service egg settings
- "APP_SERVICE_AUTHOR=noreply@your.domain.here"
## Database settings
## change if you want it to be more secure.
- "DB_HOST=database"
- "DB_PORT=3306"
- "DB_DATABASE=pterodb"
- "DB_USERNAME=ptero"
- "DB_PASSWORD=pterodbpass"
## Email settings
- "MAIL_FROM=noreply@your.domain.here"
- "MAIL_DRIVER=smtp"
- "MAIL_HOST=mail"
- "MAIL_PORT=1025"
- "MAIL_USERNAME=''"
- "MAIL_PASSWORD=''"
- "MAIL_ENCRYPTION=true"
networks:
default:
ipam:
config:
- subnet: 172.20.0.0/16