Skip to content

Deployment with Amazon ECS

In this tutorial you will learn how to deploy an application created in the setup guide to Amazon Web Services cloud using Docker Compose.

The Docker Compose CLI is fully integrated with Amazon Elastic Container Service (ECS). It allows to create / manage the task definitions, tasks, services using Compose YAML configuration files. Docker Compose CLI relies on CloudFormation to manage AWS Resources.

Docker allows to define the platform in declarative way. Switching between local and ECS environments is as easy as switching Docker Context (any addtional AWS configurations exists in the Docker Compose YAML file).

Notice

Setting up the WebSight CMS CE environment in AWS presented in this tutorial is not in the AWS Free Tier. If you run the instance according to this guide, the costs will incur (~3$/day).

Prerequisites

After finishing Creating and developing WebSight CMS project guide you should already have:

To complete this tutorial, you will additionally need:

Step 1: AWS configuration

  1. Registering a new domain with Route53.
  2. Request a public certificate using AWS Certificate Manager.
  3. Validate domain ownership for the created public certificate.
  4. Create two private image repositories:
    • Set the CMS image Repository name to <your-project-name>-cms-ce, e.g. luna-cms-ce.
    • Set the Nginx image Repository name to <your-project-name>-nginx-ce, e.g. luna-nginx-ce.

Step 2: Project configuration

In this step, we will start from the project generated in the Setup guide and update Docker and Maven configuration files.

Docker

For simplicity, we set remote environment configuration in the same repository as the project.

  1. Create environment/remote directory.
  2. Create environment/remote/admin_password.txt and environment/remote/mongo_password.txt files and fill them with random password (both should be single-line documents).
  3. Copy environment/local/docker-compose.yml to environment/remote.
  4. Add secrets section in environment/local/docker-compose.yml:
    secrets:
      admin_password:
        file: ./admin_password.txt
      mongo_password:
        file: ./mongo_password.txt
    
  5. Replace volumes section to:
    volumes:
      cms_logs:
      mongo_repository:
      site_repository:
    
  6. Change cms service definition to:

      cms:
        image: <CMS_ECR_IMAGE_URI>
        deploy:
          resources:
            limits:
              cpus: '0.5'
              memory: 2048M
        ports:
          - target: 8080
            published: 8080
            x-aws-protocol: http
        environment:
          - WS_ADMIN_USERNAME=wsadmin
          - MONGODB_HOST=mongo
          - MONGODB_PORT=27017
          - MONGODB_USERNAME=mongoadmin
        volumes:
          - cms_logs:/websight/logs
          - site_repository:/websight/docroot
        secrets:
          - source: admin_password
            target: admin.password
          - source: mongo_password
            target: mongo.password
        depends_on:
          - mongo
    

    • CMS_ECR_IMAGE_URI - replace with CMS repository URI from AWS ECR dashboard
    • x-aws-protocol - configuration for AWS ALB, read more here
  7. Change mongo service definition to:

      mongo:
        image: mongo:4.4.6
        deploy:
          resources:
            limits:
              cpus: '1'
              memory: 4096M
        environment:
          - MONGO_INITDB_ROOT_USERNAME=mongoadmin
          - MONGO_INITDB_ROOT_PASSWORD_FILE=/run/secrets/mongo.password
        volumes:
          - mongo_repository:/data/db
        secrets:
          - source: mongo_password
            target: mongo.password
    

  8. Change nginx service definition to:
      nginx:
        image: <NGINX_ECR_IMAGE_URI>
        ports:
          - target: 80
            published: 80
            x-aws-protocol: http
        volumes:
          - site_repository:/usr/share/nginx/html:ro
    
    • NGINX_ECR_IMAGE_URI - replace with Nignx repository URI from AWS ECR dashboard
    • x-aws-protocol - configuration for AWS ALB, read more here
  9. Add x-aws-cloudformation section with Load Balancer configuration:
    x-aws-cloudformation:
      Resources:
        Cms8080TargetGroup:
          Properties:
            HealthCheckProtocol: HTTP
            HealthCheckPort: 8080
            HealthCheckPath: /system/health
            Matcher:
              HttpCode: 200
        Nginx80TargetGroup:
          Properties:
            HealthCheckProtocol: HTTP
            HealthCheckPort: 80
            HealthCheckPath: /health
            Matcher:
              HttpCode: 200
        Cms8080Listener:
          Properties:
            Certificates:
              - CertificateArn: "<CERTIFICATE_ARN>"
            Protocol: HTTPS
            Port: 8443
        Nginx80Listener:
          Properties:
            Certificates:
              - CertificateArn: "<CERTIFICATE_ARN>"
            Protocol: HTTPS
            Port: 443
    
    • CERTIFICATE_ARN - replace with ARN of the certificate generated in AWS Configuration step.
  10. Create Docker ECS context named ws-ecs:
    • docker context create ecs ws-ecs
  11. Update distribution/src/main/docker/nginx/default.conf Nginx config with additional health endpoint:
        location /health {
            access_log off;
            add_header  Content-Type    text/html;
            return 200;
        }
    

To find more information about using Docker Compose with AWS Elastic Container Service, please read Deploying Docker containers on ECS.

Maven

  1. Update io.fabric8:docker-maven-plugin plugin configuration in distribution/pom.xml.
    • Add the following buildx extension to cms and nginx images <build> sections:
                      <buildx>
                        <platforms>
                          <platform>linux/amd64</platform>
                          <platform>linux/arm64</platform>
                        </platforms>
                      </buildx>
      
    • Add the following execution:
                <execution>
                  <id>push-docker-image</id>
                  <phase>package</phase>
                  <goals>
                    <goal>push</goal>
                  </goals>
                </execution>
      
  2. Add <docker.skip.push>true</docker.skip.push> property to the main pom.xml.

Alternatively, you can check the above configuration in WebSight Starter Distribution POM (where Maven profiles are used).

Step 3: Build and deployment

  1. Log in to ECR.
  2. In the project root run mvn clean install -D docker.cms-project.name=<CMS_ECR_IMAGE_URI> -D docker.nginx.name=<NGINX_ECR_IMAGE_URI> -D docker.skip.push=false.
  3. Switch Docker context to ECS docker context use ws-ecs.
  4. From environment/remote run docker compose --project-name "websight-in-aws" up. It may take a couple of minutes to finish.
  5. Route your domain to Application Load Balancer (that was created by the Docker Compose in the previous step) by creating a new Hosted Zone.

Step 4: Verification

  1. Check ECS Console and see if all cluster services are running.
  2. Open WebSight CMS CE admin panel on <your-domain>:8443. Use the wsadmin as login and content of environment/remote/admin_password.txt as password.

Cleaning up

To stop incurring AWS costs, follow these steps:

  1. From environment/remote run docker compose --project-name "websight-in-aws" down. It may take a couple of minutes.
  2. Delete EFS file systems for cms_logs ,mongo_repository, and site_repository volumes.
  3. Delete Route53 Hosted Zone created in Deployment step.
  4. Delete certificate created in AWS Configuration step.
  5. Delete ECR repositories created in AWS Configuration step.

AWS best practices

This section descirbes best practices for deploying WebSight CE DXP to AWS ECS.

Logs and monitoring

It is always worth configuring logs and observing basic metrics for your instance.

Thanks to the Docker Compose integration with AWS ECS, the AWS CloudWatch Logs service is automatically configured for your containers.

Additionally, you can monitor basic metrics thanks to the CloudWatch metrics for the Fargate launch type.

Secrets

Use Docker secrets for storing any sensitive data (like passwords, tokens, etc.). Docker Compose integration with AWS ECS creates a new secret in the AWS Secrets Manager for each secred defined in the compose configuration file. See the examples below.

Custom CMS admin credentials

WebSight CE CMS enables configuring a custom admin username and password. The default values for admin user username/password are wsadmin/wsadmin.

You can configure a custom username with WS_ADMIN_USERNAME environment variable.

To configure a custom password use admin.password secret. You will need secret files available at deploy time next to the compose file:

admin_password.txt
s33cretP@ssword
and reference it in the compose configuration:

docker-compose.yml
service:
  cms:
    secrets:
      - source: admin_password
        target: admin.password
secrets:
  admin_password:
    file: ./admin_password.txt

Custom MongoDB password

By default, ECS Tasks configured by the Docker Compose integration have public IP assigned. Therefore, you should consider securing MongoDB, which by default starts with no username/password configured. Read more about securing MongoDB containers here.