-
-
Save mpociot/1d6809a600701beca4fa544551acd2de to your computer and use it in GitHub Desktop.
/bin/bash -c "$(curl -fsSL https://php.new/install/linux)" | |
export PATH="/root/.config/herd-lite/bin/:$PATH" | |
composer install | |
cp .env.example .env | |
php artisan key:generate | |
php artisan migrate --seed --force -n | |
npm install | |
npm run build |
here is the version with MySQL
IT WORKS
`#!/usr/bin/env bash
this makes the script strict:
-e: exit on any error
-u: error on undefined variables
-o pipefail: exit if any command in a pipeline fails
set -euo pipefail
Adds a package repository that provides the latest PHP versions
(see https://deb.sury.org/ for details)
add-apt-repository -y ppa:ondrej/php
Updates package lists to get the latest information about available packages
apt-get update
Install PHP 8.4 and extensions commonly needed for Symfony applications
apt-get install -y
php8.4
php8.4-cli
php8.4-mbstring
php8.4-xml
php8.4-intl
php8.4-gd
php8.4-zip
php8.4-curl
php8.4-mysql # ✅ Also switch from pgsql to mysql now
This makes PHP 8.4 available through the global 'php' binary,
which is expected by many commands
update-alternatives --install /usr/bin/php php /usr/bin/php8.4 84
update-alternatives --set php /usr/bin/php8.4
Install Composer as a global 'composer' binary following the safest practices
EXPECTED_CHECKSUM="$(curl -fsSL https://composer.github.io/installer.sig)"
curl -fsSL https://getcomposer.org/installer -o composer-setup.php
ACTUAL_CHECKSUM="$(sha384sum composer-setup.php | cut -d ' ' -f 1)"
if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]; then
echo 'ERROR: Invalid composer installer checksum.' >&2
rm composer-setup.php
exit 1
fi
php composer-setup.php --install-dir=/usr/local/bin --filename=composer --quiet
rm composer-setup.php
Install the PHP dependencies of your project;
private packages require some more work explained later in this article
composer install --ignore-platform-req=ext-bcmath
Show installed versions to check if everything worked
php -v
composer --version
Load Laravel-style environment variables
DB_DATABASE="${DB_DATABASE:-mydb}"
DB_USERNAME="${DB_USERNAME:-myuser}"
DB_PASSWORD="${DB_PASSWORD:-mypassword}"
Default MySQL root password (optional, can be customized)
MYSQL_ROOT_PASSWORD="${MYSQL_ROOT_PASSWORD:-root}"
apt-get install -y mysql-client mysql-common mysql-server-core-8.0
mkdir -p /tmp/mysql-data
mysqld --initialize-insecure --datadir=/tmp/mysql-data
Fix for secure-file-priv error
mkdir -p /var/lib/mysql-files
Start MySQL manually
nohup mysqld --user=root --datadir=/tmp/mysql-data --socket=/tmp/mysql.sock > /tmp/mysql.log 2>&1 &
Wait for socket
echo "Waiting for MySQL to be ready..."
for i in {30..0}; do
if [ -S /tmp/mysql.sock ]; then
echo "✅ MySQL socket is ready"
break
fi
sleep 1
done
if ! [ -S /tmp/mysql.sock ]; then
echo "❌ MySQL failed to start"
tail -n 50 /tmp/mysql.log || true
exit 1
fi
Setup user/db
mysql -u root --socket=/tmp/mysql.sock <<-EOSQL
CREATE DATABASE IF NOT EXISTS `${DB_DATABASE}`;
CREATE USER IF NOT EXISTS '${DB_USERNAME}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
GRANT ALL PRIVILEGES ON `${DB_DATABASE}`.* TO '${DB_USERNAME}'@'localhost';
FLUSH PRIVILEGES;
EOSQL
Show installed MySQL version
mysql --version
cp .env.example .env
php artisan key:generate
php artisan migrate --seed --force -n
npm install --no-save
npm run build`
here is the version with MySQL IT WORKS
link to the original article:
https://dev.to/javiereguiluz/how-to-make-chatgpt-codex-work-with-php-and-symfony-4lj8
I've created a script here that uses
- MySQL
- Meilisearch
- Yarn (Instead of NPM)
Codex Environment Settings:
- Agent internet access => Off
- Image => universal
- Secrets => None
- Environment variables => None
Here the script
#!/usr/bin/env bash
# Fail fast, fail loud.
set -euo pipefail
################################################################################
# 1. PHP & Composer ############################################################
################################################################################
add-apt-repository -y ppa:ondrej/php
apt-get update
apt-get install -y \
php8.4 php8.4-cli php8.4-mbstring php8.4-xml php8.4-intl \
php8.4-gd php8.4-zip php8.4-curl php8.4-mysql \
curl gnupg lsb-release ca-certificates
update-alternatives --install /usr/bin/php php /usr/bin/php8.4 84
update-alternatives --set php /usr/bin/php8.4
EXPECTED_CHECKSUM="$(curl -fsSL https://composer.github.io/installer.sig)"
curl -fsSL https://getcomposer.org/installer -o composer-setup.php
ACTUAL_CHECKSUM="$(sha384sum composer-setup.php | cut -d ' ' -f 1)"
[ "$EXPECTED_CHECKSUM" = "$ACTUAL_CHECKSUM" ] || { echo "Composer installer corrupt" >&2; exit 1; }
php composer-setup.php --install-dir=/usr/local/bin --filename=composer --quiet
rm composer-setup.php
composer install --ignore-platform-req=ext-bcmath
php -v; composer -V
################################################################################
# 2. Node.js & Yarn ############################################################
################################################################################
NODE_VERSION="${NODE_VERSION:-20}"
YARN_VERSION="${YARN_VERSION:-1.22.22}"
# Install the desired Node LTS via NodeSource
curl -fsSL "https://deb.nodesource.com/setup_${NODE_VERSION}.x" | bash -
apt-get install -y nodejs
# ---------------------------------------------------------------------------
# Yarn (via Corepack)
# ---------------------------------------------------------------------------
# Node ≥16 ships with Corepack, which can activate pinned versions of Yarn.
# This avoids npm‑global install conflicts and sticks to a reproducible version.
if ! command -v corepack >/dev/null 2>&1; then
# Fallback for odd Node builds that omit Corepack
npm install -g corepack
fi
corepack enable
corepack prepare "yarn@${YARN_VERSION}" --activate
node -v; yarn -v
################################################################################
# 3. MySQL (local, socket‑based) ###############################################
################################################################################
DB_DATABASE="${DB_DATABASE:-mydb}"
DB_USERNAME="${DB_USERNAME:-myuser}"
DB_PASSWORD="${DB_PASSWORD:-mypassword}"
export DB_CONNECTION=mysql
export DB_HOST=127.0.0.1
export DB_PORT=3306
export DB_DATABASE DB_USERNAME DB_PASSWORD
apt-get install -y mysql-client mysql-common mysql-server-core-8.0
MYSQL_DATADIR="/tmp/mysql-data"; MYSQL_SOCKET="/tmp/mysql.sock"
mkdir -p "$MYSQL_DATADIR"
mysqld --initialize-insecure --datadir="$MYSQL_DATADIR"
mkdir -p /var/lib/mysql-files
nohup mysqld --user=root --datadir="$MYSQL_DATADIR" --socket="$MYSQL_SOCKET" \
> /tmp/mysql.log 2>&1 &
printf "Waiting for MySQL"; for _ in {30..0}; do
if mysqladmin --socket="$MYSQL_SOCKET" ping --silent 2>/dev/null; then
echo -e "\r✅ MySQL ready "; break; fi
printf "."; sleep 1; done
mysqladmin --socket="$MYSQL_SOCKET" ping --silent >/dev/null || { tail -n 50 /tmp/mysql.log; exit 1; }
mysql -u root --socket="$MYSQL_SOCKET" <<SQL
CREATE DATABASE IF NOT EXISTS \`$DB_DATABASE\`;
CREATE USER IF NOT EXISTS '$DB_USERNAME'@'%' IDENTIFIED BY '$DB_PASSWORD';
GRANT ALL PRIVILEGES ON \`$DB_DATABASE\`.* TO '$DB_USERNAME'@'%';
FLUSH PRIVILEGES;
SQL
mysql --version
################################################################################
# 4. Meilisearch (needed by seeders) ###########################################
################################################################################
MEILI_VERSION="${MEILI_VERSION:-latest}"
MEILI_MASTER_KEY="${MEILI_MASTER_KEY:-masterKey}"
MEILISEARCH_BIN="/usr/local/bin/meilisearch"
MEILISEARCH_HOST="http://127.0.0.1:7700"
if [ ! -x "$MEILISEARCH_BIN" ]; then
echo "Installing Meilisearch ($MEILI_VERSION) …"
if [ "$MEILI_VERSION" = "latest" ]; then
curl -L https://install.meilisearch.com | sh
else
ASSET_URL="https://github.com/meilisearch/meilisearch/releases/download/${MEILI_VERSION}/meilisearch-linux-amd64"
if ! curl -fSL "$ASSET_URL" -o meilisearch; then
echo "⚠️ Version $MEILI_VERSION not found – falling back to latest" >&2
curl -L https://install.meilisearch.com | sh
fi
fi
chmod +x ./meilisearch
mv ./meilisearch "$MEILISEARCH_BIN"
fi
export MEILISEARCH_HOST MEILISEARCH_KEY="$MEILI_MASTER_KEY"
nohup "$MEILISEARCH_BIN" --master-key "$MEILI_MASTER_KEY" --http-addr "127.0.0.1:7700" \
> /tmp/meilisearch.log 2>&1 &
printf "Waiting for Meilisearch"; for _ in {30..0}; do
if curl -sf "$MEILISEARCH_HOST/health" >/dev/null; then
echo -e "\r✅ Meilisearch healthy "; break; fi
printf "."; sleep 1; done
curl -sf "$MEILISEARCH_HOST/health" >/dev/null || { echo; tail -n 50 /tmp/meilisearch.log; exit 1; }
################################################################################
# 5. Build the Laravel application ############################################
################################################################################
cp .env.example .env
update_env() {
local key="$1"
local value="$2"
# Escape replacement string for sed (handles /, \ and &)
local escaped_value
escaped_value=$(printf '%s' "$value" | sed -e 's/[\\/&]/\\&/g')
if grep -q "^$key=" .env; then
sed -i "s|^$key=.*|$key=$escaped_value|" .env
else
echo "$key=$value" >> .env
fi
}
update_env DB_HOST 127.0.0.1
update_env DB_DATABASE "$DB_DATABASE"
update_env DB_USERNAME "$DB_USERNAME"
update_env DB_PASSWORD "$DB_PASSWORD"
update_env MEILISEARCH_HOST "$MEILISEARCH_HOST"
update_env MEILISEARCH_KEY "$MEILI_MASTER_KEY"
php artisan key:generate
php artisan migrate --seed --force -n
# JavaScript dependencies & build (Yarn Classic tolerates peer conflicts)
yarn install --non-interactive --no-progress
yarn run build
################################################################################
# Done #########################################################################
################################################################################
I've created a script here that uses
- MySQL
- Meilisearch
- Yarn (Instead of NPM)
Codex Environment Settings:
- Agent internet access => Off
- Image => universal
- Secrets => None
- Environment variables => None
Here the script
#!/usr/bin/env bash # Fail fast, fail loud. set -euo pipefail ################################################################################ # 1. PHP & Composer ############################################################ ################################################################################ add-apt-repository -y ppa:ondrej/php apt-get update apt-get install -y \ php8.4 php8.4-cli php8.4-mbstring php8.4-xml php8.4-intl \ php8.4-gd php8.4-zip php8.4-curl php8.4-mysql \ curl gnupg lsb-release ca-certificates update-alternatives --install /usr/bin/php php /usr/bin/php8.4 84 update-alternatives --set php /usr/bin/php8.4 EXPECTED_CHECKSUM="$(curl -fsSL https://composer.github.io/installer.sig)" curl -fsSL https://getcomposer.org/installer -o composer-setup.php ACTUAL_CHECKSUM="$(sha384sum composer-setup.php | cut -d ' ' -f 1)" [ "$EXPECTED_CHECKSUM" = "$ACTUAL_CHECKSUM" ] || { echo "Composer installer corrupt" >&2; exit 1; } php composer-setup.php --install-dir=/usr/local/bin --filename=composer --quiet rm composer-setup.php composer install --ignore-platform-req=ext-bcmath php -v; composer -V ################################################################################ # 2. Node.js & Yarn ############################################################ ################################################################################ NODE_VERSION="${NODE_VERSION:-20}" YARN_VERSION="${YARN_VERSION:-1.22.22}" # Install the desired Node LTS via NodeSource curl -fsSL "https://deb.nodesource.com/setup_${NODE_VERSION}.x" | bash - apt-get install -y nodejs # --------------------------------------------------------------------------- # Yarn (via Corepack) # --------------------------------------------------------------------------- # Node ≥16 ships with Corepack, which can activate pinned versions of Yarn. # This avoids npm‑global install conflicts and sticks to a reproducible version. if ! command -v corepack >/dev/null 2>&1; then # Fallback for odd Node builds that omit Corepack npm install -g corepack fi corepack enable corepack prepare "yarn@${YARN_VERSION}" --activate node -v; yarn -v ################################################################################ # 3. MySQL (local, socket‑based) ############################################### ################################################################################ DB_DATABASE="${DB_DATABASE:-mydb}" DB_USERNAME="${DB_USERNAME:-myuser}" DB_PASSWORD="${DB_PASSWORD:-mypassword}" export DB_CONNECTION=mysql export DB_HOST=127.0.0.1 export DB_PORT=3306 export DB_DATABASE DB_USERNAME DB_PASSWORD apt-get install -y mysql-client mysql-common mysql-server-core-8.0 MYSQL_DATADIR="/tmp/mysql-data"; MYSQL_SOCKET="/tmp/mysql.sock" mkdir -p "$MYSQL_DATADIR" mysqld --initialize-insecure --datadir="$MYSQL_DATADIR" mkdir -p /var/lib/mysql-files nohup mysqld --user=root --datadir="$MYSQL_DATADIR" --socket="$MYSQL_SOCKET" \ > /tmp/mysql.log 2>&1 & printf "Waiting for MySQL"; for _ in {30..0}; do if mysqladmin --socket="$MYSQL_SOCKET" ping --silent 2>/dev/null; then echo -e "\r✅ MySQL ready "; break; fi printf "."; sleep 1; done mysqladmin --socket="$MYSQL_SOCKET" ping --silent >/dev/null || { tail -n 50 /tmp/mysql.log; exit 1; } mysql -u root --socket="$MYSQL_SOCKET" <<SQL CREATE DATABASE IF NOT EXISTS \`$DB_DATABASE\`; CREATE USER IF NOT EXISTS '$DB_USERNAME'@'%' IDENTIFIED BY '$DB_PASSWORD'; GRANT ALL PRIVILEGES ON \`$DB_DATABASE\`.* TO '$DB_USERNAME'@'%'; FLUSH PRIVILEGES; SQL mysql --version ################################################################################ # 4. Meilisearch (needed by seeders) ########################################### ################################################################################ MEILI_VERSION="${MEILI_VERSION:-latest}" MEILI_MASTER_KEY="${MEILI_MASTER_KEY:-masterKey}" MEILISEARCH_BIN="/usr/local/bin/meilisearch" MEILISEARCH_HOST="http://127.0.0.1:7700" if [ ! -x "$MEILISEARCH_BIN" ]; then echo "Installing Meilisearch ($MEILI_VERSION) …" if [ "$MEILI_VERSION" = "latest" ]; then curl -L https://install.meilisearch.com | sh else ASSET_URL="https://github.com/meilisearch/meilisearch/releases/download/${MEILI_VERSION}/meilisearch-linux-amd64" if ! curl -fSL "$ASSET_URL" -o meilisearch; then echo "⚠️ Version $MEILI_VERSION not found – falling back to latest" >&2 curl -L https://install.meilisearch.com | sh fi fi chmod +x ./meilisearch mv ./meilisearch "$MEILISEARCH_BIN" fi export MEILISEARCH_HOST MEILISEARCH_KEY="$MEILI_MASTER_KEY" nohup "$MEILISEARCH_BIN" --master-key "$MEILI_MASTER_KEY" --http-addr "127.0.0.1:7700" \ > /tmp/meilisearch.log 2>&1 & printf "Waiting for Meilisearch"; for _ in {30..0}; do if curl -sf "$MEILISEARCH_HOST/health" >/dev/null; then echo -e "\r✅ Meilisearch healthy "; break; fi printf "."; sleep 1; done curl -sf "$MEILISEARCH_HOST/health" >/dev/null || { echo; tail -n 50 /tmp/meilisearch.log; exit 1; } ################################################################################ # 5. Build the Laravel application ############################################ ################################################################################ cp .env.example .env update_env() { local key="$1" local value="$2" # Escape replacement string for sed (handles /, \ and &) local escaped_value escaped_value=$(printf '%s' "$value" | sed -e 's/[\\/&]/\\&/g') if grep -q "^$key=" .env; then sed -i "s|^$key=.*|$key=$escaped_value|" .env else echo "$key=$value" >> .env fi } update_env DB_HOST 127.0.0.1 update_env DB_DATABASE "$DB_DATABASE" update_env DB_USERNAME "$DB_USERNAME" update_env DB_PASSWORD "$DB_PASSWORD" update_env MEILISEARCH_HOST "$MEILISEARCH_HOST" update_env MEILISEARCH_KEY "$MEILI_MASTER_KEY" php artisan key:generate php artisan migrate --seed --force -n # JavaScript dependencies & build (Yarn Classic tolerates peer conflicts) yarn install --non-interactive --no-progress yarn run build ################################################################################ # Done ######################################################################### ################################################################################
Here's a smaller version which pulls from my Gist's.
#!/usr/bin/env bash
###############################################################################
# Codex Laravel: lightweight orchestrator ######################################
###############################################################################
# This tiny entry‑point just stitches together a handful of *modular* scripts
# you now keep in public GitHub gists. Each gist handles one concern (PHP/Composer,
# Yarn/Node, MySQL, Meilisearch). The big upside is that you can iterate on any
# of those pieces in isolation without touching this file.
###############################################################################
set -euo pipefail
###############################################################################
# 0. Defaults & env ...........................................................
###############################################################################
# -----------------------------------------------------------------------------
# Database credentials (used by both MySQL & Laravel)
# -----------------------------------------------------------------------------
DB_DATABASE="${DB_DATABASE:-mydb}"
DB_USERNAME="${DB_USERNAME:-myuser}"
DB_PASSWORD="${DB_PASSWORD:-mypassword}"
export DB_DATABASE DB_USERNAME DB_PASSWORD
# -----------------------------------------------------------------------------
# Node/Yarn versions (used by the Yarn setup gist)
# -----------------------------------------------------------------------------
NODE_VERSION="${NODE_VERSION:-20}"
YARN_VERSION="${YARN_VERSION:-1.22.22}"
export NODE_VERSION YARN_VERSION
# -----------------------------------------------------------------------------
# Meilisearch versions / credentials
# -----------------------------------------------------------------------------
MEILI_VERSION="${MEILI_VERSION:-latest}"
MEILI_MASTER_KEY="${MEILI_MASTER_KEY:-masterKey}"
export MEILI_VERSION MEILI_MASTER_KEY
###############################################################################
# Helper – download & execute a gist ..........................................
###############################################################################
run_gist() {
local raw_url="$1"
echo -e "\n🔽 Running remote gist: $raw_url\n"
curl -fsSL "$raw_url" | bash -s --
}
###############################################################################
# 1. PHP & Composer ............................................................
###############################################################################
run_gist "https://gist.githubusercontent.com/AniTexs/63c116ccbabc78831fd45ad94398bfa3/raw"
###############################################################################
# 2. Node.js & Yarn ............................................................
###############################################################################
run_gist "https://gist.githubusercontent.com/AniTexs/5a31efa79f6b5708449a3067cd12d25a/raw"
###############################################################################
# 3. MySQL (local) .............................................................
###############################################################################
run_gist "https://gist.githubusercontent.com/AniTexs/10ce4272a96763c53c4e46bfbd91c49c/raw"
###############################################################################
# 4. Meilisearch ...............................................................
###############################################################################
run_gist "https://gist.githubusercontent.com/AniTexs/99e66d818a21cdce70c6c0f3f256c99a/raw"
###############################################################################
# 5. Build Laravel app ........................................................
###############################################################################
# -- .env ----------------------------------------------------------------------
cp .env.example .env
update_env() {
local key="$1"; local value="$2"
local escaped_value
escaped_value=$(printf '%s' "$value" | sed -e 's/[\\/&]/\\&/g')
if grep -q "^$key=" .env; then
sed -i "s|^$key=.*|$key=$escaped_value|" .env
else
echo "$key=$value" >> .env
fi
}
update_env DB_HOST 127.0.0.1
update_env DB_DATABASE "$DB_DATABASE"
update_env DB_USERNAME "$DB_USERNAME"
update_env DB_PASSWORD "$DB_PASSWORD"
update_env MEILISEARCH_HOST "http://127.0.0.1:7700"
update_env MEILISEARCH_KEY "$MEILI_MASTER_KEY"
# -- Laravel -------------------------------------------------------------------
php artisan key:generate
php artisan migrate --seed --force -n
# -- JavaScript deps & build ----------------------------------------------------
yarn install --non-interactive --no-progress
yarn run build
###############################################################################
# Done #########################################################################
###############################################################################
Thanks for this script. How do you deal with the DB? I'm not managing to get mysql nor sqlite working out of the box on codex. Did you add a special feature somewhere else?
Additionally, why
npm install
and notnpm install --no-save
(which would avoid merging problems, no?) and whycomposer install
and notcomposer install --no-interaction --prefer-dist --optimize-autoloader
(which has less chance in getting blocked)? Just asking to learn and to see whether it can be improved.