Deploying Code & Database Changes

Learn a safe, beginner-friendly path from an AI-assisted change to a reviewed pull request, a controlled deployment, and a healthy live site.

Beginner to intermediate35 minute guideReviewed August 10, 2026

What You Will Learn

  • Explain the difference between code in Git and data in a database.
  • Use pull requests and protected branches to make AI-assisted changes reviewable.
  • Store database structure changes as versioned migration files alongside code.
  • Set up a small, safe deployment path for cPanel, a VPS, or AWS.
  • Know when to stop automation and recover instead of retrying a broken release.

You do not need to become a cloud engineer first. Start with a small repeatable process. A good process makes change safer whether you deploy a one-page PHP site or a larger application.

The Simple Mental Model

Think of your project as four separate jobs. Keeping them separate is the key to safe automation.

PartWhat it stores or doesWhat it should not do
Git repositoryCode, documentation, tests, deployment scripts, and database migration files.Store passwords, API keys, customer data, or production database backups.
Git hostPull requests, reviews, branch protection, test results, and a history of who approved a change.Directly replace your server without a controlled deployment step.
DatabaseLive application data such as accounts, articles, orders, or event registrations.Be treated as a copy of the repository or changed casually by hand.
Deployment runnerMoves one approved release to the server, applies safe migrations once, and checks the result.Run on every untrusted pull request or give an AI agent unlimited production access.

Git records how your software should look. The database holds what your software currently knows. A deployment joins them carefully.

From a Pull Request to a Live Release

For a first automated setup, use one protected branch called main. A deployment should start when a reviewed pull request is merged into that branch, not merely when someone clicks Approve.

1

Work on a branch

You or an AI agent creates a focused branch, such as agent/add-event-signup. The live site is untouched.

2

Test the proposed change

Run the site checks and, for database work, use a fresh local or staging database. Do not test a new migration first against live customer data.

3

Review the pull request

Read the code and migration diff. A human checks that the change solves the right problem and that the agent did not add secrets, unrelated changes, or unsafe SQL.

4

Merge into protected main

Require at least one approval and passing checks. Only a trusted maintainer merges; the agent does not approve or merge its own work.

5

Deploy one release

A trusted runner receives the merged commit, makes a backup/checkpoint when needed, applies pending migrations once, activates the code, and runs a health check.

Never give production secrets to pull-request jobs. A pull request can contain untrusted code. Keep production credentials available only to the post-merge deployment environment.

Database Changes: Migrations, Not Guesswork

A database migration is a small, ordered file that changes database structure. For example: creating an articles table or adding a published_at column. Put it in the repository and review it with the application code that needs it.

Risky: manual production change
Open phpMyAdmin Run ALTER TABLE on the live database Hope everyone remembers what changed
Safer: reviewed migration
migrations/ 20260810_001_create_articles.sql 20260810_002_add_article_status.sql The release applies each new file once and records it.

A small migration system keeps a ledger such as schema_migrations. Each successful file is recorded with its ID, checksum, and date. The next deployment sees that record and does not run the same file again.

The beginner rules for migrations

  • Make one focused change at a time. A migration should have a clear purpose and a stable, date-based filename.
  • Test on a disposable copy first. Use sample data or a sanitized staging copy, never an agent session with production records.
  • Use a lock. Only one deployment may run migrations at a time.
  • Prefer expand then contract. Add a new optional column, deploy compatible code, move data, then remove old columns in a later release.
  • Do not rely on automatic undo. Rolling back code is often easy; undoing a destructive database change may not be. Plan a forward fix or restore instead.

Where AI Agents Fit Safely

An autonomous agent is useful for reading a repository, proposing a migration, updating tests, and opening a draft pull request. The safe boundary is Git: you review a concrete diff before it can reach production.

Agent can doHuman or trusted deployment system does
Inspect code and a schema-only export.Provide production credentials or approve secret access.
Write a migration file and tests on its own branch.Review, approve, and merge the pull request.
Run tests against a disposable local database.Apply migration files to production after merge.
Report a possible data issue using a read-only, sanitized source.Delete data, change permissions, or make financial or public-facing decisions.

Use separate database accounts. The website needs only its everyday application permissions. The migration account needs schema-change permission but should be available only to the trusted deployment job. An inspection account should be read-only and use schema metadata or sanitized staging data.

A Practical cPanel and MySQL Setup

cPanel can support a small deployment pipeline if your plan includes SSH or Terminal access and PHP command-line access. If it does not, keep the review and test process, then use a documented manual release rather than exposing an unsafe public script.

1

Create separate MySQL users

In cPanel, create the database and at least two users: an application user with only the permissions the site needs, and a migration user used only during deployment. Do not use the database root account.

2

Keep configuration private

Store database credentials outside public_html, in a file readable only by the account owner or in your host's secret configuration. Your PHP files load the values at runtime. Git contains an example file with placeholders, never the real password.

3

Choose server authentication

Use a repository-scoped, read-only SSH deploy key when the server pulls from Git. If SSH is unavailable, use a fine-grained HTTPS token stored privately on the server. Both should be limited to one repository and rotated when needed.

4

Run one fixed deployment script

After a merge, a trusted CI runner can connect by SSH and run a fixed server-side command. That command checks out the expected commit, obtains a backup/checkpoint, takes the migration lock, applies pending migrations, and performs a health check. It should not run arbitrary text received from a webhook.

5

Record the result

Log the commit ID, migrations applied, time, and health-check result outside the web root. Keep the previous code release available until the new one has passed its check.

SSH or HTTPS?

MethodGood forImportant rule
SSH deploy keycPanel or VPS servers that pull a private repository.Use a repository-scoped key and do not reuse a developer's personal key.
HTTPS tokenHosts where SSH Git access is unavailable.Store the token in the host's private secret area, never in a repository URL or shell history.
Cloud identityAWS and other cloud providers.Prefer short-lived identity federation over permanent cloud access keys.

Do not place database backups, SQL dumps, or secret files in the web root. A backup is sensitive data. Keep it in your host's backup system or another private, access-controlled location.

How the Same Model Looks on a VPS or AWS

The safety process stays the same. Only the services change.

Linux VPS

Create an unprivileged deploy user with a dedicated SSH key. Keep MySQL or PostgreSQL on localhost or a private network. Deploy into timestamped release folders, switch the current release only after migrations and checks pass, and use system logs and a firewall.

AWS

Use GitHub OIDC to assume a narrow AWS role instead of storing long-lived AWS keys. Store secrets in Secrets Manager or Parameter Store. Run migrations once as a controlled job, not on every web server. Use RDS backups, CloudWatch logs, and deployment health checks.

Hosted deployment platforms

Platforms such as Netlify or Vercel make static-site deployment easy, but a separate database migration job is still needed when your application has a database. Keep that job post-merge and restricted.

Failures, Rollback, and Recovery

Automation should stop safely when it cannot prove success. A failed deployment is information, not a reason to keep retrying blindly.

What happened?Safe response
A migration fails before new code is activated.Stop the release, preserve logs, and leave the previous code live. Fix and retest the migration.
New code fails its health check after a compatible migration.Switch back to the previous code release if it still supports the expanded schema.
A destructive or partially applied migration fails.Stop automation. Use a tested forward fix or restore decision; do not repeatedly rerun the SQL.
Two deployments run at once.Use CI concurrency plus a database migration lock so one release waits or stops.
No current backup exists before a risky migration.Block the risky release until a usable backup/checkpoint is confirmed.

Good deployments are observable. You should be able to answer: which commit is live, which migrations were applied, who started the release, and whether the health check passed.

Your First Safe Practice Release

  1. Create a small practice repository with a simple PHP page and a local test database.
  2. Create a table through a migration file, then add one more migration that adds a harmless column.
  3. Make a branch and ask an AI coding agent to write the migration and explain its assumptions.
  4. Review the agent's diff, run it against a fresh database, and open a pull request.
  5. Protect main so a review and passing check are required before merging.
  6. After the merge, run a local deployment script that applies new migrations only once and prints a health-check result.
  7. Try a deliberate failing migration in the practice project. Confirm that your process stops and leaves a useful log.

Before any real production release

  • Use a private secret store; no real credential appears in Git, terminal history, or an AI prompt.
  • Test the exact migration sequence on a disposable or sanitized environment.
  • Know the current backup/checkpoint and who can restore it.
  • Use a protected branch, required review, and a deployment trigger that runs only after merge.
  • Write down how to verify the release and how to contact the person responsible if it fails.

Continue learning