Skip to content

Instantly share code, notes, and snippets.

@glaszig
Last active July 14, 2026 07:31
Show Gist options
  • Select an option

  • Save glaszig/cf697eff7a1329421b4ae4d465168ecf to your computer and use it in GitHub Desktop.

Select an option

Save glaszig/cf697eff7a1329421b4ae4d465168ecf to your computer and use it in GitHub Desktop.
install piku on freebsd (preferably in a jail)
#!/usr/bin/env sh
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
# 0. You just DO WHAT THE FUCK YOU WANT TO.
set -e
set -x
export PIKU_USER=piku
pkg install -qy python uwsgitop git nginx-lite mime-support \
php82 php82-tokenizer php82-fileinfo php82-dom php82-iconv php82-pdo_sqlite php82-composer \
php82-simplexml php82-xmlwriter php82-xml php82-bcmath php82-zlib php82-xmlreader php82-zip
python_version=$(python -c "import sys; print(f'{sys.version_info.major}{sys.version_info.minor}')")
pkg install -qy py${python_version}-pip uwsgi-py${python_version}
pw usershow $PIKU_USER -q > /dev/null || pw useradd $PIKU_USER -m -c "piku user" -G www
mkdir -p /home/$PIKU_USER/.ssh
chown $PIKU_USER /home/$PIKU_USER/.ssh
chmod 700 /home/$PIKU_USER/.ssh
# download piku
su - $PIKU_USER -c "curl -sSLO https://raw.githubusercontent.com/piku/piku/master/piku.py && pip install click && python3 ~/piku.py setup"
# patch piku to have configurable plugins dir
cat << EOF | patch -sNu /home/$PIKU_USER/piku.py || true
--- piku.py 2025-08-18 05:22:22.596444000 +0000
+++ piku.py 2025-08-18 05:26:32.355605000 +0000
@@ -1159,6 +1159,7 @@
('logfile-chmod', '640'),
('logto2', '{log_file:s}.{ordinal:d}.log'.format(**locals())),
('log-backupname', '{log_file:s}.{ordinal:d}.log.old'.format(**locals())),
+ ('plugins-dir', environ.get('UWSGI_PLUGINS_DIR', '/usr/local/lib/uwsgi')),
]
# only add virtualenv to uwsgi if it's a real virtualenv
EOF
# patch piku to produce nginx proxy config that works with cascading proxies
sed -i '' 's/X-Forwarded-Proto \$scheme;/X-Forwarded-Proto \$http_x_forwarded_proto;/g' /home/$PIKU_USER/piku.py
sed -i '' 's/X-Forwarded-Port \$server_port;/X-Forwarded-Port \$http_x_forwarded_port;/g' /home/$PIKU_USER/piku.py
# patch piku to load the php plugin
sed -i '' "s/('plugin', 'http,0:php')/('plugin', 'http,0:php,router_rewrite')/g" /home/$PIKU_USER/piku.py
sed -i '' "s/('check-static', docroot),/('check-static', docroot),\n ('route', '.* rewrite:\/index.php'),/g" /home/$PIKU_USER/piku.py
chown $PIKU_USER:$(id -g $PIKU_USER) /home/$PIKU_USER/piku.py
chmod +x /home/$PIKU_USER/piku.py
echo "# managed by piku installer. changes will be overwritten." > /usr/local/etc/nginx/nginx.conf
echo "events { worker_connections 1024; }" >> /usr/local/etc/nginx/nginx.conf
echo "http {" >> /usr/local/etc/nginx/nginx.conf
curl -sSL https://github.com/piku/piku/raw/refs/heads/master/nginx.default.dist | sed '/listen \[::\]:80/d' >> /usr/local/etc/nginx/nginx.conf
echo "}" >> /usr/local/etc/nginx/nginx.conf
sysrc nginx_enable=YES
service nginx status > /dev/null || service nginx start
uwsgi_version=$(uwsgi --version)
[ ! -d uwsgi-${uwsgi_version} ] && curl -sSLo- https://github.com/unbit/uwsgi/archive/refs/tags/${uwsgi_version}.tar.gz | tar -xzf-
# patch uwsgi to make php's session ext work
cat << EOF | patch -sNud uwsgi-${uwsgi_version} || true
--- plugins/php/uwsgiplugin.py 2025-08-18 04:35:38.531340000 +0000
+++ plugins/php/uwsgiplugin.py 2025-08-18 01:08:20.277183000 +0000
@@ -31,5 +31,9 @@
phplibdir = os.environ.get('UWSGICONFIG_PHPLIBDIR')
if phplibdir:
LIBS.append('-Wl,-rpath,%s' % phplibdir)
+
+extdir = os.popen(PHPPATH + ' --extension-dir').read().rstrip()
+if extdir:
+ LDFLAGS.append('-Wl,-rpath=%s,-L%s,-l:session.so' % (extdir, extdir))
GCC_LIST = ['php_plugin', 'session']
EOF
if ! test -f /usr/local/lib/uwsgi/php_plugin.so; then
uwsgi --build-plugin uwsgi-${uwsgi_version}/plugins/php
mkdir -p /usr/local/lib/uwsgi
mv php_plugin.so /usr/local/lib/uwsgi/
fi
cat << EOF > /usr/local/etc/rc.d/uwsgi-piku
#!/bin/sh
#
# managed by piku installer. changes will be overwritten.
#
# PROVIDE: uwsgi-piku
# REQUIRE: DAEMON networking
# KEYWORD:
. /etc/rc.subr
name="uwsgi_piku"
rcvar="uwsgi_piku_enable"
: \${uwsgi_piku_enable:=NO}
: \${uwsgi_piku_pidfile:=/var/run/uwsgi-piku.pid}
command="/usr/local/bin/uwsgi"
command_args="--daemonize --ini \${uwsgi_piku_config} --pidfile \${uwsgi_piku_pidfile}"
pidfile="\${uwsgi_piku_pidfile}"
sig_stop="INT"
start_precmd="uwsgi_piku_prestart"
stop_postcmd="uwsgi_piku_poststop"
uwsgi_piku_prestart() {
if [ -z "\${uwsgi_piku_config}" ]; then
err 1 "uwsgi_piku_config must be set in rc.conf or rc.conf.d/"
fi
}
uwsgi_piku_poststop() {
rm -f "\${pidfile}"
}
run_rc_command "\$1"
EOF
chmod +x /usr/local/etc/rc.d/uwsgi-piku
sysrc uwsgi_enable=NO uwsgi_piku_enable=YES
sysrc uwsgi_piku_config="/home/piku/.piku/uwsgi/uwsgi.ini"
sysrc uwsgi_piku_flags="-L --mimefile /usr/local/etc/mime.types --plugins-dir /usr/local/lib/uwsgi"
service uwsgi-piku status > /dev/null || service uwsgi-piku start
cat << EOF > /usr/local/etc/rc.d/piku-watch
#!/bin/sh
#
# managed by piku installer. changes will be overwritten.
#
# PROVIDE: piku-watch
# REQUIRE: DAEMON networking
# KEYWORD:
. /etc/rc.subr
name="piku_watch"
rcvar="piku_watch_enable"
: \${piku_watch_enable:=no}
: \${piku_watch_trigger_cmd:="nginx -s reload"}
pidfile="/var/run/\${name}.pid"
sig_stop="INT"
command="/usr/sbin/daemon"
command_args="-P \${pidfile} -f -S /usr/local/bin/piku-watch \${piku_watch_dirs}"
run_rc_command "\$1"
EOF
chmod +x /usr/local/etc/rc.d/piku-watch
cat << EOF > /usr/local/bin/piku-watch
#!/usr/bin/env sh
fswatch -o \$@ | xargs -n1 nginx -s reload
EOF
chmod +x /usr/local/bin/piku-watch
sysrc piku_watch_enable=YES piku_watch_dirs=/home/$PIKU_USER/.piku/uwsgi-enabled/
service piku-watch start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment