Skip to content

Commit

Permalink
Use nginx Unit rather than the php development server
Browse files Browse the repository at this point in the history
  • Loading branch information
shish committed Dec 16, 2023
1 parent f00a4e3 commit 282d13f
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 28 deletions.
10 changes: 8 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@
"target": "devcontainer"
},

"workspaceMount": "source=${localWorkspaceFolder},target=/app,type=bind",
"workspaceFolder": "/app",

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [8000],

// Uncomment the next line to run commands after the container is created.
"postCreateCommand": "cd /workspaces/shimmie2 && /usr/bin/php -S 0.0.0.0:8000 tests/router.php 2>&1 | grep --line-buffered -vE \" (Accepted|Closing)\"",

"postCreateCommand": "./.docker/entrypoint.sh unitd --no-daemon --control unix:/var/run/control.unit.sock",
"containerEnv": {
"UID": "2000",
"GID": "2000"
},
"customizations": {
"vscode": {
"extensions": [
Expand Down
76 changes: 76 additions & 0 deletions .docker/entrypoint.d/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"listeners": {
"*:8000": {
"pass": "routes",
"forwarded": {
"client_ip": "X-Forwarded-For",
"recursive": false,
"source": [
"172.17.0.0/16"
]
}
}
},
"routes": [
{
"match": {
"uri": "~/_(thumbs|images)/.*"
},
"action": {
"share": [
"`/app/data/${uri.replace(/_(thumbs|images)\\/(..)(..)(.*?)\\/.*/, '$1/$2/$3/$2$3$4')}`",
"`/app/data/${uri.replace(/_(thumbs|images)\\/(..)(.*?)\\/.*/, '$1/$2/$2$3')}`"
],
"response_headers": {
"Cache-Control": "public, max-age=31556926"
}
}
},
{
"action": {
"share": [
"/app/ext/static_files/static/$uri",
"/app/$uri"
],
"types": [
"image/*",
"application/javascript",
"text/css",
"!"
],
"response_headers": {
"Cache-Control": "public, max-age=31556926"
},
"fallback": {
"pass": "applications/shimmie"
}
}
}
],
"applications": {
"shimmie": {
"type": "php",
"user": "shimmie",
"root": "/app/",
"script": "index.php",
"working_directory": "/app/",
"options": {
"admin": {
"memory_limit": "256M",
"upload_max_filesize": "50M",
"post_max_size": "50M"
}
},
"processes": {
"max": 8,
"spare": 2,
"idle_timeout": 60
}
}
},
"settings": {
"http": {
"max_body_size": 104857600
}
}
}
106 changes: 106 additions & 0 deletions .docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/bin/sh

set -e

# if user shimmie doesn't already exist, create it
if ! id -u shimmie >/dev/null 2>&1; then
groupadd -g $GID shimmie || true
useradd -ms /bin/bash -u $UID -g $GID shimmie || true
fi
mkdir -p /app/data
chown shimmie:shimmie /app/data

rm -rf /var/lib/unit/*

WAITLOOPS=5
SLEEPSEC=1

curl_put()
{
RET=$(/usr/bin/curl -s -w '%{http_code}' -X PUT --data-binary @$1 --unix-socket /var/run/control.unit.sock http://localhost/$2)
RET_BODY=$(echo $RET | /bin/sed '$ s/...$//')
RET_STATUS=$(echo $RET | /usr/bin/tail -c 4)
if [ "$RET_STATUS" -ne "200" ]; then
echo "$0: Error: HTTP response status code is '$RET_STATUS'"
echo "$RET_BODY"
return 1
else
echo "$0: OK: HTTP response status code is '$RET_STATUS'"
echo "$RET_BODY"
fi
return 0
}

if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
if /usr/bin/find "/var/lib/unit/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
echo "$0: /var/lib/unit/ is not empty, skipping initial configuration..."
else
echo "$0: Launching Unit daemon to perform initial configuration..."
/usr/sbin/$1 --control unix:/var/run/control.unit.sock

for i in $(/usr/bin/seq $WAITLOOPS); do
if [ ! -S /var/run/control.unit.sock ]; then
echo "$0: Waiting for control socket to be created..."
/bin/sleep $SLEEPSEC
else
break
fi
done
# even when the control socket exists, it does not mean unit has finished initialisation
# this curl call will get a reply once unit is fully launched
/usr/bin/curl -s -X GET --unix-socket /var/run/control.unit.sock http://localhost/
if /usr/bin/find "/app/.docker/entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
echo "$0: /app/.docker/entrypoint.d/ is not empty, applying initial configuration..."

echo "$0: Looking for certificate bundles in /app/.docker/entrypoint.d/..."
for f in $(/usr/bin/find /app/.docker/entrypoint.d/ -type f -name "*.pem"); do
echo "$0: Uploading certificates bundle: $f"
curl_put $f "certificates/$(basename $f .pem)"
done
echo "$0: Looking for JavaScript modules in /app/.docker/entrypoint.d/..."
for f in $(/usr/bin/find /app/.docker/entrypoint.d/ -type f -name "*.js"); do
echo "$0: Uploading JavaScript module: $f"
curl_put $f "js_modules/$(basename $f .js)"
done

echo "$0: Looking for configuration snippets in /app/.docker/entrypoint.d/..."
for f in $(/usr/bin/find /app/.docker/entrypoint.d/ -type f -name "*.json"); do
echo "$0: Applying configuration $f";
curl_put $f "config"
done
echo "$0: Looking for shell scripts in /app/.docker/entrypoint.d/..."
for f in $(/usr/bin/find /app/.docker/entrypoint.d/ -type f -name "*.sh"); do
echo "$0: Launching $f";
"$f"
done

# warn on filetypes we don't know what to do with
for f in $(/usr/bin/find /app/.docker/entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem" -not -name "*.js"); do
echo "$0: Ignoring $f";
done
else
echo "$0: /app/.docker/entrypoint.d/ is empty, creating 'welcome' configuration..."
curl_put /usr/share/unit/welcome/welcome.json "config"
fi
echo "$0: Stopping Unit daemon after initial configuration..."
kill -TERM $(/bin/cat /var/run/unit.pid)

for i in $(/usr/bin/seq $WAITLOOPS); do
if [ -S /var/run/control.unit.sock ]; then
echo "$0: Waiting for control socket to be removed..."
/bin/sleep $SLEEPSEC
else
break
fi
done
if [ -S /var/run/control.unit.sock ]; then
kill -KILL $(/bin/cat /var/run/unit.pid)
rm -f /var/run/control.unit.sock
fi
echo
echo "$0: Unit initial configuration complete; ready for start up..."
echo
fi
fi

exec "$@"
26 changes: 13 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ ARG PHP_VERSION=8.2

# Install base packages which all stages (build, test, run) need
FROM debian:bookworm AS base
RUN apt update && apt upgrade -y && apt install -y \
RUN apt update && apt upgrade -y
RUN apt update && apt install -y curl
RUN curl --output /usr/share/keyrings/nginx-keyring.gpg https://unit.nginx.org/keys/nginx-keyring.gpg
RUN echo 'deb [signed-by=/usr/share/keyrings/nginx-keyring.gpg] https://packages.nginx.org/unit/debian/ bookworm unit' > /etc/apt/sources.list.d/unit.list
RUN apt update && apt install -y \
php${PHP_VERSION}-cli php${PHP_VERSION}-gd php${PHP_VERSION}-zip php${PHP_VERSION}-xml php${PHP_VERSION}-mbstring \
php${PHP_VERSION}-pgsql php${PHP_VERSION}-mysql php${PHP_VERSION}-sqlite3 \
gosu curl imagemagick ffmpeg zip unzip && \
rm -rf /var/lib/apt/lists/*
gosu curl imagemagick ffmpeg zip unzip git unit unit-php
RUN apt update && apt install -y procps net-tools

# Composer has 100MB of dependencies, and we only need that during build and test
FROM base AS composer
Expand All @@ -15,7 +19,7 @@ ENV XDEBUG_MODE=coverage

# "Build" shimmie (composer install - done in its own stage so that we don't
# need to include all the composer fluff in the final image)
FROM composer AS app
FROM composer AS build
COPY composer.json composer.lock /app/
WORKDIR /app
RUN composer install --no-dev
Expand All @@ -39,16 +43,12 @@ RUN [ $RUN_TESTS = false ] || (\

# Devcontainer target
FROM composer AS devcontainer
RUN apt update && apt upgrade -y && apt install -y git && rm -rf /var/lib/apt/lists/*
EXPOSE 8000

# Actually run shimmie
FROM base
FROM base AS run
EXPOSE 8000
HEALTHCHECK --interval=1m --timeout=3s CMD curl --fail http://127.0.0.1:8000/ || exit 1
ENV UID=1000 \
GID=1000 \
UPLOAD_MAX_FILESIZE=50M
COPY --from=app /app /app

WORKDIR /app
CMD ["/bin/sh", "/app/tests/docker-init.sh"]
COPY --from=build /app /app
ENTRYPOINT ["/app/.docker/unit-entrypoint.sh"]
CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]
14 changes: 13 additions & 1 deletion core/util.php
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,19 @@ function _get_user(): User

function _get_query(): string
{
return (@$_POST["q"] ?: @$_GET["q"]) ?: "/";
// if query is explicitly set, use it
$q = @$_POST["q"] ?: @$_GET["q"];
if(!empty($q)) {
return $q;
}
// if we're just looking at index.php, use the default query
elseif (str_contains($_SERVER['REQUEST_URI'], "index.php")) {
return "/";
}
// otherwise, use the request URI
else {
return explode("?", $_SERVER['REQUEST_URI'])[0];
}
}


Expand Down
12 changes: 0 additions & 12 deletions tests/docker-init.sh

This file was deleted.

0 comments on commit 282d13f

Please sign in to comment.