Skip to content

Commit

Permalink
support setting swap (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gregory-Ledray authored Jul 26, 2024
1 parent e14f6ea commit a15251d
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 2 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ Move your Docker Compose application from your local machine to the cloud in 3 m

## Install

`npm i kiss-docker-compose`
```
npm i kiss-docker-compose
npm i aws-cdk-lib
```

## Inline Docker Compose File

Expand Down Expand Up @@ -129,5 +132,5 @@ export AWS_REGION=us-east-2
Deploy:

```
cdk deploy --app='./lib/integ.default.js'
npx cdk deploy --app='./lib/integ.default.js'
```
36 changes: 36 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@ export function Ec2InstanceRole(scope: Construct, id: string): cdk.aws_iam.Role
* @param regionOfEC2Instances EC2 instance region. Usually cdk.Stack.of(this).region
* @param regionOfECR ECR region. Usually cdk.Stack.of(this).region
* @param dockerComposeFileAsString always the same as props.dockerComposeFileAsString
* @param swapCountIn128MBChunks Default 0. If set to null or 0 or less, does not set swap.
* Sets up a swap file with size = Math.Round(swapCountIn128MBChunks) * 128M.
* For example, if swapCountIn128MBChunks == 1 then there will be 128MB of swap. There is NOT a check to verify there is enough
* storage on the instance to support the swap file size.
* @returns A NEW EC2 instance which will run Docker Compose when launched and when restarted.
*/
export function EC2Instance(
Expand All @@ -261,6 +265,7 @@ export function EC2Instance(
regionOfEC2Instances: string,
regionOfECR: string,
dockerComposeFileAsString: string,
swapCountIn128MBChunks?: number,
): cdk.aws_ec2.Instance {
if (
scope == null ||
Expand Down Expand Up @@ -330,9 +335,12 @@ export function EC2Instance(
ec2.InitFile.fromString('/home/ec2-user/docker-compose.yml', dockerComposeFileAsString),
ec2.InitFile.fromString('/etc/install.sh', installAndStartupScript()),
ec2.InitFile.fromString('/etc/systemd/system/docker-compose-app.service', dockerComposeAppService()),
ec2.InitFile.fromString('/etc/set-up-swap.sh', setUpSwap(swapCountIn128MBChunks)),
ec2.InitFile.fromString('/home/ec2-user/docker-compose-setup.sh', dockerComposeSetup(cdk.Stack.of(scope).account, regionOfECR, repoURIs)),
ec2.InitCommand.shellCommand('chmod +x /etc/install.sh'),
ec2.InitCommand.shellCommand('/etc/install.sh'),
ec2.InitCommand.shellCommand('chmod +x /etc/set-up-swap.sh'),
ec2.InitCommand.shellCommand('sudo /etc/set-up-swap.sh'),

// The very first time we start the machine, we need to start the unit because it won't start automatically without rebooting
ec2.InitCommand.shellCommand('sudo systemctl start docker-compose-app.service'),
Expand Down Expand Up @@ -459,3 +467,31 @@ sudo systemctl enable docker-compose-app
// /etc/install.sh
return `${installDocker}${installDockerCompose}${dockerOnStartup}`;
}

function setUpSwap(swapCountIn128MBChunks: number | undefined): string {
if (swapCountIn128MBChunks == null || swapCountIn128MBChunks <= 0) {
return `#!/bin/bash
echo "NOT setting up swap"
`;
}
swapCountIn128MBChunks = Math.round(swapCountIn128MBChunks);

return `#!/bin/bash
# mounting should already be done
# sudo mount /dev/xvda2 /mnt
# Create the swap file
sudo dd if=/dev/zero of=/swapfile bs=128M count=${swapCountIn128MBChunks.toString()}
# permissions
sudo chmod 600 /swapfile
# make it swap
sudo mkswap /swapfile
sudo swapon /swapfile
# Add to fstab so swap persists after restarting
echo "\n/swapfile swap swap defaults 0 0\n" >> /etc/fstab
`;
}

37 changes: 37 additions & 0 deletions test/use-swap.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { App, Stack } from 'aws-cdk-lib';
import * as cdk from 'aws-cdk-lib';
import { Template } from 'aws-cdk-lib/assertions';
import { dockerComposeFileAsString } from './docker-compose-file-as-string';
import * as KissDockerCompose from '../src/index';

const mockApp = new App();
const stack = new Stack(mockApp);

// Supplying EC2Instance as an argument overrides / ignores other properties
// So we only need to provide this one thing to get the service to deploy with everything we want
const vpc = KissDockerCompose.VPC(stack, 'testing-stack-vpc');
const role = KissDockerCompose.Ec2InstanceRole(stack, 'testing-stack-role');
const instanceSecurityGroup = KissDockerCompose.InstanceSecurityGroup(stack, 'testing-stack-sg', vpc);
const ec2Instance = KissDockerCompose.EC2Instance(stack, 'testing-stack-ec2-instance', vpc, role, instanceSecurityGroup, [], cdk.aws_ec2.InstanceSize.SMALL, 'us-east-2', 'us-east-2', dockerComposeFileAsString, 10);

new KissDockerCompose.KissDockerCompose(stack, 'testing-stack', {
dockerComposeFileAsString,
ec2Instance,
});
const minimalConfigurationTemplate = Template.fromStack(stack);

test('VPC should exist', () => {
minimalConfigurationTemplate.hasResource('AWS::EC2::VPC', {});
});

test('Role should exist', () => {
minimalConfigurationTemplate.hasResource('AWS::IAM::Role', {});
});

test('Security group should exist', () => {
minimalConfigurationTemplate.hasResource('AWS::EC2::SecurityGroup', {});
});

test('EC2 Instance should exist', () => {
minimalConfigurationTemplate.hasResource('AWS::EC2::Instance', {});
});

0 comments on commit a15251d

Please sign in to comment.