diff --git a/.dockerignore b/.dockerignore index 73f87237..7fc82ca7 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,4 @@ -bootstrap/cache/services.php +bootstrap/cache/* storage/app/* storage/framework/cache/* diff --git a/.env.development b/.env.development deleted file mode 100644 index 1ef629a1..00000000 --- a/.env.development +++ /dev/null @@ -1,35 +0,0 @@ -APP_NAME=SINF -APP_ENV=local # Use "maintenance" to enable the maitenance page -APP_KEY=base64:AVegBkyjHs2QQsx53M9Kt9GbnrDLc6yG4cRg+WMJrbA= -APP_DEBUG=true -APP_URL=http://localhost:8000 -APP_PORT=8000 - -LOCALE=pt -FAKER_LOCALE=pt_PT - -DB_HOST=pgsql -DB_PORT=5432 -DB_USERNAME=postgres -DB_PASSWORD=postgres -DB_DATABASE=sinf-website-2023 -DB_CONNECTION=pgsql - -MAIL_HOST=mailpit -MAIL_PORT=1025 - -REDIS_HOST=redis - -MAINTENANCE_DRIVER=cache - -CACHE_DRIVER=redis - -QUEUE_CONNECTION=redis - -SCOUT_QUEUE=true -SCOUT_DRIVER=meilisearch -MEILISEARCH_HOST=http://meilisearch:7700 - -MEILISEARCH_NO_ANALYTICS=false - -LOG_CHANNEL="sinfWebsite" \ No newline at end of file diff --git a/.env.railway.encrypted b/.env.railway.encrypted new file mode 100644 index 00000000..cf05d733 --- /dev/null +++ b/.env.railway.encrypted @@ -0,0 +1 @@ +eyJpdiI6IjM4ckdUdk1XazMxQjA4RnpTRUZhc3c9PSIsInZhbHVlIjoib1Q3UWtxdzdjSytwMGVRMW9MT2lERlVxclpTK05mUDk1dlhJd2NwbmtkRnFWZTExV2NZdEROMG8zb2N5ZEN1MW5tMk5JbHMxdDh4Z0NsSzYvdy9TdWNKQ3hBMVhncVMxZkFiSkJLR2VZa0JRMUZYbnF0YXJya0NsN2UwemVkMGpnaUw5Y1Z6enBtcnBPWkR3MW1mRENnU2cvcm9rSXNLMzllV3I0QitKL0xvR0J4MHhhWCtMZERYd3pNeHJiMnBINW42a1dCWkVBNmRhTU14T3FvVzgrMjh3ODd3LzMxcnUzcmRWTjZ2OW1qMis2dkVvRWtINlBmN3YzSXR4Mm12VnJFeGZyckdtL3dwQnhvRWIrTEl0WFJNU2ZEbE5pOTJEaW9LOHlLZ0ZEMjlYdTBBakJma3NvRDdidUZ0bVRkWnZUVmtCVG1oTFBZZEVOa0xyNVdnTExzdGxNL3JLcjJOQ2VqTEh4VGV0LzBJMm5WNm5VWlVRMU50bng3UzhkVnVzVkNGWWtYYTBjS1VEbXNLMk02RHhoQnFUbWVZZGREOEhPQURpejhBY3IwVHlGNGs5THZraUZ2NTZxdTB5L095bFk1d25Za3JiNU1mSUU1YUlMV0VHZzRNVVJOa0dQRXFjM3MvY0ZJSEh2eDZITFMrbDFzV1JaaUFHRWcrV1Fjb0lEVWNKaEFIVFAya1I2RUZZZi9odS82OVZmSTNhek40L2dub2IrYlkvM29rd01uRytiZEVJQ3cwaTZoaHRUeXNDTVEzd0hiTVNsc2NzMWRhOUJpSUJFQjg3dlRkdHE4WTkvdmVudFZ2YjZtY1Ryd1dNWjZ5SGxWZkhMeEhFR2MycSIsIm1hYyI6ImFiZTIyM2NkOTYxYmNkNDA4ZWViZWVlOGIyY2IzNGEwMGFlOGQ4NGM1MGYwNDY2ZWE4ODY5YjllN2ZiOWUxZTgiLCJ0YWciOiIifQ== \ No newline at end of file diff --git a/.gitignore b/.gitignore index 49613eb3..6d3dd272 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,8 @@ /storage/*.key /vendor .env.backup -.env.prod +.env.production +.env.railway .phpunit.result.cache Homestead.json Homestead.yaml diff --git a/Dockerfile b/Dockerfile.old similarity index 100% rename from Dockerfile rename to Dockerfile.old diff --git a/app/Console/Commands/CreateDbSchema.php b/app/Console/Commands/CreateDbSchema.php new file mode 100644 index 00000000..5dbfbc26 --- /dev/null +++ b/app/Console/Commands/CreateDbSchema.php @@ -0,0 +1,37 @@ + "public", + ]); + + $search_path = config('database.connections.pgsql.search_path'); + $conn->statement("CREATE SCHEMA IF NOT EXISTS $search_path"); + } +} diff --git a/config/database.php b/config/database.php index 8751af79..2439991d 100644 --- a/config/database.php +++ b/config/database.php @@ -74,7 +74,7 @@ 'charset' => 'utf8', 'prefix' => '', 'prefix_indexes' => true, - 'search_path' => env('DB_SEARCH_PATH', 'public'), + 'search_path' => str_replace('-', '_', env('DB_SEARCH_PATH', 'public')), 'sslmode' => 'prefer', ], diff --git a/docker-compose.yml b/docker-compose.yml index e701feec..28da5099 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,8 +30,11 @@ services: prod: build: context: . - dockerfile: Dockerfile - target: production + dockerfile: ./dockerfiles/Dockerfile.website + target: deploy + args: + - LARAVEL_ENV=local + - LARAVEL_ENV_FILE=.env ports: - '80:80' networks: @@ -40,15 +43,17 @@ services: - pgsql - redis - meilisearch + environment: + - APP_URL=http://localhost pgsql: - image: 'postgres:15' + image: 'postgres:16' ports: - '${FORWARD_DB_PORT:-5432}:5432' environment: - PGPASSWORD: '${DB_PASSWORD:-secret}' + PGPASSWORD: '${DB_PASSWORD}' POSTGRES_DB: '${DB_DATABASE}' POSTGRES_USER: '${DB_USERNAME}' - POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}' + POSTGRES_PASSWORD: '${DB_PASSWORD}' volumes: - 'sail-pgsql:/var/lib/postgresql/data' - './vendor/laravel/sail/database/pgsql/create-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql' diff --git a/dockerfiles/Dockerfile.seeder b/dockerfiles/Dockerfile.seeder new file mode 100644 index 00000000..55c47b69 --- /dev/null +++ b/dockerfiles/Dockerfile.seeder @@ -0,0 +1,35 @@ +# dependencies +FROM composer:2 AS dependencies +WORKDIR /app + +COPY composer.json composer.lock artisan ./ +COPY app/ ./app/ +COPY bootstrap/ ./bootstrap/ +COPY config/ ./config/ +COPY database/ ./database/ +COPY resources/ ./resources/ +COPY routes/ ./routes/ + +RUN composer install --no-interaction + +# migrate +FROM composer:2 AS migrate +WORKDIR /app + +RUN install-php-extensions pdo_pgsql pgsql redis iconv zip + +COPY --from=dependencies /app ./ + +ARG LARAVEL_ENV=production +ARG LARAVEL_ENV_FILE=.env.${LARAVEL_ENV} +ARG LARAVEL_ENV_FILE_KEY="" + +ENV APP_ENV=${LARAVEL_ENV} + +COPY --chown=nobody ${LARAVEL_ENV_FILE} ./.env.${LARAVEL_ENV} +RUN [ -z "${LARAVEL_ENV_FILE_KEY}" ] || ( mv .env.${LARAVEL_ENV} .env.${LARAVEL_ENV}.encrypted && php artisan env:decrypt -n --env=${LARAVEL_ENV} --key=${LARAVEL_ENV_FILE_KEY} ) + +COPY public/ ./public/ +COPY storage/ ./storage/ + +CMD [ "php", "artisan", "migrate", "-n"] diff --git a/dockerfiles/Dockerfile.website b/dockerfiles/Dockerfile.website new file mode 100644 index 00000000..c2208c51 --- /dev/null +++ b/dockerfiles/Dockerfile.website @@ -0,0 +1,81 @@ +# dev-dependencies +FROM composer:2 AS dev-dependencies +WORKDIR /app + +COPY composer.json composer.lock ./ +RUN composer install --no-interaction --no-autoloader + +# assets-build +FROM node:20-alpine AS assets-build +WORKDIR /app + +COPY package.json package-lock.json ./ +RUN npm install + +COPY ./resources/ ./resources +COPY ./vite.config.ts ./tsconfig.json ./tsconfig.app.json ./tsconfig.node.json ./tailwind.config.js ./postcss.config.js ./ +COPY --from=dev-dependencies /app/vendor ./vendor + +RUN npm run build + +# laravel-build +FROM composer:2 AS laravel-build +WORKDIR /app + +COPY composer.json composer.lock artisan ./ +COPY app/ ./app/ +COPY bootstrap/ ./bootstrap/ +COPY config/ ./config/ +COPY database/ ./database/ +COPY resources/ ./resources/ +COPY routes/ ./routes/ + +RUN composer install --no-interaction --optimize-autoloader --no-dev --prefer-dist + +# deploy +FROM trafex/php-nginx:3.6.0 AS deploy +WORKDIR /var/www/html + +USER root +RUN apk add --no-cache php83-pdo_pgsql php83-pgsql php83-pecl-redis php83-iconv php83-zip + +## Install supercronic (cron alternative) +ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.2.26/supercronic-linux-amd64 \ + SUPERCRONIC=supercronic-linux-amd64 \ + SUPERCRONIC_SHA1SUM=7a79496cf8ad899b99a719355d4db27422396735 + +RUN curl -fsSLO "$SUPERCRONIC_URL" \ + && echo "${SUPERCRONIC_SHA1SUM} ${SUPERCRONIC}" | sha1sum -c - \ + && chmod +x "$SUPERCRONIC" \ + && mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}" \ + && ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic + +COPY ./etc/nginx/default.conf /etc/nginx/conf.d/default.conf +COPY ./etc/php/php.ini ${PHP_INI_DIR}/conf.d/php.ini +COPY --chown=nobody ./etc/crontab ./crontab +COPY --chown=nobody ./etc/supervisord.conf ./supervisord.conf +RUN cat ./supervisord.conf >> /etc/supervisor/conf.d/supervisord.conf +RUN rm ./supervisord.conf + +USER nobody + +ARG LARAVEL_ENV=production +ARG LARAVEL_ENV_FILE=.env.${LARAVEL_ENV} +ARG LARAVEL_ENV_FILE_KEY="" + +COPY --chown=nobody ${LARAVEL_ENV_FILE} ./.env.${LARAVEL_ENV} +COPY --chown=nobody public/ ./public/ +COPY --chown=nobody storage/ ./storage/ +COPY --chown=nobody --from=laravel-build /app/ ./ +COPY --chown=nobody --from=assets-build /app/public/ ./public/ + +ENV APP_ENV=${LARAVEL_ENV} + +RUN [ -z "${LARAVEL_ENV_FILE_KEY}" ] || ( mv .env.${LARAVEL_ENV} .env.${LARAVEL_ENV}.encrypted && php artisan env:decrypt -n --env=${LARAVEL_ENV} --key=${LARAVEL_ENV_FILE_KEY} ) +RUN php artisan storage:link -n +RUN php artisan event:cache -n +RUN php artisan route:cache -n +RUN php artisan view:cache -n + +COPY --chown=nobody ./etc/entrypoint.sh /entrypoint.sh +CMD [ "/entrypoint.sh" ] diff --git a/etc/entrypoint.sh b/etc/entrypoint.sh new file mode 100755 index 00000000..46539f54 --- /dev/null +++ b/etc/entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e + +# Cache config and other stuff +php artisan optimize -n +rm .env.${LARAVEL_ENV}* + +/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf diff --git a/etc/nginx/default.conf b/etc/nginx/default.conf index 0c48634b..b36d8871 100644 --- a/etc/nginx/default.conf +++ b/etc/nginx/default.conf @@ -1,7 +1,6 @@ server { listen 80; listen [::]:80; - server_name .sinf.pt; root /var/www/html/public; add_header X-Frame-Options "SAMEORIGIN"; diff --git a/seeder.railway.json b/seeder.railway.json index 9e9bb91a..82aa961a 100644 --- a/seeder.railway.json +++ b/seeder.railway.json @@ -1,9 +1,11 @@ { "$schema": "https://railway.app/railway.schema.json", "build": { - "builder": "NIXPACKS" + "builder": "DOCKERFILE", + "dockerfilePath": "./dockerfiles/Dockerfile.seeder" }, "deploy": { - "startCommand": "php artisan migrate --force --seed --no-interaction --isolated --database=pgsql" + "restartPolicyType": "NEVER", + "sleepApplication": false } } diff --git a/website.railway.json b/website.railway.json index 5435980a..f3341f43 100644 --- a/website.railway.json +++ b/website.railway.json @@ -1,10 +1,10 @@ { "$schema": "https://railway.app/railway.schema.json", "build": { - "builder": "NIXPACKS" + "builder": "DOCKERFILE", + "dockerfilePath": "./dockerfiles/Dockerfile.website" }, "deploy": { - "sleepApplication": true, - "startCommand": "php artisan serve" + "sleepApplication": true } }