From 4c20ff324d95cf800eda6f15dea042c635aaec2f Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Mon, 19 Aug 2024 23:43:29 +0100 Subject: [PATCH] Add experimental official Docker support via a Dockerfile :D Ref Dockerfile and docs/04-Getting-Started.md --- Changelog.md | 2 + Dockerfile | 29 +++++++ README.md | 8 +- build.sh | 13 +++ docker/Caddyfile | 13 +++ docker/run.sh | 19 +++++ docs/04-Getting-Started.md | 165 ++++++++++++++++++++++++++++++++++++- 7 files changed, 242 insertions(+), 7 deletions(-) create mode 100644 Dockerfile create mode 100644 docker/Caddyfile create mode 100644 docker/run.sh diff --git a/Changelog.md b/Changelog.md index e91e0d0..bfeb389 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,8 @@ This file holds the changelog for Pepperminty Wiki. This is the master list of t ## v0.25-dev (unreleased) This is the next release of Pepperminty Wiki, that hasn't been released yet. +- **Added:** Added official (experimental) Docker support via [a Dockerfile](https://github.com/sbrl/Pepperminty-Wiki/blob/master/Dockerfile)! Check out the [*Docker* section in Getting Started page of the docs](https://starbeamrainbowlabs.com/labs/peppermint/__nightdocs/04-Getting-Started.html#docker) (`docs/04-Getting-Started.md`) for more information. + - Community assistance is requested to a) check this documentation works for you and b) add documentation for other setups - e.g. Docker Compose, Kubernetes, Docker Swarm, etc. Please [open those pull requests](https://github.com/sbrl/Pepperminty-Wiki/pulls) :-) - **Fixed:** Fixed link to the interwiki links documentation on the help page if interwiki links have not yet been setup. - **Fixed:** Fixed typos in system text - **Fixed:** Fixed handling of [`firstrun_complete`](https://starbeamrainbowlabs.com/labs/peppermint/peppermint-config-info.php#config_firstrun_complete) setting if `peppermint.json` is prefilled with a `firstrun_complete` directive but the Wiki hasn't been initialised for the first time yet - useful for installations inside Docker diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..03ccf50 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM caddy:alpine + +RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \ + apk add --no-cache php84-fpm php84-mbstring php84-pecl-imagick php84-fileinfo php84-zip php84-intl php84-pdo_sqlite php84-sqlite3 php84-session && \ + mkdir /srv/app && \ + chown 10801:10801 /var/log/php84 /srv/app && \ + echo -e "[www]\ncatch_workers_output = yes\naccess.log = /proc/self/fd/2\nphp_admin_value[error_log] = /proc/self/fd/2" >/etc/php84/php-fpm.d/peppermint.conf + +COPY docker/Caddyfile /etc/caddy/Caddyfile +COPY build/index.php /srv/app/ +COPY docker/run.sh /srv/ + +# /srv/app/peppermint.json needs to be your peppermint.json file. +# IMPORTANT: Set data_storage_dir to /srv/data! +# See also https://starbeamrainbowlabs.com/labs/peppermint/peppermint-config-info.php#config_data_storage_dir +# To generate the peppermint.json file in the first place, you'll have to setup a temporary instance of Pepperminty Wiki (even just using e.g. php -S [::]:35623 -t build after cloning the git repository.) +# +# Alternatively, you can fill peppermint.json with simply e.g. '{ "data_storage_dir": "/srv/data", "firstrun_complete": false }' (omit single quotes), and then mount that writably, and Pepperminty Wiki will fill out the rest of the missing settings. +VOLUME [ "/srv/data" ] + +EXPOSE 80 + +# Pepperminty Wiki runs as user UID 10801 and GID 10801. +# Remember: Running any docker apps as root -- even inside the container -- is a terriible idea and leaves you liable to security issues! +USER 10801:10801 +WORKDIR /srv/app + +# Start PHP-FPM and Caddy via a script +CMD ["sh", "/srv/run.sh"] diff --git a/README.md b/README.md index da22350..5d25aa8 100644 --- a/README.md +++ b/README.md @@ -56,15 +56,11 @@ Here's a list of things that I want to add at some point (please feel free to [s - (See more on the [issue tracker](https://github.com/sbrl/Pepperminty-Wiki/issues)!) - ...? -Is the feature you want to see not on this list or not implemented yet? [Open an issue](https://github.com/sbrl/Pepperminty-Wiki/issues/new) or [send a pull request](https://github.com/sbrl/Pepperminty-Wiki/pulls) - contributions welcome! +Is the feature you want to see not on this list or not implemented yet? [Open an issue](https://github.com/sbrl/Pepperminty-Wiki/issues/new) or [open a pull request](https://github.com/sbrl/Pepperminty-Wiki/pulls) - contributions welcome! ## Docker -The recommended way of running Pepperminty Wiki is with a plain PHP-enabled web server. However, a docker container is generously provided by @SQL-enwiki. You can run it like so: - -```bash -docker run -d sqlatenwiki/peppermintywiki:stable -``` +The recommended way of running Pepperminty Wiki is with a plain PHP-enabled web server. However, a Dockerfile is available in this repository. Instructions for building it are available on the [Getting Started page](https://starbeamrainbowlabs.com/labs/peppermint/__nightdocs/04-Getting-Started.html#Docker) in the official documentation (see above). ## Security diff --git a/build.sh b/build.sh index 2448572..8f86839 100755 --- a/build.sh +++ b/build.sh @@ -38,6 +38,7 @@ if [[ "$#" -lt 1 ]]; then echo -e "${CSECTION}Available actions${RS}"; echo -e " ${CACTION}setup${RS} - Perform initial setup, check the environment (skip if only building Pepperminty Wiki itself)"; echo -e " ${CACTION}build${RS} - Build Pepperminty Wiki"; + echo -e " ${CACTION}docker${RS} - Build the Docker image"; echo -e " ${CACTION}themes${RS} - Rebuild the theme index"; echo -e " ${CACTION}docs${RS} - Build the documentation"; echo -e " ${CACTION}docs-livereload${RS} - Start the documentation livereload server"; @@ -119,6 +120,18 @@ task_build() { task_end $?; } +task_docker() { + task_build; + + task_begin "Building Docker image"; + if [[ -n "${DO_DOCKER_SUDO}" ]]; then + sudo docker build --tag pepperminty-wiki .; + else + docker build --tag pepperminty-wiki .; + fi + task_end "$?" "Failed to build Docker image"; +} + task_themes() { if [[ ! -f "${server_pid_file}" ]]; then NO_BROWSER=true tasks_run start-server; diff --git a/docker/Caddyfile b/docker/Caddyfile new file mode 100644 index 0000000..c045688 --- /dev/null +++ b/docker/Caddyfile @@ -0,0 +1,13 @@ +{ + admin off +} + +:80 { + @blocked { + path *peppermint.json + } + root * /srv/app + respond @blocked 403 + file_server + php_fastcgi 127.0.0.1:9000 +} diff --git a/docker/run.sh b/docker/run.sh new file mode 100644 index 0000000..ada2570 --- /dev/null +++ b/docker/run.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +# Output version numbers of stuff +echo ">>> php-fpm84 -v"; +php-fpm84 -v +echo ">>> caddy --version"; +caddy --version + +echo ">>> DEBUG:php-fpm peppermint conf"; +cat /etc/php84/php-fpm.d/peppermint.conf + +# Start php-fpm +echo ">>> php-fpm84 -F &"; +php-fpm84 -F & + +# Empirical testing reveals that this *should* keep both running +echo ">>> exec caddy run --config /etc/caddy/Caddyfile --adapter caddyfile"; +exec caddy run --config /etc/caddy/Caddyfile --adapter caddyfile + diff --git a/docs/04-Getting-Started.md b/docs/04-Getting-Started.md index 1bde0e7..212080e 100644 --- a/docs/04-Getting-Started.md +++ b/docs/04-Getting-Started.md @@ -3,16 +3,19 @@ ## System Requirements - PHP-enabled web-server (must be at least PHP 7+; only versions of PHP that are [officially supported](https://www.php.net/supported-versions.php) are supported by Pepperminty Wiki) - PHP session support (for logging in, see [here](https://php.net/manual/en/session.installation.php) for more information) + - Alpine Linux users: install e.g. `php84-session` - The following PHP extensions: - `mbstring` (for utf8 string handling - currently **required**) - `imagick` (for preview generation) - `fileinfo` (for proper mime type checking of uploaded files) - `zip` (for compressing exports) - `intl` (for Unicode text normalization when searching and in the id index, and when sending emails when utf-8 mode is disabled) - - `sqlite3` (for search index storage; uses [PDO](https://www.php.net/manual/en/ref.pdo-sqlite.php)) + - `pdo_sqlite3` (for search index storage; uses [PDO](https://www.php.net/manual/en/ref.pdo-sqlite.php)) \*\* - Write access to Pepperminty Wiki's own folder (only for editing and first run) - Recommended: Block access to `peppermint.json`, where it stores it's settings (including passwords!) +**\*\* Note for Alpine Linux users:** That means `pdo_sqlite`! i.e. from [`php84-pdo_sqlite`](http://dl-cdn.alpinelinux.org/alpine/edge/testing/x86_64/php84-pdo_sqlite-8.4.0_beta3-r0.apk) from Alpine's testing repository, ref `php -m` inside an alpine Docker container and [this post](https://devcoops.com/install-php-mbstring-on-alpine-linux/) + ## Setup Instructions 1. Once you've ensured your web server meets the requirements, obtain a copy of Pepperminty Wiki (see _[Getting a copy](05-Getting-A-Copy.html)_). @@ -136,3 +139,163 @@ echo -e "4\nsave\n" | gpg --batch --expert --command-fd 0 --edit-key "C2F7843F9A ``` Then, simply re-run the GPG verification command above to see the difference. + +## Docker +The recommended way of running Pepperminty Wiki is with a plain PHP-enabled web server. However, a Dockerfile is available in Pepperminty Wiki's git repository. + +**Warning:** Installing Pepperminty Wiki with Docker is somewhat complicated, involving multiple steps. If this seems scary to you, it is recomended you use a plain PHP-enabled web server as described above. + +**If you do not want to use Docker, you can skip the rest of this page and move onto the next one.** + +This said, there are 4 steps to getting Pepperminty Wiki running in a Docker container: + +1. Building the Docker container +2. Creating the file structure +3. Starting the Docker container +4. Completing the first run wizard + +This guide will assume a plain Docker container running on a generic Linux box that has Docker installed. Of course, you can adapt this to container orchestration setups (e.g. Kubernetes, Docker Swarm, etc ~~[Nomad](https://www.infoq.com/news/2023/08/hashicorp-adopts-bsl/)~~ nope, the BSL license is bad). + +If you do adapt it, please do open a pull request to update this guide with your instructions! + + +### Building the Docker container +Start by `cd`ing to a nice directory and cloning the Pepperminty Wiki git repository: + +```bash +git clone https://github.com/sbrl/Pepperminty-Wiki.git +cd Pepperminty-Wiki; +``` + +Now, check out the git tag you want to build, if any. Stay as-is to build the latest development version. + +Next, we simply use the `build.sh` script like so: + +```bash +./build.sh docker +``` + +....this will build Pepperminty Wiki in the background, so it requires a working PHP install (no FPM required, only uses the CLI) with the `zip` PHP extension available. + +Once done, it will create a new Docker image with the tag `pepperminty-wiki`. + +You are now free to delete the cloned git repository, but it is advised to update regularly. If you are planning to script the update of the Docker container, the format of the giit tags can be relied upon. + +- The latest git tag will be either the latest release or the latest beta/pre release +- Release tags look like this (replacing the version/hotfix numbers of course): + - `v0.20` + - `v0.20.2-hotfix2` + - `v0.20.3` +- Beta release tags look like this: + - `v0.19-beta2` + +### Creating the file structure +Traditionally, Pepperminty Wiki keeps everything in a single directory, but in a Docker container is most likely desirable to keep the wiki data in a separate directory. Pepperminty Wiki supports this mode of operation through the [`data_storage_dir` configuration directive](https://starbeamrainbowlabs.com/labs/peppermint/peppermint-config-info.php#config_data_storage_dir) in `peppermint.json` - which it is also recommended to change if [`require_login_view`](https://starbeamrainbowlabs.com/labs/peppermint/peppermint-config-info.php#config_require_login_view) is set to true to avoid leaks. + +To this end, there are 2 things we need to do here. + +First, create an empty directory for Pepperminty Wiki to store your wiki data in, and `chown` it to `10801:10801` (UID:GID), since Pepperminty Wiki will bbe running under this user/group id combination inside the Docker container to improve security. + +```bash +mkdir path/to/directory +sudo chown 10801:10801 path/to/directory +``` + +Then, create `peppermint.json` and prefill it with the following contents: + +```bash +{ "data_storage_dir": "/srv/data", "firstrun_complete": false } +``` + +....the `data_storage_dir` here is INSIDE the container, not outside! The `"firstrun_complete": false` is required to show the firstrun installer. + +Then, set the permissions on `peppermint.json`: + +```bash +chmod 0600 path/to/peppermint.json +sudo chown 10801:10801 path/to/peppermint.json +``` + +**Note:** This method only works for Pepperminty Wiki v0.25 or above. Specifically, you MUST have commit [`c4f6ef2`](https://github.com/sbrl/Pepperminty-Wiki/commit/c4f6ef2c58afb291f3fb6e355eb0eeff00843cc5) (and [`9800c25`](https://github.com/sbrl/Pepperminty-Wiki/commit/9800c257de64774cc8e09e2a75f4de6a1dcb6ac2) immediately before it) for the firstrun wizard to correctly appear without editing `peppermint.json` a second time. + +### Starting the Docker container +Now that you have the Docker image built and the file structure setup correctly, you can start the Docker container itself. This is the Docker command required as if you were starting it in the terminal: + +```bash +docker run -it --rm -v /absolute/path/to/peppermint.json:/srv/app/peppermint.json --hostname peppermint -v /absolute/path/to/data:/srv/data pepperminty-wiki +``` + +...replacing: + +- `/absolute/path/to/peppermint.json` with the path to `peppermint.json`, and +- `/absolute/path/to/data` with the path to the wiki data directory you created earlier. + +...make sure that both of these paths are **absolute**, because otherwise you will experience issues because the Docker daemon that actually starts the Docker container does not know about your current working directory. + +It is also strongly advisable to avoid spaces in your directory paths. + +**Tip:** A simple solution to ensure the Docker container automatically restarts on reboot is to use [the `--restart always` argument](https://docs.docker.com/engine/containers/start-containers-automatically/#use-a-process-manager) to `docker run`. + +#### docker-compose +If you use Docker Compose, the following Docker Compose file may prove useful: + +```yaml +services: + pepperminty-wiki: + image: pepperminty-wiki + container_name: peppermint + volumes: + - /absolute/path/to/peppermint.json:/srv/app/peppermint.json + - /absolute/path/to/data:/srv/data +``` + +...replacing the source paths in `volumes` as previously described. + +Note that this Docker Compose file is untested. If this doesn't work for you, please open a pull request. + +### Completing the first run wizrd +Now that your Docker container is started, you should be able to navigate to it in your web browser to complete the first run wizard. + +Setups vary, but if you don't know the IP address of your shiny new Docker container, try this method: + +> First get the container ID: +> +> ```bash +> docker ps +> ``` +> +> (First column is for container ID) +> +> Use the container ID to run: +> +> ```bash +> docker inspect +> ``` +> +> At the bottom, under NetworkSettings, you can find \[the] IPAddress \[field] +> +> Or just do for UNIX based [operating systems]: +> +> ```bash +> docker inspect | grep "IPAddress" +> ``` + +_(Taken from [This StackOverflow Answer](https://stackoverflow.com/a/46310428/1460422))_ + +The Pepperminty Wiki Docker container always listens on port 80 for unencrypted HTTP requests, so enter something like the following IP address into your web browser: + +``` +http://172.17.0.3/ +``` + +**Note:** The IP address will vary depending on your network layout. It is important you put it behind another reverse proxy that handles HTTPS encryption if you want it to be world-readable. + +In your web browser, you should be presented with the first run wizard, which should tell you that all the PHP extensions needed are already installed. + +Fill this out as normal: + +- Pepperminty Wiki will add a `secret` field to Pepperminty Wiki - follow the on-screen instructions +- Put `/srv/data` into the "Data Storage Directory" field. +- Fill in all other fields as your needs require. + +Finally, press the "Create Wiki!" button to finish the first run wizard, and now use your wiki as normal. \ No newline at end of file