Private
Public Access
1
0

chg: pkg: implement CD script to Gitea and add docs to the process #4
Some checks failed
Deploy to Production / deploy (push) Has been cancelled

This commit is contained in:
2026-04-14 12:55:47 +02:00
parent 82465322f2
commit 9d51654aec
6 changed files with 135 additions and 6 deletions

View File

@@ -10,10 +10,9 @@ APP_SECRET=changethis
###< symfony/framework-bundle ### ###< symfony/framework-bundle ###
###> doctrine/doctrine-bundle ### ###> doctrine/doctrine-bundle ###
# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url # Docker PostgreSQL is exposed on port 15432 — use that for bare-metal dev.
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db" # Replace POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB with the values from your .env.
# Configure your db driver and server_version in config/packages/doctrine.yaml DATABASE_URL=postgresql://POSTGRES_USER:POSTGRES_PASSWORD@127.0.0.1:15432/POSTGRES_DB?serverVersion=18&charset=utf8
DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name
###< doctrine/doctrine-bundle ### ###< doctrine/doctrine-bundle ###
###> google/recaptcha ### ###> google/recaptcha ###

View File

@@ -0,0 +1,19 @@
name: Deploy to Production
on:
push:
tags:
- 'v*'
jobs:
deploy:
runs-on: self-hosted
steps:
- name: Deploy
run: |
set -e
cd "${{ vars.PROD_APP_DIR }}"
git fetch --tags
git checkout "${{ gitea.ref_name }}"
printf '%s' '${{ secrets.PROD_ENV_FILE }}' > .env
docker compose up -d --build

View File

@@ -9,7 +9,7 @@ COPY vite.config.js ./
COPY assets/ assets/ COPY assets/ assets/
COPY public/ public/ COPY public/ public/
RUN bun run build && cp -r node_modules/@fortawesome/fontawesome-free/webfonts public/build/webfonts RUN bun run build
FROM dunglas/frankenphp:latest FROM dunglas/frankenphp:latest

106
README.md
View File

@@ -154,6 +154,7 @@ services:
mail: mail:
image: mailhog/mailhog:latest image: mailhog/mailhog:latest
ports: ports:
- "1025:1025"
- "8025:8025" - "8025:8025"
``` ```
@@ -174,6 +175,111 @@ Open the web UI at **http://localhost:8025** to inspect them.
--- ---
## Deploying to production
Releases are automated via Gitea Actions. Pushing a tag that starts with `v` (e.g. `v2026.01`) triggers the workflow at `.gitea/workflows/deploy.yml`.
The job runs on a **self-hosted runner** installed on the production server — the server only needs an outbound connection to Gitea, no open SSH port required.
The `app` image is rebuilt with the new code; the database and storage containers are untouched so all data is preserved.
### Gitea repository variables and secrets
**Variable** (plaintext, editable — **Repository → Settings → Variables**):
| Variable | Value |
|---|---|
| `PROD_APP_DIR` | Absolute path on the server (e.g. `/var/www/mineseeker`) |
**Secret** (encrypted, write-only — **Repository → Settings → Secrets**):
| Secret | Value |
|---|---|
| `PROD_ENV_FILE` | Full content of the production `.env` file (see below) |
The workflow writes `PROD_ENV_FILE` to `.env` on every deploy, so you never need to manage the file on the server manually. To update a credential, overwrite the secret in Gitea and push a new tag.
#### `PROD_ENV_FILE` contents
Paste the filled-in `.env` file as the secret value:
```dotenv
APP_ENV=prod
APP_SECRET="<openssl rand -hex 32>"
DATABASE_URL=postgresql://POSTGRES_USER:POSTGRES_PASSWORD@db:5432/POSTGRES_DB?serverVersion=18&charset=utf8
POSTGRES_USER=mineseeker
POSTGRES_PASSWORD="<strong password>"
POSTGRES_DB=mineseeker
POSTGRES_VERSION=18
MINIO_ROOT_USER=mineseeker
MINIO_ROOT_PASSWORD="<strong password>"
MINIO_ENDPOINT=http://minio:9000
MINIO_PUBLIC_URL=https://minio.mineseeker.hu
MAILER_DSN=smtp://mail:25?verify_peer=0
MAIL_DOMAIN=mineseeker.hu
RECAPTCHA_SITE_KEY="<your reCAPTCHA v3 site key>"
RECAPTCHA_SECRET_KEY="<your reCAPTCHA v3 secret key>"
MERCURE_URL=https://mineseeker.hu/.well-known/mercure
MERCURE_PUBLIC_URL=https://mineseeker.hu/.well-known/mercure
MERCURE_JWT_SECRET="<generated by make mercure-jwt>"
MERCURE_JWT_TOKEN="<generated by make mercure-jwt>"
MERCURE_SUBSCRIBER_JWT="<generated by make mercure-jwt>"
APP_PUBLIC_HOSTNAME=mineseeker.hu
WEBAUTHN_RP_ID=mineseeker.hu
WEBAUTHN_ORIGIN=https://mineseeker.hu
```
### Production server: one-time setup
The server needs Docker, Git, and a self-hosted `act_runner` registered against the Gitea repository. Bun and Composer run inside the multi-stage Dockerfile, so they are not needed on the server.
#### 1. Clone the repository
```bash
git clone https://gitea.mineseeker.hu/youruser/mineseeker.git /var/www/mineseeker
```
#### 2. Generate Mercure JWT tokens (run once locally)
```bash
composer install # only needed for this step
make mercure-jwt
```
Copy the three printed values into the `PROD_ENV_FILE` secret.
#### 5. First deploy
Trigger it by pushing the first tag:
```bash
git tag v2026.01
git push origin v2026.01
```
This writes `.env`, builds the Docker image, starts all services, runs migrations, and initialises the MinIO buckets automatically via `minio_init`.
#### 6. Verify
```bash
docker compose ps # all services should be healthy/running
docker compose logs app # look for "Starting FrankenPHP"
```
### Releasing
```bash
git tag v2026.01
git push origin v2026.01
```
---
## License ## License
LGPL-3.0 — see [LICENSE](LICENSE) for details. LGPL-3.0 — see [LICENSE](LICENSE) for details.

View File

@@ -4,6 +4,7 @@ services:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
restart: unless-stopped restart: unless-stopped
container_name: '${APP_NAME}-app'
ports: ports:
- "10080:80" - "10080:80"
environment: environment:
@@ -42,6 +43,7 @@ services:
minio: minio:
image: minio/minio:RELEASE.2025-09-07T16-13-09Z-cpuv1 image: minio/minio:RELEASE.2025-09-07T16-13-09Z-cpuv1
restart: unless-stopped restart: unless-stopped
container_name: '${APP_NAME}-minio'
command: server /data --console-address ":9001" command: server /data --console-address ":9001"
ports: ports:
- "9000:9000" - "9000:9000"
@@ -60,6 +62,7 @@ services:
minio_init: minio_init:
image: minio/minio:RELEASE.2025-09-07T16-13-09Z-cpuv1 image: minio/minio:RELEASE.2025-09-07T16-13-09Z-cpuv1
restart: "no" restart: "no"
container_name: '${APP_NAME}-minio-init'
depends_on: depends_on:
minio: minio:
condition: service_healthy condition: service_healthy
@@ -72,6 +75,7 @@ services:
mail: mail:
image: boky/postfix:latest image: boky/postfix:latest
restart: unless-stopped restart: unless-stopped
container_name: '${APP_NAME}-mail'
environment: environment:
ALLOWED_SENDER_DOMAINS: ${MAIL_DOMAIN:-localhost} ALLOWED_SENDER_DOMAINS: ${MAIL_DOMAIN:-localhost}
RELAYHOST: ${MAIL_RELAYHOST:-} RELAYHOST: ${MAIL_RELAYHOST:-}
@@ -82,6 +86,7 @@ services:
db: db:
image: postgres:${POSTGRES_VERSION:-latest}-alpine image: postgres:${POSTGRES_VERSION:-latest}-alpine
restart: unless-stopped restart: unless-stopped
container_name: '${APP_NAME}-db'
environment: environment:
POSTGRES_USER: ${POSTGRES_USER} POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

View File

@@ -44,7 +44,7 @@
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"watch": "vite build --watch", "watch": "vite build --watch",
"build": "vite build", "build": "vite build && cp -r node_modules/@fortawesome/fontawesome-free/webfonts public/build/webfonts",
"lint": "eslint assets/js/" "lint": "eslint assets/js/"
} }
} }