Tasuki Keifu: GitHub Deployment and Data Synchronization Plan
GitHub Deployment and Data Synchronization Plan
This plan was written on 2026-09-11. It records the deployment state at that time and proposes subsequent work; its checklist is not a claim that every item was completed. Related documents are the V0.1 technical plan and V0.1 PRD.
1. Starting Point
tasuki-keifu had an initial deployment on Ubuntu-3:
- Domain:
https://tasuki-keifu.gelatoni.uk - Application directory:
/opt/apps/tasuki-keifu - Application port:
127.0.0.1:3020 - Reverse proxy: Nginx
- Runtime: Docker Compose
- Database: a PostgreSQL container dedicated to the project
The initial procedure copied local code to the server, built an image there, ran migrations, and restarted the containers. That was adequate for early validation, but the proposed regular release path was a GitHub Actions workflow similar to personal-site.
2. Reference Deployment Pattern
At the time, personal-site used a private GitHub repository as the code source. A push to main triggered Actions to install dependencies, check types, build the application and Docker image, save the image as a tar.gz artifact, upload the archive and Compose file over SSH/SCP, load the image on Ubuntu-3, and restart the service with Docker Compose.
This pattern kept a GitHub token and a Git checkout off the server, made CI failures easier to locate, and gave both sites a consistent release entry point. tasuki-keifu also needed database migrations. Business-data ingestion was deliberately outside the deployment workflow.
3. Proposed Repository and Release Rules
The proposal was to create gelatoni-xh/tasuki-keifu as a private repository initially, and revisit public access once data provenance, copyright boundaries, page quality, and operations were more mature. The first version needed only main: pushes would deploy production, and workflow_dispatch would allow a manual run. A develop branch, preview environment, and release tags were possible later, once data entry and administration made them useful.
The workflow could reuse the server connection secret names UBUNTU3_HOST, UBUNTU3_USER, and UBUNTU3_SSH_KEY. It should not store the production database password, DATABASE_URL, or .env.production in GitHub Actions. Production environment variables belonged on the server at /opt/apps/tasuki-keifu/.env.production. Actions would transport release artifacts and deployment files, not import, synchronize, or repair business data.
The repository would contain a Dockerfile, docker-compose.prod.yml, deployment notes and an Nginx configuration under deploy/, and .github/workflows/deploy.yml. The Compose file should support an image uploaded by Actions while retaining a local build option for emergencies. The Nginx configuration should be documented without being overwritten on each deployment.
4. Proposed GitHub Actions Flow
push main
build
checkout
set up pnpm and Node.js
pnpm install --frozen-lockfile
pnpm prisma:generate
pnpm lint
pnpm build
docker build -t tasuki-keifu-app:latest .
docker save tasuki-keifu-app:latest | gzip
deploy
upload image archive and Compose file
docker load
docker compose run --rm app pnpm prisma migrate deploy
docker compose up -d app
docker image prune -f
health check
The deployment must run prisma migrate deploy, but must not run pnpm db:seed. Seeding is for local development or an explicit initialization step. Once production contains business data, seeding cannot be a routine release action. Imports, synchronization, and data corrections need a separate workflow.
5. Production Database Boundary
The production PostgreSQL database was the source of truth. At the time it ran in a container with database tasuki_keifu, user tasuki_keifu_user, and volume tasuki-keifu_tasuki-keifu-postgres-data.
The operating rules were:
- Allow migrations in deployment; do not automatically seed or import data.
- Back up before significant imports.
- Prefer restoring a backup for a data rollback, rather than assuming a reverse migration can reconstruct data.
Application deployment changes code and schema. It must not overwrite the curated production dataset.
6. Data Completion and Synchronization
6.1 Near Term: Production as the Write Target
For V0.1 to V0.2, the dataset was small, one person was the main maintainer, and the data-entry model was still being explored. The goal was to put facts gathered through offline breadth-first research into production without coupling that work to application releases.
The proposed sequence was:
- Explore sources, structure the facts, and judge source credibility outside the release pipeline.
- Trigger a manual or scripted production backup before writing.
- Write through a controlled script, administrative interface, or explicit SQL.
- Record source and audit information for the write.
- Keep deployment limited to
prisma migrate deploy, without seeding or import scripts.
During this early stage, a controlled offline session could connect to production to complete data; production backups could be restored locally for page development and model checks; and local model changes could reach production through migrations. The plan discouraged replacing the production database with a local copy, automatic production seeding, committing database dumps to Git, storing production dumps in Actions, or putting scraping and cleaning into deployment.
6.2 Dataset Checkpoints
When a batch of records had been checked sufficiently, the maintainer could create a checkpoint: back up production, record the covered data and sources plus known gaps, optionally restore the backup locally as a development baseline, and continue making incremental changes against production. This checkpoint was a data-workflow snapshot, not a release or a required code tag.
6.3 Medium Term: Production as Source, Local as Development Copy
As the real dataset grew, production would remain the source of truth and the local database would become a development copy. Production changes should pass through an administrative interface, import script, or controlled SQL. Local development could use a sanitized or complete production backup, but local edits should not be synchronized directly back to production. Corrections should be auditable through administration, imports, or migrations.
That stage called for an admin interface, import jobs, audit logs, pre-import backups, and import-result reports. These were proposed additions, not claimed as existing features.
6.4 Long-Term Direction
Public pages / admin interface
PostgreSQL primary business database
Import scripts / collection jobs
staging tables
human review
business tables
Analysis / relationship graphs / statistics
warehouse or materialized views
The long-term direction retained raw source data, put cleaned records into business tables, and could serve relationship and statistical views from materialized views or an analytical store. Public pages would still use a trusted production business database. V0.1 did not implement this layer.
7. Backup and Recovery
The deployment already had /opt/apps/tasuki-keifu/backup-db.sh, a backups directory, and /etc/cron.d/tasuki-keifu-backup. The short-term plan called for a daily pg_dump, manual backups before significant entry or migrations, and restoring a backup locally when real data was needed for development.
Proposed improvements were an explicit retention period, such as 14 days; object-storage uploads; periodic restore drills; and encryption of backup files. Their presence in the plan does not imply they had been implemented.
For application rollback, retain the preceding image archive or tag, reload that image, and run docker compose up -d app if the new version breaks pages. Prisma migrations would not receive automatic reverse migrations. For risky schema changes, first validate the migration locally, back up production, run the migration, and check core pages. Data recovery would use a backup restore.
8. Manual Fallback and Checklist
The original manual route could remain available for Actions failures, server troubleshooting, and very early validation:
local code -> sync to server -> docker compose build -> migrate deploy -> compose up
Once Actions worked, the intended normal route was git push main -> GitHub Actions -> Ubuntu-3.
The plan's priorities were:
- P0: Create the private repository, initialize and push
main, adddeploy.yml, support uploaded images in the production Compose file, verify reusable connection secrets, and complete one Actions deployment. - P1: Add a post-deploy health check, document local restoration from a production backup, provide a manual production-backup command, and make the local-only seed rule explicit.
- P2: Design staging imports and import reports, add object-storage backup, and record a restore drill.