diff options
author | Freya Murphy <freya@freyacat.org> | 2024-12-23 22:14:44 -0500 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-12-23 22:14:44 -0500 |
commit | 45b58da72187a7b1ed4d75fc25bf5dd59a86a9c4 (patch) | |
tree | 721d43e663d0b9d7c15ebc4b180ba709e9e0f9c3 | |
parent | lang null check (diff) | |
download | crimson-45b58da72187a7b1ed4d75fc25bf5dd59a86a9c4.tar.gz crimson-45b58da72187a7b1ed4d75fc25bf5dd59a86a9c4.tar.bz2 crimson-45b58da72187a7b1ed4d75fc25bf5dd59a86a9c4.zip |
rework tooling to make environement loading easier
-rw-r--r-- | base.env | 73 | ||||
-rwxr-xr-x | bin/compose | 112 | ||||
-rwxr-xr-x | bin/psql (renamed from psql) | 23 | ||||
-rwxr-xr-x | bin/setup_env | 62 | ||||
-rwxr-xr-x | build/init/stamp.sh | 2 | ||||
-rwxr-xr-x | compose | 122 | ||||
-rw-r--r-- | docker/docker-compose.api.yml | 10 | ||||
-rw-r--r-- | docker/docker-compose.base.yml | 29 | ||||
-rw-r--r-- | docker/docker-compose.db.yml | 23 | ||||
-rw-r--r-- | src/_base.php | 2 | ||||
-rw-r--r-- | src/config.php | 4 |
11 files changed, 265 insertions, 197 deletions
@@ -1,34 +1,69 @@ -# ============================= GENERAL == +### CRIMSON --- A simple PHP framework. +### Copyright © 2024 Freya Murphy <contact@freyacat.org> +### +### This file is part of CRIMSON. +### +### CRIMSON is free software; you can redistribute it and/or modify it +### under the terms of the GNU General Public License as published by +### the Free Software Foundation; either version 3 of the License, or (at +### your option) any later version. +### +### CRIMSON is distributed in the hope that it will be useful, but +### WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +### GNU General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with CRIMSON. If not, see <http://www.gnu.org/licenses/>. -# project name +# ===================================================================== INFO == +# This is the CRIMSON configuration file. Copy this file as `.env` in your +# project checkout to override default crimson configuration values. +# +# NOTE: Options labeled "CHANGE ME!" MUST be modified. + +# ================================================================== GENERAL == +# Contains options for project metadata. +# PROJECT_NAME - Sets the project name in the docker compose stack. +# i.e: crimson-web-1 PROJECT_NAME="crimson" -# ================================= WEB == +# ============================================================== DEVELOPMENT == +# Sets if CRIMSON should run in "production" or "development" mode. Read +# `src/config.php` in crimson for more information. +ENVIRONMENT="production" -# What port to listen on +# ====================================================================== WEB == +# Sets what port and bind that nginx will listen on. This is how you will +# externally access your app. +# HTTP_BIND=127.0.0.1 HTTP_PORT=80 -# ============================ DATABASE == - -# Do we want the postgres database enabled +# ================================================================= DATABASE == +# If POSTGRES_ENABLED is set to `true`, then the crimson postgres database will +# be enabled. Configure the below settings for the connetions options to this +# database. +# +# WARNING: Do NOT change these values after the fist run. +# POSTGRES_ENABLED=false - -# Database authentication POSTGRES_DB=postgres POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres -# ================================= API == - -# Do we want the postgrest api enabled +# ====================================================================== API == +# If API_ENABLED is set to `true`, then the crimson postgrest container will be +# enabled. Postgres uses JWTs to do verification, so you MUST set a API_SECRET +# if the api is enabled. API_ROLE sets which role will unauthenticated api +# users will be inside postgres. API_SCHEMA sets which postgres schema that +# postgrest will use. +# +# For more information about postgres: <https://docs.postgrest.org/en/v12/>. +# +# WARNING: POSTGRES_ENABLED must be set to `true` if the API is also enabled. +# API_ENABLED=false - -# API Jwt Secret -API_SECRET="<base64>" - -# API Anonymous role +API_SECRET="" # CHANGE ME! API_ROLE="anonymous" - -# API schema API_SCHEMA="api" diff --git a/bin/compose b/bin/compose new file mode 100755 index 0000000..20c9992 --- /dev/null +++ b/bin/compose @@ -0,0 +1,112 @@ +#!/bin/sh +### CRIMSON --- A simple PHP framework. +### Copyright © 2024 Freya Murphy <contact@freyacat.org> +### +### This file is part of CRIMSON. +### +### CRIMSON is free software; you can redistribute it and/or modify it +### under the terms of the GNU General Public License as published by +### the Free Software Foundation; either version 3 of the License, or (at +### your option) any later version. +### +### CRIMSON is distributed in the hope that it will be useful, but +### WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +### GNU General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with CRIMSON. If not, see <http://www.gnu.org/licenses/>. + +# `compose` +# This script will provide a docker compose interface with all the CRIMSON +# environment setup. This script may request root privilages since it needs all +# docker containers to run with user 1000:1000. If you are not user 1000:1000, +# root privlage is required to create volume folders with uid/gid 1000. + +# Make sure errors fail to avoid nasal demons +set -e + +# ========================================================= PERMISSION CHECK == +# Make sure we are either root or user 1000:1000. This is required for crimson. + +args="$@" +command="$0 $args" + +uid=$(id -u) +gid=$(id -g) + +if [[ $uid -eq 1000 ]] && [[ $gid -eq 1000 ]]; then + true # all set +elif [[ $uid -eq 0 ]] && [[ $gid -eq 0 ]]; then + true # all set +else + # root required (1000:1000 may not exist) + exec sudo -E $command +fi + +# ========================================================= LOAD ENVIRONMENT == +# We need to load the environment variables provided by crimson and the user +# making the project. +SCRIPT_DIR="$(dirname "$0")" +source "$SCRIPT_DIR/setup_env" + +# ================================================================ BOOTSTRAP == +# Choose which docker compose files are to be loaded, and setup which arguemnts +# to pass into docker compose. + +docker_args="" + +# add env files to docker args + +docker_env_args=$(echo "$ENV_FILES" | tr ':' '\n' | sed 's/^/--env-file /' | tr '\n' ' ') +docker_args="$docker_args $docker_env_args" + +# get list of env files for docker containers + +docker_env_files="[$(echo "$ENV_FILES" | tr ':' "\n" | sed 's/.*/"&"/' | tr '\n' ',')]" + +# add compose files to docker args + +function include_docker { + local name src dest bool + name="docker-compose.$1.yml" + src="$CRIMSON_ROOT/docker/$name" + dest="/tmp/crimson/docker/$name" + + bool="$2" + if [[ "$bool" == "true" ]]; then + + mkdir -p "$(dirname "$dest")" + sed "s#DOCKER_ENV_FILES#$docker_env_files#" "$src" > "$dest" + + docker_args="$docker_args -f $dest" + fi +} + +include_docker "base" "true" +include_docker "db" "$POSTGRES_ENABLED" +include_docker "api" "$API_ENABLED" + +# set project name + +docker_args="$docker_args -p $PROJECT_NAME" + +# source check + +if [ ! -d "$PROJECT_SOURCE" ]; then + printf "fatal: cannot find PROJECT_SOURCE: '$PROJECT_SOURCE'\n" > /dev/stderr + exit 1 +fi + +# data check + +if [ ! -d "$PROJECT_DATA" ]; then + mkdir -p "$PROJECT_DATA" + mkdir -p "$PROJECT_DATA/schemas" + mkdir -p "$PROJECT_DATA/crimson" + chown -R 1000:1000 "$PROJECT_DATA" +fi + +# run docker compose + +exec -a docker -- docker compose $docker_args "$@" @@ -25,21 +25,16 @@ # database at times. This makes it nicer enter it since you dont have to type # the full command. :) -# ================================================================ CONSTANTS == -# ROOT: This is the folder the crimson project is located in. ROOT is used to -# load the crimson environment. We need this since that is where POSTGRES_USER -# and POSTGRES_DB are stored. -# CALL_ROOT: This is the folder that the user who called `compose` is currently -# in. For crimson to work this must be the folder that your project using -# crimson is. This is because crimson loads `.env` here to load any user -# specified environment. `.env` is needed in cause you override POSTGRES_USER -# and/or POSTGRES_DB. -ROOT="$(dirname "$0")" -CALL_ROOT="$(pwd)" +# Make sure errors fail to avoid nasal demons +set -e + +# ========================================================= LOAD ENVIRONMENT == +# We need to load the environment variables provided by crimson and the user +# making the project. +SCRIPT_DIR="$(dirname "$0")" +source "$SCRIPT_DIR/setup_env" # ================================================================ BOOTSTRAP == # Load `base.env` and `.env`, then launch psql in docker. -source "$ROOT/base.env" -source "$CALL_ROOT/.env" -$ROOT/compose exec postgres psql -U "${POSTGRES_USER}" "${POSTGRES_DB}" "$@" +$SCRIPT_DIR/compose exec postgres psql -U "${POSTGRES_USER}" "${POSTGRES_DB}" "$@" diff --git a/bin/setup_env b/bin/setup_env new file mode 100755 index 0000000..4a3049c --- /dev/null +++ b/bin/setup_env @@ -0,0 +1,62 @@ +#!/bin/sh +### CRIMSON --- A simple PHP framework. +### Copyright © 2024 Freya Murphy <contact@freyacat.org> +### +### This file is part of CRIMSON. +### +### CRIMSON is free software; you can redistribute it and/or modify it +### under the terms of the GNU General Public License as published by +### the Free Software Foundation; either version 3 of the License, or (at +### your option) any later version. +### +### CRIMSON is distributed in the hope that it will be useful, but +### WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +### GNU General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with CRIMSON. If not, see <http://www.gnu.org/licenses/>. + +# `setup_env` +# This script sets up the environment for crimson by loading all required .env +# files. + +# Make sure errors fail to avoid nasal demons +set -e + +# ================================================================ CONSTANTS == +# CRIMSON_ROOT: This is the folder the crimson project is located in. This +# variable is needed since it is used to load any files located in crimson, +# including base.env, and docker compose files. +# PROJECT_ROOT: This is the folder that the user who called any crimson script +# is currently located in. For crimson to work this must be the folder that +# your project checkout is in. This is because crimson loads `.env` here to +# load any user specified environment. +# PROJECT_DATA: Where docker persistent data will be stored. +# PROEJCT_SOURCE: Where user project code is located. +# ENV_FILES: A colon seperated list of all .env files loaded. +export CRIMSON_ROOT="$(realpath "$(dirname "$(dirname "$0")")")" +export PROJECT_ROOT="$(realpath "$(pwd)")" +export PROJECT_DATA="${PROJECT_ROOT}/data" +export PROJECT_SOURCE="${PROJECT_ROOT}/src" +ENV_FILES="" + +# ================================================================ BOOTSTRAP == +# Load `base.env` and `.env` +function load_env { + local file seperator + file="$1" + seperator=":" + if [ -f "$file" ]; then + # dont add seperator at the start + if [ -z "$ENV_FILES" ]; then + seperator="" + fi + # load file + source "$file" + ENV_FILES="${ENV_FILES}${seperator}${file}" + fi +} + +load_env "$CRIMSON_ROOT/base.env" +load_env "$PROJECT_ROOT/.env" diff --git a/build/init/stamp.sh b/build/init/stamp.sh index 6f71038..abb6856 100755 --- a/build/init/stamp.sh +++ b/build/init/stamp.sh @@ -1,5 +1,7 @@ #!/bin/sh +IFS=$'\n' + out="/var/run/crimson/stamp.php" public="/opt/site/public" files=$(find "$public" -type f -printf %P\\n) diff --git a/compose b/compose deleted file mode 100755 index 20126f4..0000000 --- a/compose +++ /dev/null @@ -1,122 +0,0 @@ -#!/bin/sh -### CRIMSON --- A simple PHP framework. -### Copyright © 2024 Freya Murphy <contact@freyacat.org> -### -### This file is part of CRIMSON. -### -### CRIMSON is free software; you can redistribute it and/or modify it -### under the terms of the GNU General Public License as published by -### the Free Software Foundation; either version 3 of the License, or (at -### your option) any later version. -### -### CRIMSON is distributed in the hope that it will be useful, but -### WITHOUT ANY WARRANTY; without even the implied warranty of -### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -### GNU General Public License for more details. -### -### You should have received a copy of the GNU General Public License -### along with CRIMSON. If not, see <http://www.gnu.org/licenses/>. - -# `compose` -# This script will provide a docker compose interface with all the CRIMSON -# environment setup. This script may request root privilages since it needs all -# docker containers to run with user 1000:1000. If you are not user 1000:1000, -# root privlage is required to create volume folders with uid/gid 1000. - -# Make sure errors fail to avoid nasal demons -set -e - -# ========================================================= PERMISSION CHECK == -# Make sure we are either root or user 1000:1000. This is required for crimson. - -args="$@" -command="$0 $args" - -uid=$(id -u) -gid=$(id -g) - -if [[ $uid -eq 1000 ]] && [[ $gid -eq 1000 ]]; then - true # all set -elif [[ $uid -eq 0 ]] && [[ $gid -eq 0 ]]; then - true # all set -else - # root required (1000:1000 may not exist) - exec sudo -E $command -fi - -# ================================================================ CONSTANTS == -# ROOT: This is the folder the crimson project is located in. ROOT is used to -# access docker-compose files, base.env, and other crimson files. -# CALL_ROOT: This is the folder that the user who called `compose` is currently -# in. For crimson to work this must be the folder that your project using -# crimson is. This is because crimson loads `.env` here to load any user -# specified environment. `.env` is needed for $DATA and $SOURCE. Read base.env -# for more information. - -ROOT="$(realpath "$(dirname "$0")")" -CALL_ROOT="$(pwd)" - -# ================================================================ FUNCTIONS == -# add_arg - adds arguments to the docker compose command to be run -# include_env - loads a .env file -# include - adds the docker compose file to be included called -# docker-compose.<$1>.yml - -docker_args="" -function add_arg { - docker_args="$docker_args $@" -} - -function include_env { - local file - file="$1" - if [ -f "$file" ]; then - source "$file" - add_arg --env-file $file - fi -} - -function include { - local file - if [ "$2" = "true" ]; then - file="$ROOT/docker/docker-compose.$1.yml" - add_arg -f $file - fi -} - -# ================================================================ BOOTSTRAP == -# Enter the crimson project directory, load all .env files, and pick which -# docker-compose.*.yml files are requested. Then make the docker volumes here -# with the correct permissions. If we let docker do it, it will make them owned -# by root (thanks) and break our containers. - -cd "$ROOT" - -# get docker file includes -include_env "$ROOT/base.env" -include_env "$CALL_ROOT/.env" -include "base" "true" -include "db" "$POSTGRES_ENABLED" -include "api" "$API_ENABLED" - -# assert SOURCE and DATA are set -if [ -z "$SOURCE" ]; then - printf "fatal: SOURCE is not set. See '$ROOT/base.env'\n" - exit 1 -fi - -if [ -z "$DATA" ]; then - printf "fatal: DATA is not set. See '$ROOT/base.env'\n" - exit 1 -fi - -# preset perms (postgres will crash if not) -if [ ! -d "$DATA" ]; then - mkdir -p "$DATA" - mkdir -p "$DATA/crimson" - mkdir -p "$DATA/schemas" - chown -R 1000:1000 "$DATA" -fi - -# run docker compose -exec -a docker -- docker compose -p $PROJECT_NAME $docker_args "$@" diff --git a/docker/docker-compose.api.yml b/docker/docker-compose.api.yml index 5c7f6d8..51e5c79 100644 --- a/docker/docker-compose.api.yml +++ b/docker/docker-compose.api.yml @@ -31,15 +31,9 @@ services: # database must be working (healthy) and all the api schema must be loaded. # It is db-init's job to load the api schema, thus this container depends # on both postgres and db-init. - build: ../build/postgrest + build: ${CRIMSON_ROOT}/build/postgrest restart: unless-stopped - environment: - - API_SECRET - - API_ROLE - - API_SCHEMA - - POSTGRES_DB - - POSTGRES_USER - - POSTGRES_PASSWORD + env_file: DOCKER_ENV_FILES healthcheck: test: curl -I "http://localhost:3000/" interval: 10s diff --git a/docker/docker-compose.base.yml b/docker/docker-compose.base.yml index 3dcc7b8..066545d 100644 --- a/docker/docker-compose.base.yml +++ b/docker/docker-compose.base.yml @@ -30,15 +30,14 @@ services: # # HTTP_PORT and HTTP_BIND sets what the external listen address will be for # the entire crimson stack. - build: ../build/nginx + build: ${CRIMSON_ROOT}/build/nginx restart: unless-stopped - environment: - - API_ENABLED + env_file: DOCKER_ENV_FILES ports: - ${HTTP_BIND}:${HTTP_PORT}:8080 volumes: - - ${SOURCE}:/opt/site:ro - - ../src:/opt/crimson:ro + - ${PROJECT_SOURCE}:/opt/site:ro + - ${CRIMSON_ROOT}/src:/opt/crimson:ro depends_on: php: condition: service_started @@ -47,16 +46,13 @@ services: # There exists some crimson functionaly that MAY be used which requires a # stamp.php file to be auto generated. This is done in `init`, this `init` # is an added dependency. - build: ../build/php + build: ${CRIMSON_ROOT}/build/php restart: unless-stopped - environment: - - POSTGRES_DB - - POSTGRES_USER - - POSTGRES_PASSWORD + env_file: DOCKER_ENV_FILES volumes: - - ${SOURCE}:/opt/site:ro - - ../src:/opt/crimson:ro - - ${DATA}/crimson:/var/run/crimson + - ${PROJECT_SOURCE}:/opt/site:ro + - ${CRIMSON_ROOT}/src:/opt/crimson:ro + - ${PROJECT_DATA}/crimson:/var/run/crimson depends_on: init: condition: service_completed_successfully @@ -65,8 +61,9 @@ services: # Initalizes required files for php. Currently init only generates stamp.php. # This file hols all file stamps for all public assets, which is used in # crimsons `asset_stamp` controller function. - build: ../build/init + build: ${CRIMSON_ROOT}/build/init restart: no + env_file: DOCKER_ENV_FILES volumes: - - ${SOURCE}:/opt/site - - ${DATA}/crimson:/var/run/crimson + - ${PROJECT_SOURCE}:/opt/site + - ${PROJECT_DATA}/crimson:/var/run/crimson diff --git a/docker/docker-compose.db.yml b/docker/docker-compose.db.yml index 4979bbe..b5cf34d 100644 --- a/docker/docker-compose.db.yml +++ b/docker/docker-compose.db.yml @@ -25,16 +25,14 @@ services: # This service stack is only enabled when API_ENABLED=true. postgres: - build: ../build/postgres + build: ${CRIMSON_ROOT}/build/postgres restart: unless-stopped + env_file: DOCKER_ENV_FILES environment: - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C - - POSTGRES_DB - - POSTGRES_USER - - POSTGRES_PASSWORD volumes: - - ${DATA}/schemas:/var/lib/postgresql/data - - ${SOURCE}/db:/db:ro + - ${PROJECT_DATA}/schemas:/var/lib/postgresql/data + - ${PROJECT_SOURCE}/db:/db:ro healthcheck: test: pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB} interval: 1s @@ -55,17 +53,12 @@ services: # # For information on databse conventions and layouts, see # `build/db-init/README.md`. - build: ../build/db-init + build: ${CRIMSON_ROOT}/build/db-init restart: no - environment: - - POSTGRES_DB - - POSTGRES_USER - - POSTGRES_PASSWORD - - API_ENABLED - - API_SECRET + env_file: DOCKER_ENV_FILES volumes: - - ${SOURCE}/db:/db:ro - - ${DATA}/crimson:/var/run/crimson + - ${PROJECT_SOURCE}/db:/db:ro + - ${PROJECT_DATA}/crimson:/var/run/crimson depends_on: postgres: condition: service_healthy diff --git a/src/_base.php b/src/_base.php index 89df718..d53905d 100644 --- a/src/_base.php +++ b/src/_base.php @@ -173,7 +173,7 @@ abstract class Base { */ public function asset_stamp(string $path): int { - if (ENVIRONMENT == 'devlopment') + if (ENVIRONMENT == 'development') return time(); if (isset(FILE_TIMES[$path])) return FILE_TIMES[$path]; diff --git a/src/config.php b/src/config.php index 0d52d96..2c759a2 100644 --- a/src/config.php +++ b/src/config.php @@ -19,7 +19,7 @@ // ENVIRONMENT // -// devlopment - do not cache any assets +// development - do not cache any assets // - use http host provided by user // // production - use generated timestamps for each file @@ -29,7 +29,7 @@ if (!defined('ENVIRONMENT')) { if (getenv('ENVIRONMENT') !== FALSE) define('ENVIRONMENT', getenv('ENVIRONMENT')); else - define('ENVIRONMENT', 'devlopment'); + define('ENVIRONMENT', 'development'); } // CONFIG |