From 94b8c779b6a0123729d2417e1a7dfa87986c6058 Mon Sep 17 00:00:00 2001 From: Yubao Liu Date: Tue, 29 Nov 2022 02:40:27 +0800 Subject: [PATCH] support Apache mod_fcgid/mod_proxy_fcgi and Nginx TODO: Actually mod_proxy_fcgi requires further manually configuration. Import from https://github.com/Dieken/foswiki-docker/commit/1fc4b8f71ba99ff1ba9fa3c0c0eb7ff98dcc3a80 --- docker/Dockerfile | 26 ++++-- docker/README.md | 28 ++++++- docker/{foswiki.conf => foswiki-apache.conf} | 26 +++++- docker/foswiki-nginx.conf | 87 ++++++++++++++++++++ docker/start.sh | 62 ++++++++++++++ 5 files changed, 216 insertions(+), 13 deletions(-) rename docker/{foswiki.conf => foswiki-apache.conf} (90%) create mode 100644 docker/foswiki-nginx.conf create mode 100755 docker/start.sh diff --git a/docker/Dockerfile b/docker/Dockerfile index 642939f67..539dc5f73 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,5 @@ -FROM debian:11 +ARG base=debian:11 +FROM $base ARG url=https://github.com/foswiki/distro/releases/download/FoswikiRelease02x01x07/Foswiki-2.1.7.tgz ARG sha512=7196ce5a586a3770e2d198a79d0856f34724893746a40500b7f72d3efc48dcbdfb0292a3583186cf4e5b217a70df3b5dd8af80aa3e5c34987ca202a62dada0bf @@ -16,7 +17,7 @@ RUN set -eux; \ [ -z "$mirror" ] || sed -i -E "s|http(s?)://deb.debian.org|$mirror|" /etc/apt/sources.list; \ apt update -y \ && apt install -y curl diffutils grep less logrotate vim w3m \ - apache2 libapache2-mod-perl2 \ + apache2 libapache2-mod-fcgid libapache2-mod-perl2 nginx \ libalgorithm-diff-perl \ libapache2-request-perl \ libarchive-zip-perl \ @@ -36,6 +37,7 @@ RUN set -eux; \ liberror-perl \ libfcgi-procmanager-perl \ libfile-copy-recursive-perl \ + libfile-mmagic-xs-perl \ libjson-perl \ liblocale-codes-perl \ liblocale-maketext-lexicon-perl \ @@ -43,10 +45,9 @@ RUN set -eux; \ && apt install -y --no-install-recommends \ libimage-magick-perl \ && rm -rf /var/lib/apt/lists/* \ - && a2enmod access_compat perl rewrite \ - && a2dissite 000-default - -COPY foswiki.conf /etc/apache2/sites-enabled/ + && a2enmod access_compat rewrite \ + && a2dissite 000-default \ + && rm /etc/nginx/sites-enabled/default RUN set -eux; \ mkdir -p $root \ @@ -58,10 +59,19 @@ RUN set -eux; \ && rm foswiki.tgz foswiki.tgz.sha512 \ && sh tools/fix_file_permissions.sh \ && chown -R $user:$group $root \ - && echo "0,30 * * * * cd $root/bin && perl ../tools/tick_foswiki.pl" | crontab -u $user - + && echo "0,30 * * * * cd $root/bin && perl ../tools/tick_foswiki.pl" | crontab -u $user - \ + && cp tools/foswiki.init-script /etc/init.d/foswiki \ + && chmod 755 /etc/init.d/foswiki \ + && update-rc.d foswiki defaults \ + && cp tools/foswiki.defaults /etc/default/foswiki \ + && chmod 644 /etc/default/foswiki + +COPY foswiki-apache.conf /etc/apache2/sites-enabled/foswiki.conf +COPY foswiki-nginx.conf /etc/nginx/sites-enabled/foswiki.conf +COPY start.sh /start.sh VOLUME $root EXPOSE $port -CMD ["/bin/sh", "-c", "service cron start && exec apache2ctl -DFOREGROUND -k start"] +CMD ["/bin/sh", "/start.sh"] diff --git a/docker/README.md b/docker/README.md index 338f50ab4..bdb111739 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,12 +1,11 @@ # Dockerfile for Foswiki -Run pristine Foswiki in Debian container with Apache 2 and mod_perl. +Run pristine Foswiki in Debian container with Apache 2 + mod_fcgid/mod_proxy_fcgi/mod_perl or Nginx. ## Build ```sh docker build . -t foswiki --progress plain - ``` Notice this Dockerfile uses volume for `/var/www/foswiki`. @@ -14,20 +13,39 @@ Notice this Dockerfile uses volume for `/var/www/foswiki`. ## Run ```sh +# Use Apache, may use `-e MODULE=[fcigd|proxy_fcgi|perl]` to choose different Apache module. +docker run -dt --init --name foswiki -p 8888:80 -e TZ=Asia/Shanghai -e HTTPD=apache foswiki + + +# Use Nginx docker run -dt --init --name foswiki -p 8888:80 -e TZ=Asia/Shanghai foswiki ``` Access http://localhost:8888 to further configure Foswiki: -1. http://localhost:8888/bin/configure Security and Authentication -> Registration: select `Enable User Registration` and click button `Save 1 change` on the top right corner +1. http://localhost:8888/bin/configure + 1. `Security and Authentication` -> `Registration`: select `Enable User Registration` + 2. `General settings` -> `File System Paths`: set `Safe PATH` to `/bin:/usr/bin` + 3. Click button `Save 2 changes` on the top right corner 2. http://localhost:8888/System/UserRegistration Register your first user, such as WikiName `FirstAdmin` 3. http://localhost:8888/Main/WikiGroups Click `Add Members...` in the group `AdminGroup`, add newly registered user's WikiName 4. Run `docker restart foswiki` to restart the Docker container Although you can directly access Foswiki in the container, this container is expected to be behind a reverse proxy that terminates HTTPS connections and handles virtual site, you must replace the hostname above to `https://your-reverse-proxy?SSL=1`. -## Install extension +## Extensions + +Highly recommended extension for Nginx: + +``` sh +su -s /bin/bash www-data +cd /var/www/foswiki +tools/extension_installer XSendFileContrib -r install +tools/configure -save -set '{XSendFileContrib}{Header}=X-Accel-Redirect' +tools/configure -save -set '{XSendFileContrib}{Location}=/files' +``` +Beautiful skin extension [NatSkin](https://foswiki.org/Extensions/NatSkin): ``` sh su -s /bin/bash www-data cd /var/www/foswiki @@ -41,4 +59,6 @@ Check https://foswiki.org/Extensions for more extensions. * https://github.com/timlegge/docker-foswiki * https://foswiki.org/System/InstallationGuide * https://foswiki.org/System/InstallationGuidePart2 +* https://foswiki.org/Support/FoswikiOnNginx +* https://foswiki.org/System/FastCGIEngineContrib#Nginx diff --git a/docker/foswiki.conf b/docker/foswiki-apache.conf similarity index 90% rename from docker/foswiki.conf rename to docker/foswiki-apache.conf index 1e48c424c..48ec00a46 100644 --- a/docker/foswiki.conf +++ b/docker/foswiki-apache.conf @@ -1,5 +1,6 @@ -# Autogenerated httpd.conf file for Foswiki. +# Merge autogenerated httpd.conf files for Foswiki. # Generated at https://foswiki.org/Support/ApacheConfigGenerator?vhost=;port=;dir=/var/www/foswiki;symlink=;pathurl=/;shorterurls=enabled;engine=mod_perl;fastcgimodule=fcgid;fcgidreqlen=;apver=2;confighost=;configip=;configuser=;loginmanager=Template;htpath=;errordocument=UserRegistration;errorcustom=;disablephp=on;blockpubhtml=on;blocktrashpub=on;controlattach=;blockspiders=on;foswikiversion=2.x;apacheversion=2.4;timeout=;ssl=;sslcert=/etc/ssl/apache2/yourservercert.pem;sslchain=/etc/ssl/apache2/sub.class1.server.ca.pem;sslkey=/etc/ssl/apache2/yourservercertkey.pem +# Generated at https://foswiki.org/Support/ApacheConfigGenerator?vhost=;port=;dir=/var/www/foswiki;symlink=;pathurl=/;shorterurls=enabled;engine=FastCGI;fastcgimodule=fcgid;fcgidreqlen=;apver=2;confighost=;configip=;configuser=;loginmanager=Template;htpath=;errordocument=UserRegistration;errorcustom=;disablephp=on;blockpubhtml=on;blocktrashpub=on;controlattach=;blockspiders=on;foswikiversion=2.x;apacheversion=2.4;timeout=;ssl=;sslcert=/etc/ssl/apache2/yourservercert.pem;sslchain=/etc/ssl/apache2/sub.class1.server.ca.pem;sslkey=/etc/ssl/apache2/yourservercertkey.pem # Configuration generated for Foswiki 2.x, Apache 2.4 @@ -10,7 +11,12 @@ Define foswikiroot "/var/www/foswiki" # http://my.co.uk/foswiki/bin/view/... # The second parameter must point to the physical path on your disc. + Alias /bin "${foswikiroot}/bin" + + +Alias /bin "${foswikiroot}/bin/foswiki.fcgi" + # The following Alias is used to access files in the pub directory (attachments etc) # It must come _after_ the ScriptAlias. @@ -34,7 +40,12 @@ RewriteEngine on # Alias /error/ "/usr/local/www/apache24/error/" # short urls + Alias / "${foswikiroot}/bin/view/" + + +Alias / "${foswikiroot}/bin/foswiki.fcgi/" + RewriteRule ^/+bin/+view/+(.*) /$1 [L,NE,R] RewriteRule ^/+bin/+view$ / [L,NE,R] @@ -56,6 +67,14 @@ SetEnvIf Request_URI "/pub/System/.*\.[hH][tT][mM][lL]?$" !blockAccess # mod_perl_startup.pl must exist, otherwise Apache will not start. PerlRequire "${foswikiroot}/tools/mod_perl_startup.pl" + + DefaultMaxClassProcessCount 3 + # Request length must be larger than largest ATTACHFILESIZELIMIT x 1024 + FcgidMaxRequestLen 52428800 + # Limit requests to control memory growth. + FcgidMaxRequestsPerProcess 400 + + # This specifies the options on the Foswiki scripts directory. The ExecCGI # and SetHandler tell apache that it contains scripts. "Allow from all" @@ -78,6 +97,11 @@ PerlRequire "${foswikiroot}/tools/mod_perl_startup.pl" SetHandler cgi-script + + + SetHandler fcgid-script + + # Password file for Foswiki users AuthUserFile "${foswikiroot}/data/.htpasswd" diff --git a/docker/foswiki-nginx.conf b/docker/foswiki-nginx.conf new file mode 100644 index 000000000..bd99aa26f --- /dev/null +++ b/docker/foswiki-nginx.conf @@ -0,0 +1,87 @@ +server { + listen 80 default_server; + listen [::]:80 default_server; + server_name _; + + set $foswiki_root /var/www/foswiki; # <=== Path to expanded foswiki distribution + root /var/www/html; + index index.html; + + #access_log /var/log/nginx/foswiki-access.log; + #error_log /var/log/nginx/foswiki-error.log debug; + + # Uncomment for htpasswd + #auth_basic "FOSWiki"; + #auth_basic_user_file $foswiki_root/data/.htpasswd; + + # raise upload limit (foswiki has its own limit : %ATTACHFILESIZELIMIT% in System/PreferenceSettings) + client_max_body_size 50M; + + # browsers tend to search for a favicons and robots.txt in the root directory: if it is there fine, if not don't bother + location /favicon.ico { + root $foswiki_root; + log_not_found off; + access_log off; + } + location /robots.txt { + root $foswiki_root; + allow all; + log_not_found off; + access_log off; + } + + location = / { + root $foswiki_root; + rewrite .* /Main/WebHome; + } + + # redirect short urls to view + location ~ ^/(?:bin/)?([A-Z_].*)$ { + rewrite ^/(.*)$ /bin/view/$1 last; + } + + # static files that we don't need to authenticate, i.e. css and js + location ~ ^/pub/(System|Applications|images|cache)/ { + root $foswiki_root; + expires 8h; + gzip_static on; + } + + # any other static files need to be sanctioned by the foswiki backened + location /pub { + # either by the standard viewfile approach ... + rewrite ^/pub/(.*)$ /bin/viewfile/$1; + + # or by XSendFileContrib using + # + # The following setting must be in LocalSite.cfg + # {XSendFileContrib}{Header} = 'X-Accel-Redirect'; + # {XSendFileContrib}{Location} = '/files'; + #rewrite ^/pub/(.*)$ /bin/xsendfile/$1; + } + + # internal location that sendfile serves sanctioned static files from + location /files { + internal; + alias $foswiki_root/pub/; + expires 8h; + access_log off; + } + + # deny any direct access to these directores + # note that this only is required in case the document root equals the $foswiki_root + location ~ (^/lib|^/data|^/locale|^/templates|^/tools|^/work) { + deny all; + } + + location ~ ^/bin/([a-z]+) { + gzip off; + # a request taking more than 2 minutes is considered an error + fastcgi_read_timeout 120s; + fastcgi_split_path_info ^/bin/(.+?)(/.*)$; + fastcgi_param SCRIPT_FILENAME $foswiki_root/bin/foswiki.fcgi; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_pass 127.0.0.1:9000; + include fastcgi_params; + } +} diff --git a/docker/start.sh b/docker/start.sh new file mode 100755 index 000000000..108edbcdc --- /dev/null +++ b/docker/start.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +set -eux + +service cron start + +httpd=${HTTPD:-nginx} +module=${MODULE:-fcgid} # for Apache only + +unset HTTPD MODULE # unset environment variables + +case "$httpd" in + apache) + case "$module" in + *fcgid) + a2enmod fcgid + a2dismod proxy_fcgi + a2dismod perl + ;; + + *proxy_fcgi) + a2enmod proxy_fcgi + a2dismod fcgid + a2dismod perl + + rm -f /var/run/foswiki.pid + service foswiki start + ;; + + *perl) + a2enmod perl + a2dismod fcgid + a2dismod proxy_fcgi + ;; + + *) + echo "ERROR: unknown engine $module" >&2 + exit 1 + esac + + exec apache2ctl -DFOREGROUND -k start + ;; + + nginx) + # Enable xsendfile in Nginx if XSendFileContrib is properly configured + foswiki_conf=/etc/nginx/sites-enabled/foswiki.conf + localsite_cfg=/var/www/foswiki/lib/LocalSite.cfg + if grep -q '^\s*#rewrite.*xsendfile' $foswiki_conf && + grep -q '{XSendFileContrib}{Header}\s*=\s*.X-Accel-Redirect.' $localsite_cfg && + grep -q '{XSendFileContrib}{Location}\s*=\s*./files.' $localsite_cfg; then + sed -i -E 's|^(\s*)(rewrite.*viewfile)|\1#\2|; s|^(\s*)#(rewrite.*sendfile)|\1\2|' $foswiki_conf + fi + + rm -f /var/run/foswiki.pid + service foswiki start + nginx -g "daemon off;" + ;; + + *) + echo "ERROR: unknown httpd $httpd" >&2 + exit 1 +esac