Cheap. Simple. Fast.
Move your Docker Compose application stack from your local machine to the cloud in 3 minutes with KISS-Docker-Compose.
- Cheap: All code runs on one EC2 instance, which means you can get swap space (unlike Fargate) and all containers share resources which can reduce unusued resource capacity. Note: Swap isn't currently configured for this project.
- Simple: It runs the same way on your machine with Docker Compose as it runs in the cloud because both are running a Docker Compose file.
- Fast: Deploys quickly.
npm i kiss-docker-compose
npm i aws-cdk-lib
const dockerComposeFileAsString = `
services:
frontend:
image: nginx # used as an example / for testing
restart: always
# build:
# context: ../src/client
ports:
- 80:80
volumes:
- ./vuejs:/project
- /project/node_modules
backend:
image: nginx # used as an example / for testing
restart: always
# build:
# context: ../src/server
ports:
- 443:80
depends_on:
db:
condition: service_started
db:
image: postgres
restart: always
# set shared memory limit when using docker-compose
shm_size: 128mb
healthcheck:
`+ 'test: [ "CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}" ]' + `
interval: 15s
timeout: 30s
retries: 5
ports:
- 5432:5432
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: "password"
volumes:
- db-data:/var/lib/postgres
volumes:
db-data:
`;
const kissDockerCompose = new KissDockerCompose(stack, 'kiss-docker-compose', { dockerComposeFileAsString });
// Exporting the value so you can find it easily
new cdk.CfnOutput(stack, 'Kiss-Docker-Compose-public-ip', {
value: kissDockerCompose.ec2Instance?.instancePublicDnsName ?? '',
exportName: 'Kiss-Docker-Compose-public-ip',
});
Get a sample Docker Compose File:
curl -O https://raw.githubusercontent.com/Gregory-Ledray/kiss-docker-compose-on-aws/main/test/docker-compose.yml
And use it:
import * as fs from 'fs';
import { KissDockerCompose } from 'kiss-docker-compose'
const dockerComposeFileAsString = fs.readFileSync('./docker-compose.yml', 'utf8');
const kissDockerCompose = new KissDockerCompose(stack, 'kiss-docker-compose', { dockerComposeFileAsString });
// Exporting the value so you can find it easily
new cdk.CfnOutput(stack, 'Kiss-Docker-Compose-public-ip', {
value: kissDockerCompose.ec2Instance?.instancePublicDnsName ?? '',
exportName: 'Kiss-Docker-Compose-public-ip',
});
General Procedure:
- cdk destroy
- Find the EBS Volume which was preserved after deletion and delete it.
- Run this command:
npx cdk destroy
- By default, the EC2 Instance preserves its root volume when deleted. You need to find this volume and delete it. It will be in the same region as the EC2 Instance.
When the EC2 Instance is deleted, the volumes are saved. This is to prevent the CDK from deleting the EC2 Instance whenever you make a change and you losing all of your data. To restore your data, follow this procedure, which is also documented in TestPlan.md:
- Find your detatched volume. This will be in the same account and region the EC2 instance was in.
- Create a Snapshot from the Volume. This will take a minute or two.
- Create an AMI from the snapshot. Use the following settings: Some parameters: Image Name: test for restore Architecture: x86_64 Root device name: /dev/xvda Virtualization Type: Hardware-assisted virtualization Boot mode: Use default Block device mappings:
- Volume 1: 8 GiB. gp3. 3000. 125 MB/s. Uncheck "delete on termination." Click "Create Image"
- When calling Kiss-Docker-Compose, set the AMI parameter. Example: src/integ.from-ami.ts
- Deploy. The new deployment will use the AMI which was created from your Root Volume.
Why does it work this way? Isn't this kind of roundabout? Yes, it is. I tried a variety of other approaches, but didn't get them to work. See: #3
If you destroy the stack, you could lose your EIP. What do you do if the EIP was allowlisted somewhere and you need it back?
-
You can get back the EIP by following this procedure under the heading, "Recover an Elastic IP address": https://repost.aws/knowledge-center/ec2-recover-ip-address#
-
Do NOT pass an EIP into Kiss-Docker-Compose since there is no way to import an EIP into the CDK (right now).
-
Perform the following work yourself after calling Kiss-Docker-Compose:
new cdk.aws_ec2.CfnEIPAssociation(this, `${id}-eip-association`, {
allocationId: 'the-eip-allocation-id',
instanceId: kissDockerComposeClassInstance.ec2Instance.instanceId,
});
npx projen
npx projen test
npx projen build
You may need to set some parameters since modifying src/integ.default.ts
is ill advised:
export AWS_REGION=us-east-2
Deploy:
npx cdk deploy --app='./lib/integ.default.js'