Capability Exchange
This guide walks you through deploying an updated version of the Capability Exchange (PCX) service in production using the AWS Console. No technical background required — just follow each step in order.
Prerequisites
- You have access to the AWS Console (via the ESProfiler Secured Workspace or direct login)
- You are logged in as ESPROFILER in the Europe (London) region
Part 1: Navigate to ECS
- Open the AWS Console.
- In the search bar at the top, type
ECSand select Elastic Container Service from the results. - In the left-hand menu, click Clusters.
- You will see a list of clusters. Click on
esp-infrastructure.
Part 2: Find the PCX Service
- Inside the
esp-infrastructurecluster, click on the Services tab. - Find and click on the service named
esp-pcx-service-2bjz1boz(or the current PCX service listed). - You are now on the service's Health and metrics page. Confirm the status shows Active.
Part 3: Database Migrations (if required)
If the release includes Prisma schema changes, run migrations against the production PCX database before deploying the new service revision. The new container image will expect the updated schema to already be in place.
Where migrations run from
Production RDS lives in a private AWS network and is not reachable directly from your laptop. You need PuTTY (or an equivalent SSH client) to open a tunnel through the AWS jump box before you can connect. Full setup is documented in Production Database.
Migrations are not applied by deploying a new ECS task. The live container does not run migrations on startup. The migration is triggered by running a command on your machine, using the migration files in your local PCX checkout of the release branch. The new container image does not need to be live in AWS first — you are pushing schema changes to the database ahead of the code deployment.
Migration workflow
- Check out the release — ensure your local PCX repo includes the migration files for this release. This should be the
mainbranch. - Open an SSH tunnel in PuTTY — forward local port
15432to the PCX RDS endpoint on port5432(see Production Database if you have not done this before), then keep the session open.Keep the PuTTY session open for the entire migration. The tunnel only works while the connection is active. - Retrieve credentials — in AWS RDS (
eu-west-2), open the PCX PostgreSQL instance, follow the linked secret in Configuration, and copy the username and password from Secrets Manager. Do not store these permanently — they rotate regularly. - Point your local environment at production — PCX uses Prisma, which reads the database connection from a
DATABASE_URLenvironment variable. With the SSH tunnel from step 2 running, use127.0.0.1:15432as the host.
In the PCX repository, open (or create) a.envfile in the project root and set:DATABASE_URL="postgresql://<username>:<password>@127.0.0.1:15432/<database_name>"
Replace:<username>and<password>— from Secrets Manager (step 3)<database_name>— the database name shown in the RDS instance or secret (often the same as the instance identifier)
If the password contains special characters (e.g.@,#,/), URL-encode them in the connection string.This points your local tooling at production. Do not commit.envwith production credentials, and revert or remove the productionDATABASE_URLonce migrations are complete.
To avoid editing.envpermanently, you can set the variable for a single command instead:DATABASE_URL="postgresql://<username>:<password>@127.0.0.1:15432/<database_name>" npx prisma migrate deploy - Confirm the connection — before running migrations:
npx prisma migrate status
This should connect successfully and list any pending migrations. - Run migrations — from the PCX project locally:
npx prisma migrate deploy
Review pending migrations first and confirm they match what is in the release. - Verify — confirm migrations are complete:
npx prisma migrate status
This should report Database schema is up to date! before proceeding to the ECS deployment below. - Close the tunnel — once migrations are complete and verified, close the PuTTY session and revert or remove the production
DATABASE_URLfrom your local.env.
Part 4: Create a New Task Definition Revision
Before updating the service, you need to create a new version (revision) of the task definition with the latest image.
- In the left-hand menu, click Task definitions.
- In the list of task definitions, click on
esp-pcx. - You will see a list of revisions (e.g., esp-pcx:17, esp-pcx:16, etc.). Click the
Create new revisionbutton in the top right. - On the new revision form, the container image should already point to the latest image (
esp-pcx:latest). Do not change anything — just scroll to the bottom and click Create. - You should see a green confirmation banner: "Task definition successfully created" (e.g.,
esp-pcx:18).
Part 5: Update the Service to Use the New Revision
- Navigate back to the PCX service:
- Click Clusters in the left menu →
esp-infrastructure→ Services →esp-pcx-service-2bjz1boz
- Click Clusters in the left menu →
- Click the orange
Update servicebutton in the top right. - On the update screen, under Deployment configuration:
- Confirm the Task definition family is set to
esp-pcx - Set the Task definition revision to the latest revision number (e.g.,
18 (LATEST)) - Leave all other settings as they are
- Confirm the Task definition family is set to
- Scroll to the bottom and click the orange
Updatebutton. - You should see a green banner: "Service updated: esp-infrastructure:esp-pcx-service-2bjz1boz"
Part 6: Confirm the Deployment
- You will be taken to the Tasks tab of the service.
- Watch the task list — you should briefly see 2 tasks: the old one (
Running) and the new one (Provisioning). The old task will stop once the new one is healthy. - Once complete, you should see 1 task with status Running and the load balancer showing Healthy.
- On the Health and metrics tab, confirm:
- Deployment status =
Success - Target health =
Healthy
- Deployment status =
✅ The PCX service has been successfully updated in production.
Troubleshooting
| Issue | What to check |
|---|---|
migrate deploy fails with P3005 | Database has schema but no Prisma migration history — see baselining below. Production has already been baselined; this should only recur after a snapshot restore or similar. |
migrate dev fails with P3006 / shadow database errors | Do not use migrate dev on production; use migrate deploy only. |
Connection refused on 127.0.0.1:15432 | PuTTY tunnel is not open, or local port forwarding is misconfigured. |
| Task stays in "Provisioning" for a long time | Click the Events tab to see deployment messages |
| Deployment status shows "In progress" | Wait 2–3 minutes and refresh — this is normal during rollover |
| Load balancer shows "Unhealthy" | Check the Logs tab on the service for container errors |
Baselining an existing production database (P3005)
Production PCX has already been baselined. You should not need this for routine releases — use the migration workflow and npx prisma migrate deploy only.
Use this if migrate deploy fails with P3005 ("database schema is not empty"), typically after restoring from an RDS snapshot or bringing a database online that was created with prisma db push rather than migrations. See also Prisma baselining.
- Complete steps 1–5 of the migration workflow (tunnel, credentials,
DATABASE_URL, confirm connection). - List pending migrations:
npx prisma migrate status
Note every migration folder listed as not yet applied. - Decide which migrations the database already has — for each pending migration, check whether its schema changes are already live (inspect via your client on
127.0.0.1:15432, or readprisma/migrations/<folder>/migration.sqland confirm the objects exist). Split into:- Already in the database — mark as applied in step 4
- Not yet in the database — leave for
migrate deployin step 5
- Mark each baseline migration as applied — run once per folder:
npx prisma migrate resolve --applied "<migration_folder_name>" - Deploy remaining migrations:
npx prisma migrate deploy - Verify with
npx prisma migrate status— should report Database schema is up to date! - Close the tunnel and revert your local
DATABASE_URL.

