Skip to main content

Couch to 5K

Couch to 5K is the Better Health running coach app.

The app follows the standard pattern but also has a BuddyRun feature which runs in a separate ECS container and uses Redis. This uses WebSockets through the ALB instead of HTTP.

Architecture Overview

graph TD;
    User[Mobile App]
    CloudFront[CloudFront CDN]
    MediaS3[S3 Media Bucket]
    ALB[Application Load Balancer]
    CMS[ECS Fargate - Django API]
    BuddyRun[ECS Fargate]
    Redis[BuddyRun Redis]
    RDS[Aurora PostgreSQL]

    User --> CloudFront --> MediaS3
    CMS --> MediaS3
    User --> ALB --> CMS --> RDS
    CMS --> Secrets
    User --> ALB --> BuddyRun
    BuddyRun --> Redis

Components

Applications

  • CMS – https://github.com/ukhsa-collaboration/couch25k_cloudformation_iaas
  • BuddyRun - https://github.com/ukhsa-collaboration/couch-to-5k-buddy-run

Infrastructure as Code (IaC)

  • Repo: c25k-iac – Terraform defining the AWS infrastructure.

Environments

Environment URL
Production https://couchto5kprod.phedigital.co.uk
Staging https://couchto5kstg.phedigital.co.uk
Dev https://couchto5kdev.phedigital.co.uk

DNS Overview

The phedigital.co.uk apex lives in the phe-prd account. That zone delegates couchto5kprod.phedigital.co.uk, couchto5kstg.phedigital.co.uk and couchto5kdev.phedigital.co.uk to the respective landing-zone accounts, where Terraform manages the ALB aliases and CDN records. Each environment also hosts a cdn.phedigital<env>.co.uk record that aliases the CloudFront distribution in us-east-1.

The subdomains for Buddyrun are couch25k.buddyrun.<env>.phedigital.co.uk. This might imply that other applications also have a Buddyrun but they do not.

Subdomains in use:

  • couchto5kprod.phedigital.co.uk – Production API / CMS ALB.
  • couchto5kstg.phedigital.co.uk – Staging API / CMS ALB.
  • couchto5kdev.phedigital.co.uk – Development API / CMS ALB.
  • cdn.couchto5kprod.phedigital.co.uk – Production CloudFront distribution (audio/media).
  • cdn.couchto5kstg.phedigital.co.uk – Staging CloudFront distribution.
  • cdn.couchto5kdev.phedigital.co.uk – Development CloudFront distribution.
  • couch25k.buddyrun.prod.phedigital.co.uk - Prod Buddyrun ALB
  • couch25k.buddyrun.stg.phedigital.co.uk - Staging Buddyrun ALB
  • couch25k.buddyrun.dev.phedigital.co.uk - Development Buddyrun ALB
graph TD
  subgraph PHE_PRD[phedigital.co.uk – phe-prd account]
    PHE[phedigital.co.uk Root Zone]
  end

  subgraph DEV_ACC[dev account]
    DEV_ZONE[couchto5kdev.phedigital.co.uk]
    DEV_CDN[cdn.couchto5kdev.phedigital.co.uk]
    ALB_DEV[Application Load Balancer - dev]
    CF_DEV[CloudFront - dev]
  end

  subgraph STG_ACC[stg account]
    STG_ZONE[couchto5kstg.phedigital.co.uk]
    STG_CDN[cdn.couchto5kstg.phedigital.co.uk]
    ALB_STG[Application Load Balancer - stg]
    CF_STG[CloudFront - stg]
  end

  subgraph PRD_ACC[prd account]
    PRD_ZONE[couchto5kprod.phedigital.co.uk]
    PRD_CDN[cdn.couchto5kprod.phedigital.co.uk]
    ALB_PRD[Application Load Balancer - prod]
    CF_PRD[CloudFront - prod]
  end

  PHE -->|NS| DEV_ZONE
  PHE -->|NS| STG_ZONE
  PHE -->|NS| PRD_ZONE

  DEV_ZONE -->|ALIAS| ALB_DEV
  STG_ZONE -->|ALIAS| ALB_STG
  PRD_ZONE -->|ALIAS| ALB_PRD

  DEV_CDN -->|ALIAS| CF_DEV
  STG_CDN -->|ALIAS| CF_STG
  PRD_CDN -->|ALIAS| CF_PRD

If any hosted zone is recreated, update the corresponding NS records in the phe-prd root so delegation stays valid.

Enabling Transcriptions

The app uses AWS Transcribe to generate transcripts of the audio content. This is run in the Staging environment and the output is manually copied to the production S3 bucket. To run the Transcription container in Staging, run the following commands from a terminal with AWS CLI access to the staging account:

SUBNET=$(aws ec2 describe-subnets \
  --filters 'Name=tag:Type,Values=Private' \
  --query 'Subnets[0].SubnetId' \
  --output text)

SECURITY_GROUP=$(aws ec2 describe-security-groups \
  --query "SecurityGroups[?contains(GroupName, 'c25k-transcriber-service')].GroupId | [0]" \
  --output text)

TASK_DEFINITION=$(aws ecs list-task-definitions \
  --family-prefix aw-c25k-euw2-uat-ecssvc-c25k-transcriber \
  --sort DESC \
  --query 'taskDefinitionArns[0]' \
  --output text)

aws ecs run-task \
  --cluster aw-c25k-euw2-uat-ecscluster \
  --task-definition "$TASK_DEFINITION" \
  --launch-type FARGATE \
  --network-configuration \
    "awsvpcConfiguration={subnets=[$SUBNET],securityGroups=[$SECURITY_GROUP],assignPublicIp=DISABLED}"

Once the container is no longer needed, it should be stopped to avoid unnecessary costs. This can be done through the AWS Console.

This page was last reviewed on 29 January 2026. It needs to be reviewed again on 16 July 2026 .
This page was set to be reviewed before 16 July 2026. This might mean the content is out of date.