Use nginx Unit rather than the php development server
This commit is contained in:
parent
f00a4e3d90
commit
282d13f632
6 changed files with 216 additions and 28 deletions
|
@ -8,6 +8,9 @@
|
||||||
"target": "devcontainer"
|
"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 to add to the dev container. More info: https://containers.dev/features.
|
||||||
// "features": {},
|
// "features": {},
|
||||||
|
|
||||||
|
@ -15,8 +18,11 @@
|
||||||
"forwardPorts": [8000],
|
"forwardPorts": [8000],
|
||||||
|
|
||||||
// Uncomment the next line to run commands after the container is created.
|
// 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": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": [
|
"extensions": [
|
||||||
|
|
76
.docker/entrypoint.d/config.json
Normal file
76
.docker/entrypoint.d/config.json
Normal file
|
@ -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
.docker/entrypoint.sh
Executable file
106
.docker/entrypoint.sh
Executable file
|
@ -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
Dockerfile
26
Dockerfile
|
@ -2,11 +2,15 @@ ARG PHP_VERSION=8.2
|
||||||
|
|
||||||
# Install base packages which all stages (build, test, run) need
|
# Install base packages which all stages (build, test, run) need
|
||||||
FROM debian:bookworm AS base
|
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}-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 \
|
php${PHP_VERSION}-pgsql php${PHP_VERSION}-mysql php${PHP_VERSION}-sqlite3 \
|
||||||
gosu curl imagemagick ffmpeg zip unzip && \
|
gosu curl imagemagick ffmpeg zip unzip git unit unit-php
|
||||||
rm -rf /var/lib/apt/lists/*
|
RUN apt update && apt install -y procps net-tools
|
||||||
|
|
||||||
# Composer has 100MB of dependencies, and we only need that during build and test
|
# Composer has 100MB of dependencies, and we only need that during build and test
|
||||||
FROM base AS composer
|
FROM base AS composer
|
||||||
|
@ -15,7 +19,7 @@ ENV XDEBUG_MODE=coverage
|
||||||
|
|
||||||
# "Build" shimmie (composer install - done in its own stage so that we don't
|
# "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)
|
# 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/
|
COPY composer.json composer.lock /app/
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN composer install --no-dev
|
RUN composer install --no-dev
|
||||||
|
@ -39,16 +43,12 @@ RUN [ $RUN_TESTS = false ] || (\
|
||||||
|
|
||||||
# Devcontainer target
|
# Devcontainer target
|
||||||
FROM composer AS devcontainer
|
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
|
# Actually run shimmie
|
||||||
FROM base
|
FROM base AS run
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
HEALTHCHECK --interval=1m --timeout=3s CMD curl --fail http://127.0.0.1:8000/ || exit 1
|
HEALTHCHECK --interval=1m --timeout=3s CMD curl --fail http://127.0.0.1:8000/ || exit 1
|
||||||
ENV UID=1000 \
|
COPY --from=build /app /app
|
||||||
GID=1000 \
|
ENTRYPOINT ["/app/.docker/unit-entrypoint.sh"]
|
||||||
UPLOAD_MAX_FILESIZE=50M
|
CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]
|
||||||
COPY --from=app /app /app
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
CMD ["/bin/sh", "/app/tests/docker-init.sh"]
|
|
|
@ -686,7 +686,19 @@ function _get_user(): User
|
||||||
|
|
||||||
function _get_query(): string
|
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];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
groupadd -g $GID shimmie || true
|
|
||||||
useradd -ms /bin/bash -u $UID -g $GID shimmie
|
|
||||||
mkdir -p /app/data
|
|
||||||
chown $UID:$GID /app/data
|
|
||||||
export PHP_CLI_SERVER_WORKERS=8
|
|
||||||
exec gosu shimmie:shimmie \
|
|
||||||
/usr/bin/php \
|
|
||||||
-d upload_max_filesize=$UPLOAD_MAX_FILESIZE \
|
|
||||||
-d post_max_size=$UPLOAD_MAX_FILESIZE \
|
|
||||||
-S 0.0.0.0:8000 \
|
|
||||||
tests/router.php 2>&1 | grep --line-buffered -vE " (Accepted|Closing)"
|
|
Reference in a new issue