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"
|
||||
},
|
||||
|
||||
"workspaceMount": "source=${localWorkspaceFolder},target=/app,type=bind",
|
||||
"workspaceFolder": "/app",
|
||||
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
// "features": {},
|
||||
|
||||
|
@ -15,8 +18,11 @@
|
|||
"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": [
|
||||
|
|
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
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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"]
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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