Loom73 Deployment Guide¶
This guide describes the current build-and-sync deployment model for a Loom73 instance.
Loom73 is designed to be forked. Each application may keep the shared workflow while using its own repository, domain, configuration, database, storage and deployment credentials.
Requirements¶
The current deployment baseline is:
PHP 8.3 or newer
PHP 8.4 recommended
PDO
PDO MySQL
Fileinfo
Composer
Node.js 24 in the supplied workflow
Apache with mod_rewrite
rsync
SSH access
The supplied Apache configuration also uses:
for indexing and cache headers.
Deployment model¶
The current workflow performs:
GitHub Actions
→ checkout
→ install production Composer dependencies
→ install Node dependencies
→ build frontend assets
→ rsync the built application to the VPS
→ run deploy/after-deploy.sh
The VPS does not need a Git checkout.
Code and built dependencies are deployed. Instance-owned state is preserved on the server.
Server structure¶
For an instance at:
the expected shape is:
application/
commands/
config/
.env
example.env
modules/
deploy/
documentation/
lib/
public_html/
public/
index.php
.htaccess
robots.txt
css/
js/
assets/
storage/
uploads/
logs/
cache/
vendor/
shuttle
The web-server document root must be:
The browser must not receive direct access to:
Environment¶
The repository provides:
Create the real server configuration at:
For example:
Then configure at least:
APPNAME
APPURL
SYSTEM_STATUS
database connection
timezone and locale
session secrets
mail credentials
Yarn storage
Use:
for a production instance.
The real .env must never be committed or overwritten by deployment.
Runtime storage¶
Runtime files remain outside the public web root.
The standard directories are:
storage/cache/ remains part of the installed runtime structure even though Loom73 does not currently provide a generic caching abstraction.
Yarn can receive an absolute storage path through:
The upload path remains relative to it:
The deployment workflow excludes storage/. Shuttle creates the standard directories during installation.
Deployment user and permissions¶
Use a dedicated deployment account, for example:
A practical ownership model is:
where the deployment user updates code and the web-server group can read the application.
Runtime directories must also be writable by the process that handles uploads and logs.
Example:
sudo chown -R deploy:www-data /var/www/example.com
sudo find /var/www/example.com/storage \
-type d -exec chmod 2770 {} \;
sudo find /var/www/example.com/storage \
-type f -exec chmod 660 {} \;
Set the real environment file separately:
sudo chown deploy:www-data \
/var/www/example.com/config/.env
sudo chmod 640 \
/var/www/example.com/config/.env
Exact permission values may vary with the server configuration. The required behavior is:
deploy can update the application
the web server can read application files
the web server can write required runtime directories
unrelated users cannot read secrets
Apache virtual host¶
A minimal virtual host is:
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/example.com/public_html/public
<Directory /var/www/example.com/public_html/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>
Enable the required modules:
TLS termination and certificate management depend on the host and are outside the repository workflow.
GitHub repository secrets¶
Each fork defines its own Actions secrets:
Example values:
Install the matching public key in:
Test the deployment account before running the workflow:
Never store a private key, password or instance .env in the repository.
Deployment exclusions¶
The supplied exclusion list prevents runtime and development state from being synchronized.
Important exclusions include:
The workflow builds assets before deployment, so compiled files under:
remain part of the deployed result.
Composer production dependencies are installed in CI and the resulting vendor/ directory is deployed.
Workflow¶
The supplied workflow lives at:
It currently runs for pushes to:
and uses:
Because rsync uses --delete, anything inside the deployment path that is absent from the build may be removed unless explicitly excluded.
Before adding instance-owned files or directories, add them to:
After-deploy script¶
After synchronization, the workflow runs:
The current script confirms the application path and reports whether the standard storage directories exist.
It does not install the database, create runtime state or repair permissions.
That separation is deliberate:
First installation¶
After the first deployment:
Create and configure:
Then inspect the instance:
Missing database tables are expected before installation, but the environment and PHP requirements should already be visible.
Run the installer:
The command is destructive and intended for a new instance. Read its confirmation prompt carefully.
Create the first administrator:
Run the health check again:
The final result should be:
or a understood HEALTHY WITH WARNINGS result.
Indexing policy¶
Loom73 ships with indexing disabled.
The repository currently includes:
and .htaccess sends:
This is the safe default for a blueprint, test instance or private application.
Before publishing a site that should be indexed:
- update or remove the blocking
robots.txtdirective; - remove the
X-Robots-Tagrule from.htaccess; - verify the final HTTP headers;
- confirm that protected routes remain protected independently of indexing rules.
Robots directives are not access control.
Cache policy¶
Loom73 currently deploys CSS, JavaScript and images with stable filenames. These assets must be revalidated rather than cached immutably.
The supplied .htaccess applies:
to mutable images, CSS and JavaScript.
Fonts may use:
provided their filenames are changed when their contents change.
Dynamic HTML and PHP responses use a no-cache policy.
Verify the actual response headers after deployment:
curl -I https://example.com/css/main.min.css
curl -I https://example.com/js/index.min.js
curl -I https://example.com/assets/fonts/IBM-Plex-Sans_latin_100_700_normal.woff2
The configuration only applies when the relevant Apache modules and .htaccess overrides are enabled.
Smoke test¶
After installation or deployment, verify:
php shuttle loom73.info reports a healthy instance
homepage loads
CSS, JavaScript, fonts and images load
pretty URLs work
an unknown route returns HTTP 404
a missing application view returns HTTP 500
production errors expose no internal path
administrator login works
profile page loads
flash messages survive redirects
avatar upload succeeds
uploaded files remain outside the public web root
public and protected asset delivery behave correctly
Ledger records expected actions
Inspect an uploaded asset through its application route rather than through a filesystem URL.
Updating a fork¶
Loom73 does not yet provide a finalized automatic update or migration system.
Until the release and upgrade milestone is complete:
review upstream changes
review database changes
test the update on a non-production instance
preserve config/.env and storage/
deploy only after the application-specific merge is understood
When tagged releases and loom73.update become available, the documentation will define the supported upgrade path.
Do not run loom73.install to update an existing production instance.
Deployment rule¶
DEPLOY_PATH
application root
DocumentRoot
DEPLOY_PATH/public_html/public
config/.env
server-owned secret
storage/
server-owned runtime state
frontend-src/
build source, not deployed
vendor/
installed in CI and deployed
The governing rule is: