summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-05-23 12:15:02 -0400
committerFreya Murphy <freya@freyacat.org>2024-05-23 12:15:02 -0400
commit17159879069c2e38e6415d152d35455f123ac674 (patch)
treef7107d1d3a416dc972b266029c8340c0a2266bbb
parentthings (diff)
downloadxssbook2-17159879069c2e38e6415d152d35455f123ac674.tar.gz
xssbook2-17159879069c2e38e6415d152d35455f123ac674.tar.bz2
xssbook2-17159879069c2e38e6415d152d35455f123ac674.zip
changes
-rw-r--r--build/init/Dockerfile18
-rwxr-xr-xbuild/init/init73
-rw-r--r--build/nginx/Dockerfile21
-rw-r--r--build/php/Dockerfile15
-rw-r--r--build/postgres/Dockerfile17
-rw-r--r--build/postgrest/Dockerfile27
-rwxr-xr-xbuild/postgrest/entrypoint.sh19
-rw-r--r--conf/nginx/nginx.conf72
-rw-r--r--conf/nginx/site.conf72
-rw-r--r--docker-compose.yml18
-rw-r--r--src/web/_views/header_empty.php4
-rw-r--r--src/web/index.php13
12 files changed, 225 insertions, 144 deletions
diff --git a/build/init/Dockerfile b/build/init/Dockerfile
index 2b3d770..98eb285 100644
--- a/build/init/Dockerfile
+++ b/build/init/Dockerfile
@@ -1,5 +1,21 @@
FROM alpine:3.19
-RUN apk add --no-cache postgresql16-client tini
+
+# install packages
+RUN apk add --no-cache postgresql16-client tini shadow
+RUN rm -fr /var/cache/apk/*
+
+# setup main user
+RUN adduser -D init
+RUN groupmod --gid 1000 init
+RUN usermod --uid 1000 init
+
+# copy scripts
COPY ./init /usr/local/bin/init
+
+# remove build packages
+RUN apk del shadow
+
+# do the
+USER init
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["/usr/local/bin/init"]
diff --git a/build/init/init b/build/init/init
index c64f139..c8dd3f0 100755
--- a/build/init/init
+++ b/build/init/init
@@ -1,21 +1,37 @@
#!/bin/sh
+errors=$(mktemp)
+
step() {
printf '\x1b[34;1m>> %s\x1b[0m\n' "$*"
}
error() {
- printf '\x1b[31;1merror: \x1b[0m%s\n' "$*"
+ {
+ printf '\x1b[31;1merror: \x1b[0m%s\n' "$*";
+ grep -v 'current transaction is aborted' < "$errors";
+ printf "\x1b[31m;1error: \x1b[0mAborting migrations, fix file(s) then restart process.";
+ } 1>&2;
+}
+
+try() {
+ "$@" 2> "$errors";
+ count=$(grep -c 'ERROR' < "$errors")
+ if [ "$count" -eq 0 ]; then
+ return 0;
+ else
+ return 1;
+ fi
}
-export PGPASSWORD=$POSTGRES_PASSWORD
+export PGPASSWORD="$POSTGRES_PASSWORD"
psql() {
/usr/bin/psql \
-h db \
-p 5432 \
- -d $POSTGRES_DB \
- -U $POSTGRES_USER \
+ -d "$POSTGRES_DB" \
+ -U "$POSTGRES_USER" \
"$@"
}
@@ -23,9 +39,8 @@ pg_isready() {
/usr/bin/pg_isready \
-h db \
-p 5432 \
- -d $POSTGRES_DB \
- -U $POSTGRES_USER \
- "$@"
+ -d "$POSTGRES_DB" \
+ -U "$POSTGRES_USER"
}
curr_revision() {
@@ -49,17 +64,12 @@ run_migrations() {
while true; do
name=$(printf "%04d" "$i");
file="/db/migrations/$name.sql"
-
- if [ -f $file ]; then
- psql -f $file 2> /errors
- errors=$(cat /errors | grep 'ERROR' | wc -l)
- if [ "$errors" -eq 0 ]; then
+ if [ -f "$file" ]; then
+ if try psql -f "$file"; then
i=$((i+1));
continue;
else
error "An error occoured during a migration (rev $name)"
- cat /errors | grep -v 'current transaction is aborted';
- error "Aborting migrations, fix file(s) then restart process."
return 1;
fi
else
@@ -69,24 +79,19 @@ run_migrations() {
}
init_api() {
- psql -f /db/rest/rest.sql 2> /errors;
- errors=$(cat /errors | grep 'ERROR' | wc -l)
- if [ "$errors" -eq 0 ]; then
+ if try psql -f /db/rest/rest.sql; then
return 0;
else
error "An error occoured during api initialization"
- cat /errors | grep -v 'current transaction is aborted';
- error "Aborting api initialization, fix file(s) then restart process."
return 1;
fi
}
update_jwt() {
- psql -c "UPDATE sys.database_info SET jwt_secret = '$JWT_SECRET' WHERE name = current_database();"
- errors=$(cat /errors | grep 'ERROR' | wc -l)
- if [ "$errors" -eq 0 ]; then
+ if try psql -c "UPDATE sys.database_info SET jwt_secret = '$JWT_SECRET' WHERE name = current_database();"; then
return 0;
else
+ error "Could not update JWT"
return 1;
fi
}
@@ -98,7 +103,7 @@ load_ext() {
init () {
# reomve ready status
# so php ignores requests
- rm -fr /status/ready
+ rm -f /status/ready
step 'Waiting for database';
# make sure the database is running
@@ -116,31 +121,22 @@ init () {
step "Database at revision: $REV"
# run each migration that is
# higher than our current revision
- run_migrations "$REV"
- CODE=$?;
-
- if [ $CODE -ne 0 ]; then
- return $CODE;
+ if ! run_migrations "$REV"; then
+ return 1;
fi
step 'Initalizing the api';
# reinit the api schema for
# postgrest
- init_api;
- CODE=$?;
-
- if [ $CODE -ne 0 ]; then
- return $CODE;
+ if ! init_api; then
+ return 1;
fi
step 'Updating JWT secret';
# make sure postgres has the corrent
# jwt secret
- update_jwt;
- CODE=$?;
-
- if [ $CODE -ne 0 ]; then
- return $CODE;
+ if ! update_jwt; then
+ return 1;
fi
step 'Database is initialized'
@@ -149,3 +145,4 @@ init () {
}
init
+rm "$errors"
diff --git a/build/nginx/Dockerfile b/build/nginx/Dockerfile
new file mode 100644
index 0000000..6aa4e00
--- /dev/null
+++ b/build/nginx/Dockerfile
@@ -0,0 +1,21 @@
+FROM alpine:3.19
+
+# install packages
+RUN apk add --no-cache nginx shadow tini
+RUN rm -fr /var/cache/apk/*
+
+# update nginx user
+RUN groupmod --gid 1000 nginx
+RUN usermod --uid 1000 nginx
+
+# remove build packages
+RUN apk del shadow
+
+# make log syms
+RUN ln -sf /dev/stdout /var/log/nginx/access.log && \
+ ln -sf /dev/stderr /var/log/nginx/error.log
+
+# do the
+USER nginx
+ENTRYPOINT ["/sbin/tini", "--"]
+CMD ["/usr/sbin/nginx", "-c", "/etc/nginx/nginx.conf"]
diff --git a/build/php/Dockerfile b/build/php/Dockerfile
index d05e60b..5f4bdd5 100644
--- a/build/php/Dockerfile
+++ b/build/php/Dockerfile
@@ -1,4 +1,17 @@
FROM php:fpm-alpine
-RUN apk add --no-cache postgresql-dev runuser
+
+# install packages
+RUN apk add --no-cache postgresql-dev runuser shadow
+RUN rm -fr /var/cache/apk/*
+
+# update php user
+RUN groupmod --gid 1000 www-data
+RUN usermod --uid 1000 www-data
+
+# install php packages
RUN docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql
RUN docker-php-ext-install pdo pdo_pgsql
+
+# remove build packages
+RUN apk del shadow
+USER www-data
diff --git a/build/postgres/Dockerfile b/build/postgres/Dockerfile
index 834fa89..32bca6e 100644
--- a/build/postgres/Dockerfile
+++ b/build/postgres/Dockerfile
@@ -1,6 +1,21 @@
FROM postgres:16-alpine
-RUN apk add --no-cache make git
+
+# install packages
+RUN apk add --no-cache make git shadow
+RUN rm -fr /var/cache/apk/*
+
+# install pgjwt
RUN git clone https://github.com/michelp/pgjwt.git /tmp/pgjwt
WORKDIR /tmp/pgjwt
RUN make install
+
+# update postgres user
+RUN groupmod --gid 1000 postgres
+RUN usermod --uid 1000 postgres
+
+# remove build packages
+RUN apk del make git shadow
+
+# fix workdir
WORKDIR /
+USER postgres
diff --git a/build/postgrest/Dockerfile b/build/postgrest/Dockerfile
index d7720aa..bf1a573 100644
--- a/build/postgrest/Dockerfile
+++ b/build/postgrest/Dockerfile
@@ -1,9 +1,30 @@
FROM alpine:3.19
+
+# install packages
+RUN apk add --no-cache tini shadow
+RUN rm -fr /var/cache/apk/*
+
+# setup main user
+RUN adduser -D postgrest
+RUN groupmod --gid 1000 postgrest
+RUN usermod --uid 1000 postgrest
+
+# install postgrest
COPY ./postgrest.tar.xz /tmp/postgrest.tar.xz
-RUN tar xJf /tmp/postgrest.tar.xz -C /tmp
-RUN cp /tmp/postgrest /usr/local/bin/postgrest
+RUN tar xJf /tmp/postgrest.tar.xz -C /usr/local/bin
RUN rm /tmp/postgrest.tar.xz
+
+# copy scripts
COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
-CMD ["/usr/local/bin/entrypoint.sh"]
+# remove build packages
+RUN apk del shadow
+
+# make the dirs
+RUN mkdir -p /etc/postgrest.d && \
+ chown postgrest:postgrest /etc/postgrest.d
+# do the
+USER postgrest
+ENTRYPOINT ["/sbin/tini", "--"]
+CMD ["/usr/local/bin/entrypoint.sh"]
diff --git a/build/postgrest/entrypoint.sh b/build/postgrest/entrypoint.sh
index d375769..71b433d 100755
--- a/build/postgrest/entrypoint.sh
+++ b/build/postgrest/entrypoint.sh
@@ -1,6 +1,5 @@
#!/bin/sh
-mkdir /etc/postgrest.d
config=/etc/postgrest.d/postgrest.conf
PGRST_DB_URI="postgres://authenticator:postgrest@db:5432/$POSTGRES_DB"
@@ -9,12 +8,14 @@ PGRST_SCHEMA="api"
rm -fr "$config"
touch "$config"
-printf 'db-uri = "%s"\n' "$PGRST_DB_URI" >> $config
-printf 'db-anon-role = "%s"\n' "$PGRST_ROLE" >> $config
-printf 'db-schemas = "%s"\n' "$PGRST_SCHEMA" >> $config
-printf 'jwt-secret = "%s"\n' "$JWT_SECRET" >> $config
-printf 'jwt-secret-is-base64 = false\n' >> $config
-printf 'server-host = "*"\n' >> $config
-printf 'server-port = 3000\n' >> $config
+{
+ printf 'db-uri = "%s"\n' "$PGRST_DB_URI";
+ printf 'db-anon-role = "%s"\n' "$PGRST_ROLE";
+ printf 'db-schemas = "%s"\n' "$PGRST_SCHEMA";
+ printf 'jwt-secret = "%s"\n' "$JWT_SECRET";
+ printf 'jwt-secret-is-base64 = false\n';
+ printf 'server-host = "*"\n';
+ printf 'server-port = 3000\n';
+} >> $config
-exec /usr/local/bin/postgrest $config
+exec /usr/local/bin/postgrest "$config"
diff --git a/conf/nginx/nginx.conf b/conf/nginx/nginx.conf
new file mode 100644
index 0000000..64f1b1d
--- /dev/null
+++ b/conf/nginx/nginx.conf
@@ -0,0 +1,72 @@
+worker_processes 4;
+daemon off;
+pid /tmp/nginx.pid;
+error_log /var/log/nginx/error.log;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ include mime.types;
+ default_type application/octet-stream;
+ sendfile on;
+ keepalive_timeout 70;
+ server_tokens off;
+ client_max_body_size 2m;
+
+ access_log /var/log/nginx/access.log;
+
+ upstream postgrest {
+ server rest:3000;
+ }
+
+ server {
+ listen 8080;
+ root /opt/xssbook;
+
+ gzip on;
+ gzip_vary on;
+ gzip_proxied any;
+ gzip_comp_level 6;
+ gzip_buffers 16 8k;
+ gzip_http_version 1.1;
+ gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml image/x-icon;
+
+ location /api/ {
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header Host $http_host;
+ proxy_set_header Accept-Encoding "";
+ proxy_redirect off;
+
+ default_type application/json;
+ add_header 'Access-Control-Allow-Origin' '*';
+ add_header Content-Location /api/$upstream_http_content_location;
+ proxy_set_header Connection "";
+ proxy_http_version 1.1;
+
+ proxy_pass http://postgrest/;
+ }
+
+ location /favicon.ico {
+ add_header 'Access-Control-Allow-Origin' '*';
+ root /opt/xssbook/public;
+ add_header Cache-Control "public, max-age=108000";
+ }
+
+ location /public {
+ add_header 'Access-Control-Allow-Origin' '*';
+ try_files $uri =404;
+ add_header Cache-Control "public, max-age=108000";
+ }
+
+ location / {
+ add_header 'Access-Control-Allow-Origin' '*';
+ root /opt/xssbook/web;
+ include fastcgi_params;
+ fastcgi_pass php:9000;
+ fastcgi_param SCRIPT_FILENAME $document_root/index.php;
+ }
+
+ }
+}
diff --git a/conf/nginx/site.conf b/conf/nginx/site.conf
deleted file mode 100644
index 04c75ca..0000000
--- a/conf/nginx/site.conf
+++ /dev/null
@@ -1,72 +0,0 @@
-server_tokens off;
-
-upstream postgrest {
- server rest:3000 fail_timeout=0;
-}
-
-upstream swagger {
- server swagger:3000 fail_timeout=0;
-}
-
-server {
- listen 80;
- server_name localhost;
-
- keepalive_timeout 70;
- sendfile on;
- client_max_body_size 2m;
-
- error_log /var/log/nginx/error.log;
- access_log /var/log/nginx/access.log;
-
- root /opt/xssbook;
-
- gzip on;
- gzip_vary on;
- gzip_proxied any;
- gzip_comp_level 6;
- gzip_buffers 16 8k;
- gzip_http_version 1.1;
- gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml image/x-icon;
-
- location /api/ {
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header Host $http_host;
- proxy_set_header Accept-Encoding "";
- proxy_redirect off;
-
- default_type application/json;
- add_header 'Access-Control-Allow-Origin' '*';
- add_header Content-Location /api/$upstream_http_content_location;
- proxy_set_header Connection "";
- proxy_http_version 1.1;
- proxy_pass http://postgrest/;
- }
-
- location /apidocs {
- add_header 'Access-Control-Allow-Origin' '*';
- proxy_http_version 1.1;
- proxy_pass http://swagger;
- }
-
- location /favicon.ico {
- add_header 'Access-Control-Allow-Origin' '*';
- root /opt/xssbook/public;
- add_header Cache-Control "public, max-age=108000";
- }
-
- location /public {
- add_header 'Access-Control-Allow-Origin' '*';
- try_files $uri =404;
- add_header Cache-Control "public, max-age=108000";
- }
-
- location / {
- add_header 'Access-Control-Allow-Origin' '*';
- root /opt/xssbook/web;
- include fastcgi_params;
- fastcgi_pass php:9000;
- fastcgi_param SCRIPT_FILENAME $document_root/index.php;
- }
-
-}
diff --git a/docker-compose.yml b/docker-compose.yml
index ce40cde..10a37a3 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,15 +1,14 @@
services:
web:
- image: nginx:alpine
+ build: ./build/nginx
restart: unless-stopped
ports:
- - '80:80'
+ - '80:8080'
volumes:
- ./src:/opt/xssbook:ro
- - ./conf/nginx:/etc/nginx/conf.d:ro
+ - ./conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- rest
- - swagger
- php
php:
@@ -25,7 +24,6 @@ services:
- db
db:
- #image: postgres:16-alpine
build: ./build/postgres
restart: unless-stopped
env_file:
@@ -66,13 +64,3 @@ services:
- ./data/shim/:/data:ro
depends_on:
- db
-
- swagger:
- image: swaggerapi/swagger-ui
- restart: unless-stopped
- environment:
- SWAGGER_JSON_URL: '/api'
- BASE_URL: '/apidocs'
- PORT: 3000
- depends_on:
- - db
diff --git a/src/web/_views/header_empty.php b/src/web/_views/header_empty.php
index 037c89a..cca43a1 100644
--- a/src/web/_views/header_empty.php
+++ b/src/web/_views/header_empty.php
@@ -1,6 +1,8 @@
<!DOCTYPE html>
-<html>
+<html lang="en">
<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
<script>
<?php if ($this->main->session): ?>
var jwtStr = <?=json_encode($this->main->session['jwt'])?>;
diff --git a/src/web/index.php b/src/web/index.php
index dc54905..e032ef2 100644
--- a/src/web/index.php
+++ b/src/web/index.php
@@ -1,8 +1,5 @@
<?php /* Copyright (c) 2024 Freya Murphy */
-session_save_path('/var/lib/php/session');
-session_start();
-
$webroot = dirname(__FILE__);
// load all the helper files
@@ -21,6 +18,16 @@ require($webroot . '/core/database.php');
require($webroot . '/core/loader.php');
require($webroot . '/core/router.php');
+session_save_path('/var/lib/php/session');
+session_set_cookie_params(
+ 60 * 60 * 24 * 365, // lifetime (seconds),
+ '/', // path
+ NULL, // domain,
+ FALSE, // secure,
+ FALSE // http only
+);
+session_start();
+
function __init() {
$load = new Loader();
$router = new Router($load);