diff --git a/docs/eggs/creating-a-custom-egg.mdx b/docs/eggs/creating-a-custom-egg.mdx new file mode 100644 index 00000000..6076c583 --- /dev/null +++ b/docs/eggs/creating-a-custom-egg.mdx @@ -0,0 +1,301 @@ +# Creating a Custom Egg + +## Create New Egg + +Navigate to the Admin Panel and click the eggs option in the sidebar then select `New Egg` button. + +You will be taken to a new egg configuration page which is where most of the configuration happens. + +### Name +This is the name of your egg. + +### Author +This is the original creator's email. + +### Description +This is the description of your egg and what is needed to run it. + +### Startup Commands +Here you can assign multiple startup commands to run your server. +Example below: +```bash +java -Xms128M -XX:MaxRAMPercentage=95.0 -Dterminal.jline=false -Dterminal.ansi=true -jar {{SERVER_JARFILE}} +``` +### File Denylist +Here you can specify a list of files that the end user is not allowed to edit. + +### Features (Egg Features) +Egg features can do different things when specified. Example below: +| Tag | Description | +| ------------------------- | ------------------------------------------- | +| eula | Displays a popup for accepting the EULA | +| java_version | Specifies the Java version | +| pid_limit | Setting that restricts the maximum number of processes that can run within a container or on a system | +| steam_disk_space | Sets a limit to enable an "out of disk space" Popup if the host system is out of disk space | + +### Tags +The tag system allows you to group eggs together by type. This is the successor to nests. + +### Update URL +This can be specified so that users who use your egg can update the egg without having to look around for where the egg is hosted. + +### Docker Images (Yolks) +Every egg has a Docker image or Yolk as they are referred to. Images can be custom-made, and you can learn how to create them in the "Creating a Custom Yolk" guide or you can use the pre-made ones found here [Yolk Repo](https://github.com/pelican-eggs/yolks). They have two fields that need to be defined: the name of the image and the URL where the image is hosted. + +:::info +Docker images must be specifically designed to work with Pelican Panel. You should read more about that in our Creating a Yolk guide. +::: + +## Configure Process Management + +This is perhaps the most important step in egg configuration, as this tells Wings how to run everything. + +The first field you'll encounter is `Copy Settings From`. The default selection is `None`. That is expected, and okay. This dropdown is discussed at the end of this article. + +### Stop Command + +Next, you'll encounter `Stop Command` and, as the name implies, this should be the command used to safely stop the server. For some games, this is `stop` or `end`. Certain programs and games don't have a specified stop command, so you can enter `^C`, `^SIGINT`, `^SIGABRT`, `^SIGTERM` or `^SIGKILL` to have Wings end the process. + +### Log Storage (Coming Soon) + +Logs are completely handled by Wings and use Docker logs to output the complete output from the server. This can be set like below: + +```json +{} +``` + +### Configuration Files + +The next block is one of the most complex blocks, the `Configuration Files` descriptor. Wings will process this block prior to booting the server to ensure all of the required settings are defined and set correctly. + +```json +{ + "server.properties": { + "parser": "properties", + "find": { + "server-ip": "0.0.0.0", + "enable-query": "true", + "server-port": "{{server.allocations.default.port}}", + "query.port": "{{server.allocations.default.port}}" + } + } +} +``` + +In this example, we are telling Wings to read `server.properties` in `/home/container`. Within this block, we define a `parser`, in this case `properties` but the following are valid parsers: + +- `file` — This parser goes based on matching the beginning of lines, and not a specific property like the other five. Avoid using this parser if possible. +- `yaml` (supports `*` notation) +- `properties` +- `ini` +- `json` (supports `*` notation) +- `xml` (supports `*` notation) + +Once you have defined a parser, we then define a `find` block which tells Wings what specific elements to find and replace. In this example, we have provided four separate items within the `server.properties` file that we want to find and replace to the assigned values. You can use either an exact value, or define a specific server setting from the server configuration. In this case, we're assigning the default server port to be used as the `server.port` and `query.port`. **These placeholders are case sensitive, and should have no spaces in them.** + +You can have multiple files listed here, Wings will process them in parallel before starting the server. When using `yaml` or `json` you can use more advanced searching for elements. + +```json +{ + "config.yml": { + "parser": "yaml", + "find": { + "listeners[0].query_enabled": true, + "listeners[0].query_port": "{{server.allocations.default.port}}", + "listeners[0].host": "0.0.0.0:{{server.allocations.default.port}}", + "servers.*.address": { + "127.0.0.1": "{{config.docker.interface}}", + "localhost": "{{config.docker.interface}}" + } + } + } +} +``` + +In this example, we are parsing `config.yml` using the `yaml` parser. The first three find items are simply assigning ports and IPs for the first listener block. The last one, `servers.*.address` uses wildcard matching to match any items within the `servers` block, and then finding each `address` block for those items. + +An advanced feature of this file configuration is the ability to define multiple find and replace statements for a single matching line. In this case, we are looking for either `127.0.0.1` or `localhost` and replacing them with the docker interface defined in the configuration file using `{{config.docker.interface}}`. + +### Start Configuration + +The last block to configure is the `Start Configuration` for servers running using this egg. + +```json +{ + "done": ")! For help, type " +} +``` + +In the example block above, we define `done` as the entire line, or part of a line that indicates a server is done starting, and is ready for players to join. When Wings sees this output, it will mark the server as `RUNNING` rather than `STARTING`. + +That concludes basic egg configuration. + +## Copy Settings From + +As mentioned above, there is a unique `Copy Settings From` dropdown when adding a new egg. This is used in two different places, there is one for the Process Management and one for the Install Script. This gives you the ability to, as the name suggests, copy settings defined above from a different egg. + +In the panel, we use this to copy settings that remain the same between similar eggs, such as many of the Minecraft eggs. + +## Egg Variables + +One of the great parts of Egg Variables is the ability to define specific variables that users and/or admins can control to tweak different settings without letting users modify the startup command. To create new variables, or edit existing ones, visit the egg you created, and click the `Variables` tab at the top of the page. Let's take a look at an example variable that we can create. + +The name and description are rather self-explanatory, so I'll skip down to the `Environment Variable` box. This should be an alphanumeric name with underscores, and should be uppercase. This will be the name of the environment variable which can be accessed in the startup command as `{{WOOZLE_WOO}}`, within file modifications as `{{server.environment.WOOZLE_WOO}}`, or just `${WOOZLE_WOO}` in any shell scripts (it is passed through in the environment). We also define a default value for this environment variable in this example, but it is not required to do so. + +### How to Reference Egg Variables + +Egg variables can be referenced in three different ways depending on the context: + +**In Startup Commands:** +```bash +java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}} +``` + +**In Configuration File Parser (find/replace blocks):** +```json +{ + "server.properties": { + "parser": "properties", + "find": { + "server-port": "{{server.allocations.default.port}}", + "max-players": "{{server.environment.MAX_PLAYERS}}", + "server-name": "{{server.environment.SERVER_NAME}}" + } + } +} +``` + +:::note +Variable syntax depends on the context: +**Startup commands**: Use `{{VAR_NAME}}` (e.g., `{{SERVER_MEMORY}}`) +**Configuration file parsers**: Use `{{server.environment.VAR_NAME}}` or `{{server.allocations.default.port}}` +**Install scripts and shell environments**: Use `${VAR_NAME}` +::: + +**In Install Scripts:** +```bash +#!/bin/bash +cd /mnt/server + +echo "Downloading Minecraft version ${MINECRAFT_VERSION}..." +curl -o server.jar https://example.com/minecraft-${MINECRAFT_VERSION}.jar + +echo "Setting default config from ${CONFIG_URL}" +``` + +The next section is `Permissions`, which is a dropdown with two options: `Users Can View` and `Users Can Edit`. + +- `Users Can View` — allows a user to view the field on the front-end, as well as the assigned value of that variable. They will be able to see it replaced in their startup command. +- `Users Can Edit` — allows a user to edit the value of the variable, for example the name of their `server.jar` file if running Minecraft. + +You should use caution here, even if you assign neither of the permissions it does not mean that the value will be hidden. Crafty users will still be able to get the environment on their server. In most cases this is simply hiding it from the user, and then used within the Dockerfile to perform actions, thus it is not important for the user to see. + +Finally, you will need to define some input rules to validate the value against. In this example, we use `required|string|between:1,10`, which means the field is `required`, must be a `string`, and must be between `1` and `10` characters in length. You can find all of the available validation rules in the [Laravel validation documentation](https://laravel.com/docs/validation#available-validation-rules). You can also use regex-based validation by using the `regex:` rule flag. For example, `required|regex:/^([\w\d._-]+)(\.jar)$/` will require the field, and will match the regex as any letters or numbers (`\w\d`) including underscore (`_`), periods (`.`), and dashes (`-`) ending in `.jar`. + +They will then be visible when managing the startup for a server in both the Admin CP and on the Front-End. + +## List of Default Variables + +The default variables are always accessible to all eggs and don't have to be created separately. They can be used in the egg startup, install script, or the configuration file parser. Below are an example of a few. + +| Variable | Description | Example | +| ------------------------- | ------------------------------------------- | -------------------------------------------------------------- | +| TZ | Time Zone | `Etc/UTC` | +| STARTUP | Startup command of the egg | `java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}` | +| SERVER_MEMORY | Memory available for the server in MB | `512` | +| SERVER_IP | Default IP of the server | `127.0.0.1` | +| SERVER_PORT | Primary Server Port | `27015` | +| P_SERVER_LOCATION | Location of the server | `Example City` | +| P_SERVER_UUID | UUID of the server | `539fdca8-4a08-4551-a8d2-8ee5475b50d9` | +| P_SERVER_ALLOCATION_LIMIT | Limit of allocations allowed for the server | `0` | + +## Install Script + +The install script is a crucial component of your egg that defines how the server files are downloaded, installed, and configured before the server can run for the first time. This script runs in a separate container during the installation process. + +### Install Script Configuration + +When configuring the install script, you'll need to specify: + +- **Script Container**: The Docker image that will be used to run the installation. This is often different from the runtime image and typically includes tools needed for downloading and extracting files (like `curl`, `wget`, `git`, `unzip`, etc.). +- **Install Script**: The actual bash script that performs the installation steps. +- **Script Entry**: This dropdown specifies which shell interpreter to use for running your install script: + - `bash` - Use for Debian/Ubuntu-based install images + - `ash` - Use for Alpine Linux-based install images + +### Example Install Script + +Here's an example of a typical install script for a Minecraft server: + +```bash +#!/bin/bash +# Minecraft Server Installation Script + +cd /mnt/server + +# Download the server jar +echo "Downloading server jar..." +curl -o server.jar https://example.com/minecraft-server.jar + +echo "Installation complete!" +``` + +### Install Script Variables + +Install scripts have access to all egg variables as well as some special installation-specific variables. You can reference these using the `${VARIABLE_NAME}` syntax: + +```bash +#!/bin/bash +cd /mnt/server + +# Download specific version using egg variable +echo "Downloading Minecraft version ${MINECRAFT_VERSION}..." +curl -o server.jar https://example.com/minecraft-${MINECRAFT_VERSION}.jar + +# Use server memory variable +echo "Server will run with ${SERVER_MEMORY}MB of RAM" +``` + +### Install Container Path + +:::warning +Install scripts run in `/mnt/server` instead of `/home/container`. All files you download or create during installation should be placed in `/mnt/server`, which will be mapped to `/home/container` when the server runs. +::: + +### Common Install Script Patterns + +**Downloading from a URL:** +```bash +curl -sSL -o server.jar https://example.com/server.jar +``` + +**Cloning from Git:** +```bash +git clone https://github.com/example/repo.git . +``` + +**Extracting Archives:** +```bash +curl -sSL https://example.com/archive.tar.gz | tar -xzv +``` + +**Building from Source:** +```bash +npm install +npm run build +``` + +### Install Script Exit Codes + +Your install script should exit with code `0` on success. Any non-zero exit code will be treated as a failure and the installation will be marked as failed. + +```bash +# Check if download was successful +if [ ! -f "server.jar" ]; then + echo "Failed to download server.jar" + exit 1 +fi + +echo "Installation successful" +exit 0 +``` diff --git a/docs/eggs/creating-a-custom-yolk.mdx b/docs/eggs/creating-a-custom-yolk.mdx new file mode 100644 index 00000000..c18648d4 --- /dev/null +++ b/docs/eggs/creating-a-custom-yolk.mdx @@ -0,0 +1,215 @@ + +# Creating a Custom Yolk + +:::warning +This tutorial uses examples from our [`ghcr.io/pelican-eggs/yolks:java_8`](https://github.com/pelican-eggs/yolks) docker image, which can be found on GitHub. This tutorial also assumes some knowledge of [Docker](https://docker.io/), we suggest reading up if this all looks foreign to you. +::: + +## Creating the Dockerfile + +The most important part of this process is to create the [`Dockerfile`](https://docs.docker.com/engine/reference/builder/) that will be used by Wings. Due to heavy restrictions on server containers, you must setup this file in a specific manner. + +In the past we have tried to make use of [Alpine Linux](https://alpinelinux.org) as much as possible for our images in order to keep their size down. But for my example we will just use what most eggs are built on, Ubuntu. + +```dockerfile +# ---------------------------------- +# Pelican Panel Dockerfile +# Environment: Java +# Minimum Panel Version: 1.0.0 +# ---------------------------------- + +FROM --platform=$TARGETOS/$TARGETARCH eclipse-temurin:8-jdk-noble + +LABEL org.opencontainers.image.authors=“support@pelican.dev” \ + org.opencontainers.image.source=“https://github.com/pelican-eggs/yolks” \ + org.opencontainers.image.licenses=MIT \ + org.opencontainers.image.description=“Custom Yolk for Pelican Hosting Panel” + +RUN apt update -y \ + && apt install -y \ + curl \ + lsof \ + ca-certificates \ + openssl \ + git \ + tar \ + sqlite3 \ + fontconfig \ + tzdata \ + iproute2 \ + libfreetype6 \ + redis-tools \ + tini \ + zip \ + unzip \ + jq + +## Setup user and working directory +RUN useradd -m -d /home/container -s /bin/bash container +USER container +ENV USER=container HOME=/home/container +WORKDIR /home/container + +STOPSIGNAL SIGINT + +COPY --chown=container:container ./entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh +ENTRYPOINT ["/usr/bin/tini", "-g", "--"] +CMD ["/entrypoint.sh"] +``` + +Let's walk through the `Dockerfile` above. The first thing you'll notice is the [`FROM`](https://docs.docker.com/engine/reference/builder/#from) declaration. + +```dockerfile +FROM --platform=$TARGETOS/$TARGETARCH eclipse-temurin:8-jdk-noble +``` + +In this case, we are using [`eclipse-temurin:8-jdk-noble`](https://github.com/adoptium/temurin-build) which provides us with Java 8. + +# Dockerfile Platform Architecture + +The `--platform=$TARGETOS/$TARGETARCH` flag tells Docker which platform architecture to use when pulling the base image. + +## Build-time variables + +- `$TARGETOS` - Target operating system (e.g., `linux`) +- `$TARGETARCH` - Target CPU architecture (e.g., `amd64`, `arm64`, `arm`) + +Docker automatically sets these during the build based on your target platform. +This is essential for cross-platform builds and ensuring containers run correctly on different architectures. + +## Installing Dependencies + +The next thing we do is install the dependencies we will need using Ubuntu's package manager: `apt-get`. To keep things clean everything is being contained in a single [`RUN`](https://docs.docker.com/engine/reference/builder/#run) block. + +```bash +RUN apt update -y \ + && apt install -y \ + curl \ + lsof \ + ca-certificates \ + openssl \ + git \ + tar \ + sqlite3 \ + fontconfig \ + tzdata \ + iproute2 \ + libfreetype6 \ + redis-tools \ + tini \ + zip \ + unzip \ + jq +``` + +## Creating a Container User + +Within this `RUN` block, you'll notice the `useradd` command. This is needed to be sure the container has the correct permissions within the system. + +```bash +RUN useradd -m -d /home/container -s /bin/bash container +``` + +:::warning +All Pelican containers must have a user named `container`, and the user home **must** be `/home/container`. +::: + +After we create that user, we then define the default container [`USER`](https://docs.docker.com/engine/reference/builder/#user) as well as a few [`ENV`](https://docs.docker.com/engine/reference/builder/#env) settings to be applied to things running within the container. + +```bash +ENV USER=container HOME=/home/container +``` + +## Work Directory & Entrypoint + +One of the last things we do is define a `WORKDIR` which is where everything else will be executed. The `WORKDIR` must be set to `/home/container`. +```bash +WORKDIR /home/container +``` + +Finally, we need to copy our `ENTRYPOINT` script into the docker image root. This is done using `COPY`, after which we define the command to be used when the container is started using `CMD`. The `CMD` line should always point to the `entrypoint.sh` file. +```dockerfile +COPY --chown=container:container ./entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh +ENTRYPOINT ["/usr/bin/tini", "-g", "--"] +CMD ["/entrypoint.sh"] +``` + +### Understanding the ENTRYPOINT + +The `ENTRYPOINT ["/usr/bin/tini", "-g", "--"]` line sets up Tini as the init process for the container. + +**What is Tini:** Tini is a minimal init system that acts as PID 1 inside the container, handling process signals and reaping zombie processes. + +**Flags:** +- `-g` - Sends signals to the entire process group, not just the child process +- `--` - Separates Tini's arguments from the command that follows + +**Why use it:** +- **Signal handling:** Ensures signals (like `SIGTERM` during container shutdown) are properly forwarded to your application, allowing graceful shutdowns +- **Zombie reaping:** Prevents zombie processes from accumulating when child processes aren't properly cleaned up + +:::warning +Sometimes you may need to change the permissions of the `entrypoint.sh` file. On Ubuntu Linux you can do this by executing `chmod +x entrypoint.sh` in the directory where the file is located. +::: + +## Entrypoint Script + +In order to complete this `Dockerfile`, we will need an `entrypoint.sh` file which tells Docker how to run this specific server type. + +These entrypoint files are actually fairly abstracted, and Wings will pass in the start command as an environment variable before processing it and then executing the command. + +```bash +#!/bin/bash +cd /home/container + +# Output Current Java Version +java -version ## only really needed to show what version is being used. Should be changed for different applications + +# Replace Startup Variables +MODIFIED_STARTUP=`eval echo $(echo ${STARTUP} | sed -e 's/{{/${/g' -e 's/}}/}/g')` +echo ":/home/container$ ${MODIFIED_STARTUP}" + +# Run the Server +${MODIFIED_STARTUP} +``` + +The second command, `cd /home/container`, simply ensures we are in the correct directory when running the rest of the commands. We then follow that up with `java -version` to output this information to end-users, but that is not necessary. + +## Modifying the Startup Command + +The most significant part of this file is the `MODIFIED_STARTUP` environment variable. What we are doing in this case is parsing the environment `STARTUP` that is passed into the container by Wings. In most cases, this variable looks something like the example below: + +```bash +STARTUP="java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}" +``` + +You'll notice some placeholders there, specifically `{{SERVER_MEMORY}}` and `{{SERVER_JARFILE}}`. These both refer to other environment variables being passed in, and they look something like the example below. + +```bash +SERVER_MEMORY=1024 +SERVER_JARFILE=server.jar +``` + +There are a host of different environment variables, and they change depending on the specific egg configuration. However, that is not necessarily anything to worry about here. + +```bash +MODIFIED_STARTUP=`eval echo $(echo ${STARTUP} | sed -e 's/{{/${/g' -e 's/}}/}/g')` +``` + +The command above simply evaluates the `STARTUP` environment variable, and then replaces anything surrounded in curly braces `{{EXAMPLE}}` with a matching environment variable (such as `EXAMPLE`). Thus, our `STARTUP` command: + +```bash +java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}} +``` + +Becomes: + +```bash +java -Xms128M -Xmx1024M -jar server.jar +``` + +## Run the Command + +The last step is to run this modified startup command, which is done with the line `${MODIFIED_STARTUP}`. diff --git a/docs/guides/disk-quotas/about.mdx b/docs/guides/disk-quotas/about.mdx new file mode 100644 index 00000000..18096552 --- /dev/null +++ b/docs/guides/disk-quotas/about.mdx @@ -0,0 +1,29 @@ +import Admonition from '@theme/Admonition'; +import Link from '@docusaurus/Link'; + +# About Quotas + + + As called out in the Wings install docs. It is always recommended to keep the server files on a separate partition. + + +## There are a lot of notices here for a reason! + + + Support for disk quotas is still being worked on! + + + + These are advanced configurations meant for hosts but "should" work for individuals as well. + + + + Depending on the filesystem Quotas can be difficult to enable for the `/` mount, which requires booting a live disk to change. + + + + You can either make a new mount with quotas enabled or enable quotas on an existing partition. + + +## Filesystem-specific docs +EXT4/XFS \ No newline at end of file diff --git a/docs/guides/disk-quotas/btrfs.mdx b/docs/guides/disk-quotas/btrfs.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/guides/disk-quotas/ext4-xfs.mdx b/docs/guides/disk-quotas/ext4-xfs.mdx new file mode 100644 index 00000000..fdc3eedd --- /dev/null +++ b/docs/guides/disk-quotas/ext4-xfs.mdx @@ -0,0 +1,226 @@ +import Admonition from '@theme/Admonition'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import Link from '@docusaurus/Link'; + +# EXT4 and XFS + +This page covers disk quota management for EXT4/XFS. + +Both EXT4 and XFS use the built-in quota management services in linux. + + + Please read About Quotas before continuing + + +## Configure Filesystem +How to format and mount a device for use with quotas + +
+I understand the risks and Pelican is not Liable for anything that breaks + + + Enabling quotas for `/` is difficult, as it requires booting a live disk to change. + + This is not recommended! + + +These examples use the following: +`/dev/sdb` as the device formatted as EXT4 enabling only project quotas. +`/var/lib/pelican/volumes/` as the mount point and data directory + + + + ## Format Device + `mkfs.ext4` will format the disk with the ext4 filesystem + * The `O` flag is the enable Feature Options + - enable quotas while formatting + * The `E` flag is for Extended Options + - set the quota type as project + ```bash + mkfs.ext4 -O quota -E quotatype=prjquota /dev/sdb + ``` + + + You need to update fstab so the disk mounts automatically on boot with quotas enabled. + + + ## Add to fstab + ### get device UUID + The disk UUID is the best option for mounting the correct device via fstab. + ```bash + lsblk /dev/sdb -no UUID + # example output + 6c3b1734-3db4-4368-9bee-58651731b206 + ``` + + ### add new mount to fstab + ```shell title="/etc/fstab" {4} + # + # / was on /dev/sda1 during installation + UUID=8529a07b-28bc-4296-848a-a185aaf11e94 / ext4 errors=remount-ro 0 1 + UUID=6c3b1734-3db4-4368-9bee-58651731b206 /var/lib/pelican/volumes/ ext4 defaults,prjquota 0 1 + ``` + For more information on fstab check the [Arch Linux fstab docs](https://wiki.archlinux.org/title/Fstab) + + + Depending on the OS you may need to refresh services to be able to mount the partition after updating `fstab`. + + It is often easier to reboot and have the disk mount on boot. + + + + ## Update existing partition + Get the disk device path and uuid for your partition + + by default `findmnt` lists all mounts on the system and lists their source, fstype, and options + * The `n` flag disables headers + * The `o` flag only returns specified values + - `SOURCE` is device path + - `UUID` is the device id + ```bash + findmnt /var/lib/pelican/volumes -no SOURCE,UUID + ## example response + /dev/sdb 6c3b1734-3db4-4368-9bee-58651731b206 + ``` + + ## Unmount disk + Use `umount` to unmount the pelican volume mount. + ```bash + umount /var/lib/pelican/volumes/ + ``` + + ## Enable quotas + + This can only be ran on an unmounted disk + + `tune2fs` is used to adjust tunable file system parameters for EXT filesystems + * The `Q` flag is to manage quotas + - `prjquota` is to enable project quotas + * The device path is needed + ```bash + tune2fs -Q prjquota /dev/sdb + ``` + + ## update fstab entry + add `prjquota` to the line for the mount + from + ```shell title="/etc/fstab" + UUID=6c3b1734-3db4-4368-9bee-58651731b206 /var/lib/pelican/volumes/ ext4 defaults 0 1 + ``` + to + ```shell title="/etc/fstab" + UUID=6c3b1734-3db4-4368-9bee-58651731b206 /var/lib/pelican/volumes/ ext4 defaults,prjquota 0 1 + ``` + For more information on fstab check the [Arch Linux fstab docs](https://wiki.archlinux.org/title/Fstab) + + + Depending on the OS you may need to refresh services to be able to mount the partition after updating `fstab`. + + It is often easier to reboot and have the disk mount on boot. + + + +
+ +## Advanced EXT4 Quota Management + + The following section is for manual management of quotas. + + +
+I understand + + You should never need to go here, this is your last warning. + +
+I agree and Pelican is not Liable for anything that breaks + +## Manually Manage Quotas +Limits for the servers are managed on a "project" level so they can be assigned per-directory. + +### Add A New Project +To add a new project, 2 files must be edited. + +First is the `projid` file which is formatted where each line is in the `project_name:project_id` format as seen below +* Pelican will use the server UUID as the project name +* Make sure the ID is not already being used. +```shell title="/etc/projid" +235844d3-9258-4846-bb04-bcff209ccf9a:1 +b91d5528-d53f-4586-8d5c-682027f74a36:2 +``` + +Second is the `projects` file which is formatted where each line is in the `project_id:path_to_directory` format as seen below +```shell title="/etc/projects" +1:/var/lib/pelican/volumes/235844d3-9258-4846-bb04-bcff209ccf9a +2:/var/lib/pelican/volumes/b91d5528-d53f-4586-8d5c-682027f74a36 +``` + +### Set directory attributes +The project attribute must be set on the directory to track quota usage. + +The `chattr` command changes attribute for files and directories. +* The `+` and `-` operators add or remove attributes + - The `P` makes it so files and directories created in the directory will inherit the project id of the directory. + - The project id and directory must match +* The `p` flag is for the project id +```bash +chattr +P -p ${project_id} ${path_to_directory} +``` + +Example: +```bash +chattr +P -p 1 /var/lib/pelican/volumes/235844d3-9258-4846-bb04-bcff209ccf9a +``` + +### set quota limits +The built-in quota management uses blocks by default. +* You can specify limits in bytes as well. + +The `setquota` command sets the quota for any object that supports quotas. +* The `P` flag sets the quota for a project + - This can use the project `id` or `name` + - This should be the server UUID as shown in the examples below +* The soft limit would send a warning to a user + - This is not used by Pelican and will be set to 0 +* The hard limit is set to the disk resource limit set in the Pelican +* Neither the block or inode/file grace sections will be used by the Pelican +* The path for either the device or the mount point + - `/dev/sdb/` or `/var/lib/pelican/volumes/` +```bash +setquota -P ${server_uuid} ${soft_limit} ${hard_limit} ${block_grace} ${inode_grace} ${path} +``` + +Example: +setting a hard limit, in Gigabytes +```bash +setquota -P 235844d3-9258-4846-bb04-bcff209ccf9a 0 10G 0 0 /var/lib/pelican/volumes/ +``` + +### get quota stats +The `repquota` command will generate a report on the quotas for the specified device or mount path +* The `P` flag will break down the report by project. + - In this case it should be the server UUID that is the project name +* The `--human-readable` flag sets the limits to be displayed in a human-readable format. By default that is Megabytes + - `=g,g` changes the output to be in Gigabytes (can be `k`, `g`, `m`, or `t`) + +Example: +```bash +repquota -P --human-readable=g,g /var/lib/pelican/volumes/ # could also be /dev/sdb +``` + +Example Output +```shell + Block limits File limits +Project used soft hard grace used soft hard grace +---------------------------------------------------------------------- +235844d3-9258-4846-bb04-bcff209ccf9 -- 3G 0G 5G 1g 0g 0g +cdb26bbb-963d-44b1-8353-360243032b1 -- 2G 0G 2G 1g 0g 0g +``` + +
+
+ + + TODO: Add documentation specifically for XFS + \ No newline at end of file diff --git a/docs/guides/disk-quotas/lvm.mdx b/docs/guides/disk-quotas/lvm.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/guides/disk-quotas/zfs.mdx b/docs/guides/disk-quotas/zfs.mdx new file mode 100644 index 00000000..e69de29b diff --git a/docs/guides/php-upgrade.mdx b/docs/guides/php-upgrade.mdx index 9b32880b..00a7ec3a 100644 --- a/docs/guides/php-upgrade.mdx +++ b/docs/guides/php-upgrade.mdx @@ -10,13 +10,13 @@ import TabItem from '@theme/TabItem'; This documentation includes instructions for upgrading your system to the latest version of PHP. Please reference the table below to check what PHP version you need for your version of Pelican. -| Panel Version | PHP Version | -|---------------|---------------| -| 1.0.0+ | 8.2, 8.3, 8.4 | +| Panel Version | PHP Version | +|---------------|--------------------| +| 1.0.0+ | 8.2, 8.3, 8.4, 8.5 | ## Install PHP -In order to install PHP 8.4, you will need to run the following commands. Please keep in mind different operating systems +In order to install PHP 8.5, you will need to run the following commands. Please keep in mind different operating systems may have slightly different requirements for how this commands are formatted. ```bash @@ -27,22 +27,22 @@ sudo apt -y update # Optional: Remove old PHP versions sudo apt -y purge php* -# Install PHP 8.4 -sudo apt -y install php8.4 php8.4-{gd,mysql,mbstring,bcmath,xml,curl,zip,intl,sqlite3,fpm} +# Install PHP 8.5 +sudo apt -y install php8.5 php8.5-{gd,mysql,mbstring,bcmath,xml,curl,zip,intl,sqlite3,fpm} ``` ## Webserver Configuration - After upgrading to PHP 8.4, you will most likely need to update your NGINX configuration. Your configuration file + After upgrading to PHP 8.5, you will most likely need to update your NGINX configuration. Your configuration file is most likely called `pelican.conf` and located in the `/etc/nginx/sites-available/` directory, or if on CentOS, `/etc/nginx/conf.d/`. Make sure to update the path in the command below to reflect the actual location of your configuration file. ``` bash - sed -i -e 's/php[7|8].[0-9]-fpm.sock/php8.4-fpm.sock/' /etc/nginx/sites-available/pelican.conf + sed -i -e 's/php[7|8].[0-9]-fpm.sock/php8.5-fpm.sock/' /etc/nginx/sites-available/pelican.conf ``` Once you have edited the file run the command below to reload NGINX and apply your changes. @@ -52,21 +52,21 @@ sudo apt -y install php8.4 php8.4-{gd,mysql,mbstring,bcmath,xml,curl,zip,intl,sq ``` - Run the commands below to disable all previous PHP versions and enable PHP 8.4 when serving requests. + Run the commands below to disable all previous PHP versions and enable PHP 8.5 when serving requests. ``` bash a2dismod php* - a2enmod php8.4 + a2enmod php8.5 ``` - After upgrading to PHP 8.4, you will most likely need to update your Caddy configuration. Your configuration file + After upgrading to PHP 8.5, you will most likely need to update your Caddy configuration. Your configuration file is most likely called `Caddyfile` and located in the `/etc/caddy/` directory. Make sure to update the path in the command below to reflect the actual location of your configuration file. ``` bash - sed -i -e 's/php[7|8].[0-9]-fpm.sock/php8.4-fpm.sock/' /etc/caddy/Caddyfile + sed -i -e 's/php[7|8].[0-9]-fpm.sock/php8.5-fpm.sock/' /etc/caddy/Caddyfile ``` Once you have edited the file run the command below to restart Caddy and apply your changes. diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index 06fc0aee..57ec5253 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -207,6 +207,34 @@ This means you need to prefix view-strings with your plugin id, e.g. `myplugin:: If present, a seeder with the name of your plugin will be automatically registered. It needs to be named `Seeder` (e.g. `MyPluginSeeder`) and put inside your plugins `database/Seeder` folder, e.g. `plugins/myplugin/database/Seeder/MyPluginSeeder.php`. This seeder will be automatically called when a user installs the plugin or when seeders are run in general, e.g. when using `php artisan db:seed` or `php artisan migrate --seed`. +### Routes + +Routes need to be registered in a `RouteServiceProvider`. Example: + +```php +use Illuminate\Foundation\Support\Providers\RouteServiceProvider; + +class MyPluginRoutesProvider extends RouteServiceProvider +{ + public function boot(): void + { + $this->routes(function () { + // Single new endpoint with Controller + Route::get('test', [TestController::class, 'test'])->name('my-plugin.test'); + + // Load routes from file + Route::prefix('/my-plugin')->group(plugin_path('my-plugin', 'routes/web.php')); + + // Add routes from file to existing client api + Route::middleware(['api', 'client-api', 'throttle:api.client']) + ->prefix('/api/client') + ->scopeBindings() + ->group(plugin_path('my-plugin', 'routes/api-client.php')); + }); + } +} +``` + ### Plugin Settings Your main plugin class can implement the `HasPluginSettings` interface to conveniently add a settings page to your plugin. @@ -342,4 +370,4 @@ And that's it! Now you can take the zip file and share it with the world! You can license your plugin code under whatever license you want. You do not have to use the same license as the panel! You also don't have to open source your plugin code. But if you do want to open source it we recommend [MIT](https://choosealicense.com/licenses/mit) or [GPL v3](https://choosealicense.com/licenses/gpl-3.0) as license. - \ No newline at end of file + diff --git a/docs/panel/getting-started.mdx b/docs/panel/getting-started.mdx index 40d79a48..0c4ba7a2 100644 --- a/docs/panel/getting-started.mdx +++ b/docs/panel/getting-started.mdx @@ -45,7 +45,7 @@ SQLite support depends on [libsqlite3-0_3.35+](https://pkgs.org/download/libsqli ### Dependencies -For the Panel you need to install **PHP `8.4` (recommended), `8.3` or `8.2`**, with the following **extensions**: +For the Panel you need to install **PHP `8.5` (recommended), `8.4`, `8.3` or `8.2`**, with the following **extensions**: `gd`, `mysql`, `mbstring`, `bcmath`, `xml`, `curl`, `zip`, `intl`, `sqlite3` and `fpm`. You will also need a Webserver. Currently, **Apache, NGINX or Caddy** are supported. diff --git a/docs/panel/panel-setup.mdx b/docs/panel/panel-setup.mdx index 4dcb5def..f780d22c 100644 --- a/docs/panel/panel-setup.mdx +++ b/docs/panel/panel-setup.mdx @@ -10,7 +10,7 @@ These steps will cover setting up things such as sessions, caching, database cre Running `php artisan p:environment:setup` will, if it does not exist, auto create the required `.env` file and generate a `APP_KEY`. ```sh -php artisan p:environment:setup +sudo php artisan p:environment:setup ``` diff --git a/docs/panel/update.mdx b/docs/panel/update.mdx index f544a38c..ed7058d4 100644 --- a/docs/panel/update.mdx +++ b/docs/panel/update.mdx @@ -12,9 +12,9 @@ Each version of Pelican Panel also has a corresponding minimum version of Wings Please see the chart below for how these versions line up. -| Panel Version | Wings Version | Supported | PHP Version | -|:-------------:|:-------------:|:---------:|:-----------:| -| 1.x | 1.x | ✅︎ | 8.2/8.3/8.4 | +| Panel Version | Wings Version | Supported | PHP Version | +|:-------------:|:-------------:|:---------:|:---------------:| +| 1.x | 1.x | ✅︎ | 8.2/8.3/8.4/8.5 | ## Updating diff --git a/docs/panel/webserver-config.mdx b/docs/panel/webserver-config.mdx index 8a5cbe70..c1919430 100644 --- a/docs/panel/webserver-config.mdx +++ b/docs/panel/webserver-config.mdx @@ -12,7 +12,7 @@ import TabItem from '@theme/TabItem'; - If you're **not** using php8.4, you will need to edit the config file to point to the proper php fpm socket. + If you're **not** using php8.5, you will need to edit the config file to point to the proper php fpm socket. The line is highlighted below. @@ -75,7 +75,7 @@ import TabItem from '@theme/TabItem'; location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass unix:/run/php/php8.4-fpm.sock; + fastcgi_pass unix:/run/php/php8.5-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M"; @@ -125,7 +125,7 @@ import TabItem from '@theme/TabItem'; location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass unix:/run/php/php8.4-fpm.sock; + fastcgi_pass unix:/run/php/php8.5-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M"; @@ -230,7 +230,7 @@ import TabItem from '@theme/TabItem'; Once you've created the file above, simply run the commands below. - If you're **not** using php8.4, you will need to edit the command to point to enable the correct mod. + If you're **not** using php8.5, you will need to edit the command to point to enable the correct mod. The line is highlighted below. @@ -238,7 +238,7 @@ import TabItem from '@theme/TabItem'; ```sh {3} sudo a2ensite pelican.conf sudo a2enmod rewrite - sudo a2enmod php8.4 + sudo a2enmod php8.5 ``` #### You need to restart apache to load the new config file. @@ -250,7 +250,7 @@ import TabItem from '@theme/TabItem'; - If you're **not** using php8.4, you will need to edit the config file to point to the proper php fpm socket. + If you're **not** using php8.5, you will need to edit the config file to point to the proper php fpm socket. The line is highlighted below. @@ -281,7 +281,7 @@ import TabItem from '@theme/TabItem'; file_server - php_fastcgi unix//run/php/php8.4-fpm.sock { + php_fastcgi unix//run/php/php8.5-fpm.sock { root /var/www/pelican/public index index.php @@ -334,7 +334,7 @@ import TabItem from '@theme/TabItem'; file_server - php_fastcgi unix//run/php/php8.4-fpm.sock { + php_fastcgi unix//run/php/php8.5-fpm.sock { root /var/www/pelican/public index index.php diff --git a/docs/wings/install.mdx b/docs/wings/install.mdx index aac6adcb..3bbb8938 100644 --- a/docs/wings/install.mdx +++ b/docs/wings/install.mdx @@ -6,6 +6,11 @@ import Admonition from '@theme/Admonition'; This software will not work on Windows operating systems. + + It is always recommended to keep the server files on a separate partition. + This prevents the root partition from filling and causing the host to crash, potentially becoming unbootable. + + ## Supported Systems The following is a list of supported operating systems. Please be aware that this is not an exhaustive list, @@ -83,7 +88,7 @@ Alternatively, you can click on the Auto Deploy Command button, copy the sh comm If your Panel is using SSL, then Wings must also use SSL. - See [Creating SSL Certificates](../guides/ssl) documentation page for how to create these certificates before continuing. + See [Creating SSL Certificates](./../guides/ssl) documentation page for how to create these certificates before continuing. ### Starting Wings diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 41cae8fa..f287159d 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -108,7 +108,9 @@ const config: Config = { "ini", "sql", "yaml", + "docker", "php", + "docker" ], }, } satisfies Preset.ThemeConfig, diff --git a/sidebars.ts b/sidebars.ts index 6d8c5777..c5b00466 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -45,6 +45,14 @@ const sidebars: SidebarsConfig = { 'wings/update' ], }, + { + type: 'category', + label: 'Eggs', + items: [ + 'eggs/creating-a-custom-egg', + 'eggs/creating-a-custom-yolk', + ], + }, { type: 'category', label: 'Guides', @@ -56,6 +64,15 @@ const sidebars: SidebarsConfig = { 'guides/database-hosts', 'guides/change-panel-domain', 'guides/uninstalling', + + { + type: 'category', + label: 'Disk Quotas', + items: [ + 'guides/disk-quotas/about', + 'guides/disk-quotas/ext4-xfs', + ] + } ], }, 'troubleshooting', diff --git a/src/css/custom.scss b/src/css/custom.scss index 3545dec1..5e1144d0 100644 --- a/src/css/custom.scss +++ b/src/css/custom.scss @@ -19,6 +19,9 @@ --ifm-color-info-lighter: rgb(186, 230, 253); --ifm-color-info-lightest: rgb(240, 249, 255); + --ifm-container-width-xl: 1600px; + --ifm-container-width: 1280px; + --ifm-code-font-size: 95%; }