diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0495b79 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,13 @@ +symfony/.env.local +symfony/.env.local.php +symfony/.env.*.local +symfony/config/secrets/prod/prod.decrypt.private.php +symfony/public/bundles/ +symfony/var/ +symfony/vendor/ +symfony/phpunit.xml +symfony/.phpunit.result.cache +symfony/.phpunit.result.cache +symfony/phpunit.xml +symfony/public/assets/ +symfony/assets/vendor/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2c654d8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +FROM docker.io/bitnami/php-fpm:8.4 + +WORKDIR /app +RUN set -eux \ + && apt-get update && apt-get install -y --no-install-recommends \ + acl \ + && rm -rf /var/lib/apt/lists/* + +COPY ./symfony/composer.* ./symfony/symfony.* ./ +COPY ./symfony/.env.prod ./.env +RUN composer install \ + --no-cache \ + --no-dev \ + --no-progress \ + --no-scripts \ + --optimize-autoloader \ + --prefer-dist + +WORKDIR / +COPY ./scripts ./scripts + +WORKDIR /app +COPY ./symfony . + +RUN mkdir -p var/log var/cache && \ + chown -R www-data:www-data var && \ + chmod -R 775 var +RUN composer install \ + --no-cache \ + --no-dev \ + --no-progress \ + --optimize-autoloader \ + --prefer-dist +RUN php bin/console doctrine:migrations:migrate latest diff --git a/compose.override.yaml b/compose.override.yaml deleted file mode 100644 index 8dc54de..0000000 --- a/compose.override.yaml +++ /dev/null @@ -1,18 +0,0 @@ - -services: -###> doctrine/doctrine-bundle ### - database: - ports: - - "5432" -###< doctrine/doctrine-bundle ### - -###> symfony/mailer ### - mailer: - image: axllent/mailpit - ports: - - "1025" - - "8025" - environment: - MP_SMTP_AUTH_ACCEPT_ANY: 1 - MP_SMTP_AUTH_ALLOW_INSECURE: 1 -###< symfony/mailer ### diff --git a/compose.yaml b/compose.yaml index 89c74d1..9feae35 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,25 +1,26 @@ +networks: + app-network: + driver: bridge services: -###> doctrine/doctrine-bundle ### - database: - image: postgres:${POSTGRES_VERSION:-16}-alpine - environment: - POSTGRES_DB: ${POSTGRES_DB:-app} - # You should definitely change the password in production - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-!ChangeMe!} - POSTGRES_USER: ${POSTGRES_USER:-app} - healthcheck: - test: ["CMD", "pg_isready", "-d", "${POSTGRES_DB:-app}", "-U", "${POSTGRES_USER:-app}"] - timeout: 5s - retries: 5 - start_period: 60s + phpfpm: + build: . volumes: - - database_data:/var/lib/postgresql/data:rw - # You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data! - # - ./docker/db/data:/var/lib/postgresql/data:rw -###< doctrine/doctrine-bundle ### + - ./php-fpm:/opt/bitnami/php/etc/php-fpm.d + expose: + - 9000 + networks: + - app-network -volumes: -###> doctrine/doctrine-bundle ### - database_data: -###< doctrine/doctrine-bundle ### + nginx: + image: 'docker.io/bitnami/nginx:1.28' + depends_on: + - phpfpm + networks: + - app-network + ports: + - '8080:8080' + - '443:443' + volumes: + - ./nginx:/opt/bitnami/nginx/conf/server_blocks + - ./symfony:/app diff --git a/nginx/joeac.net.nginx.conf b/nginx/joeac.net.nginx.conf new file mode 100644 index 0000000..5c0f772 --- /dev/null +++ b/nginx/joeac.net.nginx.conf @@ -0,0 +1,28 @@ +server { + listen 0.0.0.0:8080; + server_name localhost; + root /app/public; + access_log /opt/bitnami/nginx/logs/joeacnet_access.log; + error_log /opt/bitnami/nginx/logs/joeacnet_error.log; + keepalive_requests 100; + + location / { + try_files $uri /index.php$is_args$args; + } + + location ~ ^/index\.php(/|$) { + fastcgi_pass phpfpm:9000; + fastcgi_keep_conn on; + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi_params; + include /opt/bitnami/nginx/conf/fastcgi.conf; + fastcgi_param APP_ENV prod; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param DOCUMENT_ROOT $document_root; + internal; + } + + location ~ \.php$ { + return 404; + } +} diff --git a/php-fpm/joeac_php-fpm_pool_definition.conf b/php-fpm/joeac_php-fpm_pool_definition.conf new file mode 100644 index 0000000..0b89d9f --- /dev/null +++ b/php-fpm/joeac_php-fpm_pool_definition.conf @@ -0,0 +1,7 @@ +[joeac] +listen = phpfpm:9000 +pm = ondemand +pm.max_children = 10 +pm.max_requests = 100 +security.limit_extensions = .php .css .webp .jpg +user = www-data diff --git a/symfony/.env b/symfony/.env index ae5c7f3..e6a3200 100644 --- a/symfony/.env +++ b/symfony/.env @@ -1,41 +1,4 @@ -# In all environments, the following files are loaded if they exist, -# the latter taking precedence over the former: -# -# * .env contains default values for the environment variables needed by the app -# * .env.local uncommitted file with local overrides -# * .env.$APP_ENV committed environment-specific defaults -# * .env.$APP_ENV.local uncommitted environment-specific overrides -# -# Real environment variables win over .env files. -# -# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES. -# https://symfony.com/doc/current/configuration/secrets.html -# -# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). -# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration - -###> symfony/framework-bundle ### APP_ENV=dev -APP_SECRET= -###< symfony/framework-bundle ### - -###> doctrine/doctrine-bundle ### -# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url -# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml -# -DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_%kernel.environment%.db" -# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4" -# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4" -# DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8" -###< doctrine/doctrine-bundle ### - -###> symfony/messenger ### -# Choose one of the transports below -# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages -# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages -MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 -###< symfony/messenger ### - -###> symfony/mailer ### -MAILER_DSN=null://null -###< symfony/mailer ### +DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db" +#JOEAC_PASSWORD= +MESSENGER_TRANSPORT_DSN=doctrine://default diff --git a/symfony/.gitignore b/symfony/.gitignore index 8dc906c..cda89ba 100644 --- a/symfony/.gitignore +++ b/symfony/.gitignore @@ -2,6 +2,7 @@ .env.local .env.local.php .env.*.local +.env.prod config/secrets/prod/prod.decrypt.private.php public/bundles/ var/ diff --git a/symfony/migrations/Version20250522212300.php b/symfony/migrations/Version20250522212300.php index b5116e5..12f0e58 100644 --- a/symfony/migrations/Version20250522212300.php +++ b/symfony/migrations/Version20250522212300.php @@ -36,7 +36,7 @@ final class Version20250522212300 extends AbstractMigration public function up(Schema $schema): void { foreach (self::BLOG_POST_SLUGS as $slug) { - $blogPostPath = 'scripts/blog-migrated/' . $slug . '.yaml'; + $blogPostPath = '../scripts/blog-migrated/' . $slug . '.yaml'; $blogPost = Yaml::parseFile($blogPostPath); $publishedDateTime = DateTime::createFromFormat('U', strval($blogPost['pubDate'])); diff --git a/todo.txt b/todo.txt index 87a6948..0522574 100644 --- a/todo.txt +++ b/todo.txt @@ -2,7 +2,7 @@ Add a most recent blog post to my home page Add a most recent note to my home page Write a script to take a database dump Write a systemd unit to back up a daily database dump to Backblaze -Write a Docker compose.yaml to co-ordinate the symfony app with the database back-up script +Manage secrets in some better way than uncommitted .env files Start serving the website from a Raspberry Pi Add Next and Prev links to each note page Can create notes by Micropub