Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: moved docker files into service #721

Merged
merged 1 commit into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .docker/dbtest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
$DB_HOST = $argv[1];
$DB_BASE = $argv[2];
$DB_PORT = $argv[3];
$DB_USER = $argv[4];
$DB_PASS = $argv[5];

# echo "Testing DB:";
# echo "*";
# echo "* new \PDO(mysql:host=$DB_HOST;dbname=$DB_BASE;port=$DB_PORT, $DB_USER, $DB_PASS, [ \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION ]);";
# echo "*";

try {
$pdo = new \PDO("mysql:host=$DB_HOST;dbname=$DB_BASE;port=$DB_PORT", "$DB_USER", "$DB_PASS", [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
]);
} catch(\Exception $ex) {
switch ($ex->getCode()) {
// we can immediately stop startup here and show the error message
case 1045:
echo 'Access denied (1045)';
die(1);
// we can immediately stop startup here and show the error message
case 1049:
echo 'Unknown database (1049)';
die(2);
// a lot of errors share the same meaningless error code zero
case 0:
// this error includes the database name, so we can only search for the static part of the error message
if (stripos($ex->getMessage(), 'SQLSTATE[HY000] [1049] Unknown database') !== false) {
echo 'Unknown database (0-1049)';
die(3);
}
switch ($ex->getMessage()) {
// eg. no response (fw) - the startup script should retry it a couple of times
case 'SQLSTATE[HY000] [2002] Operation timed out':
echo 'Operation timed out (0-2002)';
die(4);
// special case "localhost" with a stopped db server (should not happen in docker compose setup)
case 'SQLSTATE[HY000] [2002] No such file or directory':
echo 'Connection could not be established (0-2002)';
die(5);
// using IP with stopped db server - the startup script should retry it a couple of times
case 'SQLSTATE[HY000] [2002] Connection refused':
echo 'Connection refused (0-2002)';
die(5);
}
echo $ex->getMessage() . " (0)";
die(7);
default:
// unknown error
echo $ex->getMessage() . " (?)";
die(10);
}
}
83 changes: 83 additions & 0 deletions .docker/entry-point.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/bin/bash -x

function checkDatabase() {
echo "Wait for MySQL DB connection ..."
echo -n "Checking DB"
until php /dbtest.php "$DB_HOST" "$DB_DATABASE" "$DB_PORT" "$DB_USERNAME" "$DB_PASSWORD"; do
echo -n "."
sleep 3
done
echo " ✅ Connection established"
}

function handleStartup() {
# in production we will have a .env mounted into the container, this will have (at least) a
# APP_KEY, if we don't have a .env we will create one
if [ ! -e /opt/project/.env ]; then
if [ "$APP_ENV" == "production" ]; then
echo "No .env file present."
echo "Your are running a prod environment version but there is no .env file present"
echo "You need to mount one into this container or the system cannot proceed."
exit 1
else
touch .env
fi
fi

grep APP_KEY .env
# shellcheck disable=SC2181
if [ "$?" != 0 ]; then
echo "APP_KEY=''" > .env
php /opt/project/artisan key:generate
fi

# These are idempotent, run them anyway
php /opt/project/artisan migrate
if [ "$APP_ENV" == "local" ] || [ "$APP_ENV" == "dev" ] || [ "$APP_ENV" == "development" ] ; then
# check the DB, if there are no vouchers install fixtures
voucher_count=$(/opt/project/artisan tinker --execute='print(App\Voucher::all()->count()))')
if [ "$voucher_count" == "0" ]; then
php /opt/project/artisan migrate:refresh --seed --force
fi
fi

php /passport-install.php

if [ -e /docker-entrypoint-initdb.d ]; then
for filename in /docker-entrypoint-init.d/*; do
if [ "${filename##*.}" == "sh" ]; then
# shellcheck disable=SC1090
source /docker-entrypoint-initdb.d/"$filename"
fi
done
fi
yarn production
}

checkDatabase
handleStartup

if [ -n "$RUN_AS" ]; then
GROUP_ID=${RUN_AS#*:}
USER_ID=${RUN_AS%:*} # drops substring from last occurrence of `SubStr` to end of string

GROUP_NAME=$(id -ng "$GROUP_ID")
if [ -z "$GROUP_NAME" ]; then
addgroup --gid "$GROUP_ID" arcuser
GROUP_NAME=arcuser
fi

USER_NAME=$(id -n "$USER_ID")
if [ -z "$USER_NAME" ]; then
adduser -G "$GROUP_NAME" -u "$USER_ID" arcuser
USER_NAME=arcuser
fi
sed -i "s/user = www-data/user = $USER_NAME/g" /usr/local/etc/php-fpm.d/www.conf
sed -i "s/group = www-data/group = $GROUP_NAME/g" /usr/local/etc/php-fpm.d/www.conf

chown -R $USER_NAME:$GROUP_NAME /opt/project/storage
fi

exec php-fpm

exit
40 changes: 40 additions & 0 deletions .docker/passport-install.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

if (! is_writeable("/opt/project/.env")) {
echo "Can't write to .env file\n";
exit(1);
}

$contents = file_get_contents("/opt/project/.env");
if (getenv("APP_ENV") == "prod" && strpos($contents, "PASSWORD_CLIENT_SECRET")) {
echo "PASSWORD_CLIENT_SECRET exists and env is production, not overwriting\n";
exit(0);
}

$lines = explode("\n", $contents);
$cleaned = [];
print_r($lines);
foreach ($lines as $line) {
if (!strpos($line, "PASSWORD_CLIENT") || !strpos($line, "PASSWORD_CLIENT_SECRET")) {
$cleaned[] = $line;
}
}

$output = [];

exec('php artisan passport:keys --force');
exec("php artisan passport:client --password --name '" . getenv("APP_NAME") . " Password Grant Client' --provider=users", $output);
print_r($output);
foreach ($output as $line) {
if (str_starts_with($line, "Client ID")) {
$elements = explode(" ", $line);
$cleaned[] = "PASSWORD_CLIENT=" . $elements[2];
}
if (str_starts_with($line, "Client secret")) {
$elements = explode(" ", $line);
$cleaned[] = "PASSWORD_CLIENT_SECRET=" . $elements[2];
}
}
exec("chmod 600 /opt/project/storage/*.key");

file_put_contents("/opt/project/.env", implode("\n", $lines + $cleaned));
6 changes: 6 additions & 0 deletions .docker/xdebug.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
zend_extension=xdebug

[xdebug]
xdebug.mode=develop,debug
xdebug.client_host=host.docker.internal
xdebug.start_with_request=yes
18 changes: 11 additions & 7 deletions .github/workflows/build-and-push-to-dockerhub.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
name: Build and Push to Docker Hub

on:
workflow_dispatch:
# on:
# push:
# branches:
# - main # Replace with your branch name
push:
branches:
- '*'
pull_request:
types:
- 'opened'
- 'synchronize'

jobs:
build-and-push:
Expand All @@ -20,5 +22,7 @@ jobs:

- name: Build and push Docker image
run: |
docker build -t arc/service:latest .
docker push arc/service:latest
docker build -t arcvouchers/service:v${EVENT_NUMBER} .
docker push arcvouchers/service:v${EVENT_NUMBER}
env:
EVENT_NUMBER: "${{ github.event.number }}"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ tests/Browser/screenshots/
passport.install
coverage
.php-cs-fixer.cache
*.swp
Loading
Loading