Initial work on CDK+fargate.
This commit is contained in:
parent
4c5246e5fa
commit
be3f44c7b1
|
@ -0,0 +1,8 @@
|
||||||
|
*.js
|
||||||
|
!jest.config.js
|
||||||
|
*.d.ts
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# CDK asset staging directory
|
||||||
|
.cdk.staging
|
||||||
|
cdk.out
|
|
@ -0,0 +1,6 @@
|
||||||
|
*.ts
|
||||||
|
!*.d.ts
|
||||||
|
|
||||||
|
# CDK asset staging directory
|
||||||
|
.cdk.staging
|
||||||
|
cdk.out
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Welcome to your CDK TypeScript project
|
||||||
|
|
||||||
|
This is a blank project for CDK development with TypeScript.
|
||||||
|
|
||||||
|
The `cdk.json` file tells the CDK Toolkit how to execute your app.
|
||||||
|
|
||||||
|
## Useful commands
|
||||||
|
|
||||||
|
* `npm run build` compile typescript to js
|
||||||
|
* `npm run watch` watch for changes and compile
|
||||||
|
* `npm run test` perform the jest unit tests
|
||||||
|
* `cdk deploy` deploy this stack to your default AWS account/region
|
||||||
|
* `cdk diff` compare deployed stack with current state
|
||||||
|
* `cdk synth` emits the synthesized CloudFormation template
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
import 'source-map-support/register';
|
||||||
|
import * as cdk from '@aws-cdk/core';
|
||||||
|
import { WarpStack } from '../lib/warp';
|
||||||
|
|
||||||
|
const app = new cdk.App();
|
||||||
|
|
||||||
|
new WarpStack(app, 'warp-us-east-1', {
|
||||||
|
env: { account: '864566598233', region: 'us-east-1' },
|
||||||
|
});
|
||||||
|
|
||||||
|
new WarpStack(app, 'warp-us-west-2', {
|
||||||
|
env: { account: '864566598233', region: 'us-west-2' },
|
||||||
|
});
|
||||||
|
|
||||||
|
app.synth();
|
|
@ -0,0 +1,105 @@
|
||||||
|
{
|
||||||
|
"vpc-provider:account=864566598233:filter.isDefault=true:region=us-east-1:returnAsymmetricSubnets=true": {
|
||||||
|
"vpcId": "vpc-0eb5406e69a058c21",
|
||||||
|
"vpcCidrBlock": "172.31.0.0/16",
|
||||||
|
"availabilityZones": [],
|
||||||
|
"subnetGroups": [
|
||||||
|
{
|
||||||
|
"name": "Public",
|
||||||
|
"type": "Public",
|
||||||
|
"subnets": [
|
||||||
|
{
|
||||||
|
"subnetId": "subnet-098223d57b90bc5ba",
|
||||||
|
"cidr": "172.31.0.0/20",
|
||||||
|
"availabilityZone": "us-east-1a",
|
||||||
|
"routeTableId": "rtb-00247d339210de603"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subnetId": "subnet-0f85396c1e654088a",
|
||||||
|
"cidr": "172.31.80.0/20",
|
||||||
|
"availabilityZone": "us-east-1b",
|
||||||
|
"routeTableId": "rtb-00247d339210de603"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subnetId": "subnet-0da18611f81d0ee65",
|
||||||
|
"cidr": "172.31.16.0/20",
|
||||||
|
"availabilityZone": "us-east-1c",
|
||||||
|
"routeTableId": "rtb-00247d339210de603"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subnetId": "subnet-04ec9401177026153",
|
||||||
|
"cidr": "172.31.32.0/20",
|
||||||
|
"availabilityZone": "us-east-1d",
|
||||||
|
"routeTableId": "rtb-00247d339210de603"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subnetId": "subnet-09990358c6611a867",
|
||||||
|
"cidr": "172.31.48.0/20",
|
||||||
|
"availabilityZone": "us-east-1e",
|
||||||
|
"routeTableId": "rtb-00247d339210de603"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subnetId": "subnet-09eefe16a158ac97d",
|
||||||
|
"cidr": "172.31.64.0/20",
|
||||||
|
"availabilityZone": "us-east-1f",
|
||||||
|
"routeTableId": "rtb-00247d339210de603"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"vpc-provider:account=864566598233:filter.isDefault=true:region=us-west-2:returnAsymmetricSubnets=true": {
|
||||||
|
"vpcId": "vpc-0e1c6b8dc284b5ea8",
|
||||||
|
"vpcCidrBlock": "172.31.0.0/16",
|
||||||
|
"availabilityZones": [],
|
||||||
|
"subnetGroups": [
|
||||||
|
{
|
||||||
|
"name": "Public",
|
||||||
|
"type": "Public",
|
||||||
|
"subnets": [
|
||||||
|
{
|
||||||
|
"subnetId": "subnet-0b20049ea38baab49",
|
||||||
|
"cidr": "172.31.16.0/20",
|
||||||
|
"availabilityZone": "us-west-2a",
|
||||||
|
"routeTableId": "rtb-02fa3d3e8c3c073a2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subnetId": "subnet-035cb5403ca3a6fd0",
|
||||||
|
"cidr": "172.31.32.0/20",
|
||||||
|
"availabilityZone": "us-west-2b",
|
||||||
|
"routeTableId": "rtb-02fa3d3e8c3c073a2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subnetId": "subnet-08a943f1d7ffe1269",
|
||||||
|
"cidr": "172.31.0.0/20",
|
||||||
|
"availabilityZone": "us-west-2c",
|
||||||
|
"routeTableId": "rtb-02fa3d3e8c3c073a2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subnetId": "subnet-05ce9ae279372b111",
|
||||||
|
"cidr": "172.31.48.0/20",
|
||||||
|
"availabilityZone": "us-west-2d",
|
||||||
|
"routeTableId": "rtb-02fa3d3e8c3c073a2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"acknowledged-issue-numbers": [
|
||||||
|
19836
|
||||||
|
],
|
||||||
|
"availability-zones:account=864566598233:region=us-east-1": [
|
||||||
|
"us-east-1a",
|
||||||
|
"us-east-1b",
|
||||||
|
"us-east-1c",
|
||||||
|
"us-east-1d",
|
||||||
|
"us-east-1e",
|
||||||
|
"us-east-1f"
|
||||||
|
],
|
||||||
|
"availability-zones:account=864566598233:region=us-west-2": [
|
||||||
|
"us-west-2a",
|
||||||
|
"us-west-2b",
|
||||||
|
"us-west-2c",
|
||||||
|
"us-west-2d"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"app": "npx ts-node --prefer-ts-exts bin/deploy.ts",
|
||||||
|
"watch": {
|
||||||
|
"include": [
|
||||||
|
"**"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"README.md",
|
||||||
|
"cdk*.json",
|
||||||
|
"**/*.d.ts",
|
||||||
|
"**/*.js",
|
||||||
|
"tsconfig.json",
|
||||||
|
"package*.json",
|
||||||
|
"yarn.lock",
|
||||||
|
"node_modules",
|
||||||
|
"test"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
|
||||||
|
"@aws-cdk/core:checkSecretUsage": true,
|
||||||
|
"@aws-cdk/core:target-partitions": [
|
||||||
|
"aws",
|
||||||
|
"aws-cn"
|
||||||
|
],
|
||||||
|
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
|
||||||
|
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
|
||||||
|
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
|
||||||
|
"@aws-cdk/aws-iam:minimizePolicies": true,
|
||||||
|
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
|
||||||
|
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
|
||||||
|
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
|
||||||
|
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
|
||||||
|
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
|
||||||
|
"@aws-cdk/core:enablePartitionLiterals": true,
|
||||||
|
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
|
||||||
|
"@aws-cdk/aws-iam:standardizedServicePrincipals": true,
|
||||||
|
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = {
|
||||||
|
testEnvironment: 'node',
|
||||||
|
roots: ['<rootDir>/test'],
|
||||||
|
testMatch: ['**/*.test.ts'],
|
||||||
|
transform: {
|
||||||
|
'^.+\\.tsx?$': 'ts-jest'
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,167 @@
|
||||||
|
import * as cdk from '@aws-cdk/core';
|
||||||
|
import * as ec2 from "@aws-cdk/aws-ec2"; // Allows working with EC2 and VPC resources
|
||||||
|
import * as iam from "@aws-cdk/aws-iam"; // Allows working with IAM resources
|
||||||
|
import * as ecs from "@aws-cdk/aws-ecs";
|
||||||
|
import * as cwl from "@aws-cdk/aws-logs";
|
||||||
|
import * as elb from "@aws-cdk/aws-elasticloadbalancingv2"
|
||||||
|
import * as ecr_assets from '@aws-cdk/aws-ecr-assets';
|
||||||
|
import * as route53 from "@aws-cdk/aws-route53";
|
||||||
|
import * as route53_targets from "@aws-cdk/aws-route53-targets"
|
||||||
|
import * as path from "path"; // Helper for working with file paths
|
||||||
|
|
||||||
|
export class WarpStack extends cdk.Stack {
|
||||||
|
constructor(scope: cdk.Construct, id: string, props: cdk.StackProps) {
|
||||||
|
super(scope, id, props);
|
||||||
|
|
||||||
|
//1. Create VPC
|
||||||
|
const vpc = new ec2.Vpc(this, 'VPC');
|
||||||
|
|
||||||
|
//2. Creation of Execution Role for our task
|
||||||
|
const execRole = new iam.Role(this, 'warp-exec-role', {
|
||||||
|
roleName: 'warp-exec-role', assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com')
|
||||||
|
})
|
||||||
|
|
||||||
|
//3. Adding permissions to the above created role...basically giving permissions to ECR image and Cloudwatch logs
|
||||||
|
execRole.addToPolicy(new iam.PolicyStatement({
|
||||||
|
actions: [
|
||||||
|
"ecr:GetAuthorizationToken",
|
||||||
|
"ecr:BatchCheckLayerAvailability",
|
||||||
|
"ecr:GetDownloadUrlForLayer",
|
||||||
|
"ecr:BatchGetImage",
|
||||||
|
"logs:CreateLogStream",
|
||||||
|
"logs:PutLogEvents"
|
||||||
|
], effect: iam.Effect.ALLOW, resources: ["*"]
|
||||||
|
}));
|
||||||
|
|
||||||
|
//4. Create the ECS fargate cluster
|
||||||
|
const cluster = new ecs.Cluster(this, 'warp-cluster', { vpc, clusterName: "warp-cluster" });
|
||||||
|
|
||||||
|
//5. Create a task definition for our cluster to invoke a task
|
||||||
|
const taskDef = new ecs.FargateTaskDefinition(this, "warp-task", {
|
||||||
|
family: 'warp-task',
|
||||||
|
executionRole: execRole,
|
||||||
|
taskRole: execRole,
|
||||||
|
volumes: [{ name: "cert" }],
|
||||||
|
});
|
||||||
|
|
||||||
|
//6. Create log group for our task to put logs
|
||||||
|
const log_group = cwl.LogGroup.fromLogGroupName(this, 'warp-log-group', '/ecs/warp-task');
|
||||||
|
|
||||||
|
const log = new ecs.AwsLogDriver({
|
||||||
|
logGroup: log_group ? log_group : new cwl.LogGroup(this, 'warp-log-group', { logGroupName: '/ecs/warp-task' }),
|
||||||
|
streamPrefix: 'ecs'
|
||||||
|
})
|
||||||
|
|
||||||
|
// ?? Build the docker images
|
||||||
|
const player_image = new ecr_assets.DockerImageAsset(this, 'warp-player-image', {
|
||||||
|
directory: path.join(__dirname, '/../../player'),
|
||||||
|
});
|
||||||
|
|
||||||
|
const server_image = new ecr_assets.DockerImageAsset(this, 'warp-server-image', {
|
||||||
|
directory: path.join(__dirname, '/../../server'),
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
const media_image = new ecr_assets.DockerImageAsset(this, 'warp-media-image', {
|
||||||
|
directory: path.join(__dirname, '/../../media'),
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
//7. Create container for the task definition from ECR image
|
||||||
|
var player_container = taskDef.addContainer("warp-player-container", {
|
||||||
|
image: ecs.ContainerImage.fromDockerImageAsset(player_image),
|
||||||
|
logging: log,
|
||||||
|
portMappings: [{
|
||||||
|
containerPort: 80,
|
||||||
|
hostPort: 80,
|
||||||
|
protocol: ecs.Protocol.TCP
|
||||||
|
}, {
|
||||||
|
containerPort: 443,
|
||||||
|
hostPort: 443,
|
||||||
|
protocol: ecs.Protocol.TCP
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
|
||||||
|
var server_container = taskDef.addContainer("warp-server-container", {
|
||||||
|
image: ecs.ContainerImage.fromDockerImageAsset(server_image),
|
||||||
|
logging: log,
|
||||||
|
portMappings: [{
|
||||||
|
containerPort: 443,
|
||||||
|
hostPort: 443,
|
||||||
|
protocol: ecs.Protocol.UDP
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
|
||||||
|
//9. Create the NLB using the above VPC.
|
||||||
|
const nlb = new elb.NetworkLoadBalancer(this, 'warp-nlb', {
|
||||||
|
loadBalancerName: 'warp-nlb',
|
||||||
|
vpc,
|
||||||
|
internetFacing: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// ?? Create a DNS entry for the nlb
|
||||||
|
const zone = route53.HostedZone.fromHostedZoneAttributes(this, "warp-zone", {
|
||||||
|
hostedZoneId: "Z0166044CZ3H7MIDXT7P", // Unfortunately we need to hard-code the route53 zone
|
||||||
|
zoneName: "quic.video",
|
||||||
|
});
|
||||||
|
|
||||||
|
const record = new route53.ARecord(this, "warp-record", {
|
||||||
|
zone: zone,
|
||||||
|
target: route53.RecordTarget.fromAlias(new route53_targets.LoadBalancerTarget(nlb)),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Route based on latency.
|
||||||
|
const recordSet = (record.node.defaultChild as route53.CfnRecordSet);
|
||||||
|
recordSet.region = props.env?.region;
|
||||||
|
recordSet.setIdentifier = props.env?.region;
|
||||||
|
|
||||||
|
//10. Add a listener on a particular port for the NLB
|
||||||
|
const http_listener = nlb.addListener('warp-http-listener', {
|
||||||
|
protocol: elb.Protocol.TCP,
|
||||||
|
port: 80,
|
||||||
|
});
|
||||||
|
|
||||||
|
const https_listener = nlb.addListener('warp-https-listener', {
|
||||||
|
protocol: elb.Protocol.TCP_UDP,
|
||||||
|
port: 443,
|
||||||
|
});
|
||||||
|
|
||||||
|
//11. Create your own security Group using VPC
|
||||||
|
const sg = new ec2.SecurityGroup(this, 'warp-player-sg', {
|
||||||
|
securityGroupName: "warp-player-sg",
|
||||||
|
vpc: vpc,
|
||||||
|
allowAllOutbound: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
//12. Add IngressRule to access the docker image
|
||||||
|
sg.addIngressRule(ec2.Peer.ipv4('0.0.0.0/0'), ec2.Port.tcp(80), 'HTTP');
|
||||||
|
sg.addIngressRule(ec2.Peer.ipv4('0.0.0.0/0'), ec2.Port.tcp(443), 'HTTPS');
|
||||||
|
sg.addIngressRule(ec2.Peer.ipv4('0.0.0.0/0'), ec2.Port.udp(443), 'HTTP/3');
|
||||||
|
|
||||||
|
//13. Create Fargate Service from cluster, task definition and the security group
|
||||||
|
const service = new ecs.FargateService(this, 'warp-service', {
|
||||||
|
cluster: cluster,
|
||||||
|
taskDefinition: taskDef,
|
||||||
|
assignPublicIp: true,
|
||||||
|
serviceName: "warp-service",
|
||||||
|
securityGroups: [sg],
|
||||||
|
});
|
||||||
|
|
||||||
|
//14. Add fargate service to the listener
|
||||||
|
http_listener.addTargets('warp-http-target', {
|
||||||
|
targetGroupName: 'warp-http-target',
|
||||||
|
protocol: elb.Protocol.TCP,
|
||||||
|
port: 80,
|
||||||
|
targets: [service],
|
||||||
|
deregistrationDelay: cdk.Duration.seconds(300)
|
||||||
|
});
|
||||||
|
|
||||||
|
https_listener.addTargets('warp-https-target', {
|
||||||
|
targetGroupName: 'warp-https-target',
|
||||||
|
protocol: elb.Protocol.TCP_UDP,
|
||||||
|
port: 443,
|
||||||
|
targets: [service],
|
||||||
|
deregistrationDelay: cdk.Duration.seconds(300)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"name": "deploy",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"bin": {
|
||||||
|
"deploy": "bin/deploy.js"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"watch": "tsc -w",
|
||||||
|
"test": "jest",
|
||||||
|
"cdk": "cdk"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/jest": "^29.2.3",
|
||||||
|
"@types/node": "18.11.9",
|
||||||
|
"aws-cdk": "^2.54.0",
|
||||||
|
"jest": "^29.3.1",
|
||||||
|
"ts-jest": "^29.0.3",
|
||||||
|
"ts-node": "^10.9.1",
|
||||||
|
"typescript": "~4.9.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@aws-cdk/aws-ec2": "^1.191.0",
|
||||||
|
"@aws-cdk/aws-ecs": "^1.191.0",
|
||||||
|
"@aws-cdk/aws-ecs-patterns": "^1.191.0",
|
||||||
|
"@aws-cdk/aws-iam": "^1.191.0",
|
||||||
|
"@aws-cdk/aws-s3-assets": "^1.191.0",
|
||||||
|
"aws-cdk-lib": "^2.63.0",
|
||||||
|
"constructs": "^10.0.0",
|
||||||
|
"source-map-support": "^0.5.21"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
// import * as cdk from 'aws-cdk-lib';
|
||||||
|
// import { Template } from 'aws-cdk-lib/assertions';
|
||||||
|
// import * as Deploy from '../lib/deploy-stack';
|
||||||
|
|
||||||
|
// example test. To run these tests, uncomment this file along with the
|
||||||
|
// example resource in lib/deploy-stack.ts
|
||||||
|
test('SQS Queue Created', () => {
|
||||||
|
// const app = new cdk.App();
|
||||||
|
// // WHEN
|
||||||
|
// const stack = new Deploy.DeployStack(app, 'MyTestStack');
|
||||||
|
// // THEN
|
||||||
|
// const template = Template.fromStack(stack);
|
||||||
|
|
||||||
|
// template.hasResourceProperties('AWS::SQS::Queue', {
|
||||||
|
// VisibilityTimeout: 300
|
||||||
|
// });
|
||||||
|
});
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2020",
|
||||||
|
"module": "commonjs",
|
||||||
|
"lib": [
|
||||||
|
"es2020"
|
||||||
|
],
|
||||||
|
"declaration": true,
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"alwaysStrict": true,
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"noUnusedParameters": false,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": false,
|
||||||
|
"inlineSourceMap": true,
|
||||||
|
"inlineSources": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"strictPropertyInitialization": false,
|
||||||
|
"typeRoots": [
|
||||||
|
"./node_modules/@types"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"cdk.out"
|
||||||
|
]
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,19 @@
|
||||||
|
FROM ubuntu
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN apt-get update && apt-get install -y nginx certbot python3-certbot-nginx
|
||||||
|
|
||||||
|
# Contains the final certificates created by certbot
|
||||||
|
VOLUME /etc/letsencrypt
|
||||||
|
|
||||||
|
# Application configuration for our site
|
||||||
|
COPY nginx/quic.video.conf /etc/nginx/conf.d/quic.video.conf
|
||||||
|
|
||||||
|
# The script to init and run nginx
|
||||||
|
COPY nginx/run.sh /run/warp-player.sh
|
||||||
|
|
||||||
|
# Copy over the web contents
|
||||||
|
COPY dist/* /var/www/quic.video
|
||||||
|
|
||||||
|
# Run the shell script
|
||||||
|
CMD /run/warp-player.sh
|
|
@ -0,0 +1,6 @@
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name quic.video;
|
||||||
|
root /var/www/quic.video;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
# Try to generate a certificate that expires in 90 days.
|
||||||
|
# This will listen on port 80 and serve a challenge file, proving we own the domain.
|
||||||
|
certbot --nginx --email kixelated@gmail.com -d quic.video --agree-tos
|
||||||
|
|
||||||
|
# The certbot nginx plugin will automatically append the certs to the configuration.
|
||||||
|
nginx
|
|
@ -0,0 +1,10 @@
|
||||||
|
FROM golang
|
||||||
|
|
||||||
|
WORKDIR /usr/src/warp
|
||||||
|
|
||||||
|
ENV GOPRIVATE=*
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN go build -v -o /usr/local/bin/warp-server .
|
||||||
|
|
||||||
|
CMD [ "warp-server" ]
|
Loading…
Reference in New Issue