- Gvary web-reader
Gvary web-reader is a Laravel 10 MPA (Multi Page Application).
We use VS Code as our IDE, so all setup is done for it.
You must install the next plugins:
- Laravel Pint - for formatting PHP files
- Prettier - for formatting JS, TS, Blade files
- Tailwind CSS IntelliSense - for autocompletion with values from our .tailwind config
- Markdown All in One - for formatting .md files (mostly readme)
You are ready to contribute! Formatting should work out of the box because we have workspace overrides in defined .vscode/settings.json
- Pre-requirements
sudo apt-get install ca-certificates apt-transport-https software-properties-common- Add apt repo
sudo add-apt-repository ppa:ondrej/php- Install PHP 8.3
sudo apt install php8.3- Install PHP extensions (modules)
sudo apt install php8.3-dom php8.3-mysqli php8.3-mbstring php8.3-curl- Run the script
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === 'edb40769019ccf227279e3bdd1f5b2e9950eb000c3233ee85148944e555d97be3ea4f40c3c2fe73b22f875385f6a5155') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"- Make executable accessible globally
sudo mv composer.phar /usr/local/bin/composer- Install docker
- Add current user to docker group
- Install
nvmscript to manage NodeJS versions
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash- Install LTS Iron version
nvm install lts/iron- Before using node or npm
nvm use lts/ironMake sure you have
Docker version 25.0.3, build 4debf41
PHP 8.3.3-1+ubuntu22.04.1+deb.sury.org+1 (cli) (built: Feb 15 2024 18:38:52) (NTS)
Composer version 2.7.1 2024-02-09 15:26:28
nvm 0.39.7
and the next PHP extensions(modules)
PHP extensions
You can see your currently installed extensions using
php -mMy extensions look like so. Install them
[PHP Modules]
calendar
Core
ctype
curl
date
dom
exif
FFI
fileinfo
filter
ftp
gettext
hash
iconv
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
Phar
posix
random
readline
Reflection
session
shmop
SimpleXML
sockets
sodium
SPL
standard
sysvmsg
sysvsem
sysvshm
tokenizer
xml
xmlreader
xmlwriter
xsl
Zend OPcache
zlib
[Zend Modules]
Zend OPcache
- Start up infrastructure
docker compose up -d- Run migration for the DB
php artisan migrate- If you have errors, try
php artisan config:cache
php artisan config:clear
php artisan cache:clear- Select LTS Iron by running.
nvm use lts/iron- Start vite server for hot reload
npm run dev- Start the MPA
php artisan servedocker-compose file is here just to describe how to connect all docker images together. It is not suitable for local development. It also don't have build stage, so you have to build application by yourself and then pack it.
DON'T BUILD WITH DEV SERVER RUNNING!!!!
On the host PC:
nvm use lts/iron
npm run build
php artisan view:clear
php artisan route:clear
php artisan key:generate
export APP_VERSION=YOUR_VERSION_HERE
docker build -f .docker/php/Dockerfile -t s1ckret/gvary-web-reader-php:$APP_VERSION .
docker build -f .docker/nginx/Dockerfile -t s1ckret/gvary-web-reader-nginx:$APP_VERSION .
docker push s1ckret/gvary-web-reader-php:$APP_VERSION
docker push s1ckret/gvary-web-reader-nginx:$APP_VERSIONOn the target PC ONCE
scp ${PWD}/docker-compose.yml root@139.59.209.61:/root
scp ${PWD}/.env root@139.59.209.61:/rootThen change the images to reflect your version and either do docker compose up. Or use portainer. Don't forget to set env vars:
export POSTGRES_DB=
export POSTGRES_USER=
export POSTGRES_PASSWORD=Then edit .env file and it will automatically reflect in docker. (DO NOT USE VIM, only nano)
Also once you need to run a DB migration do this:
docker exec -it web-reader-php /bin/bash
php artisan migratedocker compose up -dAlso once you need to generate readonly Typesense API key and paste it into TYPESENSE_SEARCHONLY_API_KEY env var.
export TYPESENSE_API_KEY=xyz
curl 'http://localhost:8108/keys' \
-X POST \
-H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{"description":"Search-only cover key.","actions": ["documents:search"], "collections": ["cover_index"]}'Then you can import all entries
php artisan scout:import
docker exec -it web-reader-php /bin/bashThere is a good official documentation that describes the theory. In this section we will take a look a the practice.
- Login to the MPA (path
127.0.0.1/login) - Get
laravel_sessioncookies using dev tools - Execute the next curl
Fill in value for
laravel_sessioncookie.Accept,Content-TypeandOriginheaders are mandatory!
curl -v \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Origin: http://localhost:3000" \
-b "laravel_session=" \
-b ./cookie.txt -c ./cookie.txt \
127.0.0.1:8000/api/usercurl example
curl -v \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Origin: http://localhost:3000" \
-b "laravel_session=eyJpdiI6IlhSd3luWmsyaUpZUU1vSVR0QzdtRmc9PSIsInZhbHVlIjoiWDFOVVpHcmtVN1FvckcwNzRRb3BNL1QvaHZEL0dRaWErNnJjUWRHbmM2R0hiQUtvZ0EyblI3bjkyTDhHTngwMUZpaElsMjJCQmJCeGNFV3JLUUdpZDc2MWtROVlxcFA4MHl3QlpPdHBSbDVGWXc0cm1WNHVrd09oS0hvdXpjbmMiLCJtYWMiOiJiZjRhYjc5MzkzODBhMDJkYzU1YzdlMzIwN2I1MWM5YTUzNWY2ZmMzOWYwMWI4NTU3MDgyYmY1NmE2ZWY4YWRhIiwidGFnIjoiIn0%3D" \
127.0.0.1:8000/api/user- You should receive 200 - OK with response such as
{"user_id":2,"login":"olen","email":"olen@olen.com","email_verified_at":null,"created_at":"2024-02-27T07:26:39.000000Z","updated_at":"2024-02-27T07:26:39.000000Z","pen_name":"olen","first_name":"olen","last_name":"olen"}- Now your session cookie is saved to
cookie.txtfile so you can make requests without-bflag. E.g:
curl -v \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Origin: http://localhost:3000" \
-b ./cookie.txt -c ./cookie.txt \
127.0.0.1:8000/api/userYou should add X-XSRF-TOKEN header to your request. Copy value of XSRF-TOKEN cookie from your cookie.txt.
Note: Do NOT copy last three symbols
%3D!
Example:
curl \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Origin: http://localhost:3000" \
-b ./cookie.txt -c ./cookie.txt \
-H "X-XSRF-TOKEN: eyJpdiI6IkV0Z1FTMnpKNFVKbWgzVHdJRGlRS1E9PSIsInZhbHVlIjoiRWZnSk5rZk9VN0xBZGxTNVduSVFWMFdxdmpGK3N0d1VWcks4bmVDSVR2YlhLQ1E2a0JNVlhsYTd6RjRaUm5uMTRGMHFUejRiL0QwWHJZZytCSXRESFRJS1JFVzE4UFJsVVRmV2dBNTQ1a3BTZjAzSWkxN0U5S2dNMGc1TWtka2MiLCJtYWMiOiIwOTA2ZDQyMjZjNmJkODMwODQ5MzE1NDhlZDE4YmU4N2VlY2I3MDkyNTkyNzcwZjczYWQwYzU2ZWY3Mzc0Yjc3IiwidGFnIjoiIn0" \
-X POST \
-d '{"title": "chapter one", "cover_id": 4}' \
127.0.0.1:8000/api/chaptersphp artisan scribe:generate
- Navigate to
public/docs/index.html
Note: There is also a Postman collection and OpenAPI spec generated!
- Created
forgeuser in AWS IAM - Created access keys for
forgeuser - Logged into Forge
- Created new server
- Deleted
defaultsite - Created
dev.gvary.comsite - Install
gvary-ua/web-readerGitHub repo - Clicked
Deploy now - Created A DNS record pointing to public IP
- Created
Let's Encryptcertificate for SSL/TLS - Configured
.envfile with following
APP_URL="https://dev.gvary.com"
SANCTUM_STATEFUL_DOMAINS=editor.dev.gvary.com,dev.gvary.com
SESSION_DOMAIN=.dev.gvary.com
SESSION_SECURE_COOKIE=true- Added steps to build public assets
# For public/ folder
npm ci
npm run build
rm -rf node_modulesNote: Deploy script is adapted to GH Actions and won't work with Forge Branch you update on web site.
- Go to
Deploymentstab - Choose your branch and press
Update - Press
Deploy now
- Go to web-reader - Deploy
- Press
Run workflow - Select your branch and env to deploy
- Press green
Run workflow - Done!