You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In this project, you'll build a simple Go server application and Dockerise it to run within a container. You'll write tests that run against the container, and then build GitHub actions automate continuous testing and release of the application. You'll then run it in the cloud by pushing the container image to Amazon AWS Elastic Container Repository, and then launch it in Amazon AWS Elastic Container Service using the user interface.
4
+
5
+
> ⚠️ This project requires you to have access to an Amazon AWS account, with permissions to configure ECS, ECR, Fargate, and Elastic Load Balancing. Ask on CYF Slack for help with that.
6
+
3
7
Learning objectives:
4
8
5
9
- Det up Docker locally
@@ -9,6 +13,201 @@ Learning objectives:
9
13
- Deploy images to Elastic Cloud resources using Elastic Container Service
10
14
- Destroy cloud resources to mitigate cost
11
15
12
-
This project relies on access to an AWS account, with permissions to configure ECS, Fargate, and Elastic Load Balancing.
16
+
Timebox: 2 days
17
+
18
+
## Project
19
+
20
+
This project will require us to pull together information from several different guides to get an application developed locally to run in the cloud. This project will give you experience of building and deploying a real applications. Our focus here is **not** on the Go code, but on the infrastructure around it.
21
+
22
+
> **Important:** You will need a GitHub repo to complete this becase we'll be using [GitHub Actions](https://docs.github.com/en/actions). If you are not already working in the `immersive-go-course` repository, now would be a good time!
23
+
24
+
### Motivation
25
+
26
+
We're going to build a simple Go server, and then _containerise_ it.
27
+
28
+
> In this project, we'll use the terms containerise and dockerise interchangeably to mean the same thing: making an application run in a container using Docker.
29
+
30
+
A container is a "sandboxed" process on your computer that is isolated from all other processes, unless specifically allowed.
31
+
32
+
When running a container, it uses an isolated filesystem. This filesystem is provided by a container image. Since the image contains the container’s filesystem, it must contain everything needed to run an application - all dependencies, configurations, scripts, binaries, etc. The image also contains other configuration for the container, such as environment variables, a default command to run, and other metadata.
33
+
34
+
When you combine images and containers, we can package whole applications in way that is transferrable (we can create them completely separately from running them) and highly reproducible. Both of these are very important in a production environment.
35
+
36
+
The isolation and security allows you to run many containers simultaneously on a given host. Containers are lightweight and contain everything needed to run the application, so you do not need to rely on what is currently installed on the host. You can easily share containers while you work, and be sure that everyone you share with gets the same container that works in the same way.
37
+
38
+
To summarize, a container:
39
+
40
+
- is a runnable instance of an image. You can create, start, stop, move, or delete containers
41
+
- can be run on local machines, virtual machines or deployed to the cloud
42
+
- is portable (can be run on any OS)
43
+
- is isolated from other containers and runs its own software, binaries, and configurations
44
+
45
+
## Background
46
+
47
+
### Docker
48
+
49
+
Docker is an open platform for developing, shipping, and running applications, based around containers and images. Docker provides tooling and a platform to manage the lifecycle of your containers:
50
+
51
+
- Develop your application and its supporting components using containers
52
+
- The container becomes the unit for distributing and testing your application.
53
+
- When you’re ready, deploy your application into your production environment, as a container or an orchestrated service. This works the same whether your production environment is a local data center, a cloud provider, or a hybrid of the two.
54
+
55
+
Read [this guide to get an overview of Docker](https://docs.docker.com/get-started/overview/).
56
+
57
+
To build hands-on familiarity with Docker, complete parts 1, 2 and 3 of [this tutorial](https://docs.docker.com/get-started/), after which you should know about:
58
+
59
+
- Running applications with docker: `docker run -dp 80:80 docker/getting-started`
60
+
- Containers and images: process & filesystem isolation
61
+
-`Dockerfile`: a text-based script of instructions that is used to create a container image
62
+
- Starting, managing processes and images: `docker ps` and `docker rm -f`s
63
+
64
+
Next work through the [Go Docker tutorial](https://docs.docker.com/language/golang/), after which you should know about:
65
+
66
+
- Dockerising a go application
67
+
- Starting and stopping containers
68
+
- Volumes & networking between docker containers
69
+
- Basics of docker-compose and CockroachDB
70
+
- GitHub actions for pushing the image to Docker Hub
71
+
72
+
Spend some time on these steps, and feel free to complete other tutorials too. It's very important to grasp the core ideas of containers, images and docker:
73
+
74
+
- Docker is a set of tools for managing containers and images
75
+
- Images are frozen file systems that hold everything a container needs to run
76
+
- Containers are your running application, based on an image
77
+
78
+
### Cloud hosting in AWS
79
+
80
+
We're going to host our application in the cloud, specifically in Amazon Web Services (AWS). AWS is a large suite of products for running technology in the cloud.
81
+
82
+
The set of AWS products we're going to interact with directly are:
83
+
84
+
- Elastic Container Repository (ECS): store images that can later be run as containers
85
+
- Elastic Container Service (ECR): run containers, including all the infrastructure needed to make them accessible to the internet
86
+
- Identity & Access Management (IAM): manage security, identity and access within AWS
87
+
88
+
To get familiar with ECS, run through the [AWS tutorial](https://aws.amazon.com/getting-started/hands-on/deploy-docker-containers/), after which you should know about:
89
+
90
+
- Container & task: like a blueprint for your application
91
+
- Service & load balancing: launches and maintains copies of the task definition in your cluster
92
+
- Cluster: compute resources used to run the service & load balancing
93
+
94
+
## Building & Dockerising server
95
+
96
+
The rest of this project will cover putting this all together to run an application that we've written on Elastic Container Service. The steps will be:
97
+
98
+
- Build a simple Go server
99
+
- Dockerise it to run locally within a container
100
+
- Write tests that run against the docker container
101
+
- Build GitHub actions automate CI/CD
102
+
- Push the image to ECR
103
+
- Launch it in ECS using the UI
104
+
105
+
Make sure to commit code as you work with clear messages. We are going to work in a tight loop with GitHub — pushing code and testing it — so [good Git hygiene](https://betterprogramming.pub/six-rules-for-good-git-hygiene-5006cf9e9e2) is important.
106
+
107
+
## Server
108
+
109
+
Write a simple server in Go with this behaviour when you `go run` it:
110
+
111
+
```console
112
+
> curl localhost:8090
113
+
Hello, world.
114
+
115
+
> curl localhost:8090/ping
116
+
pong
117
+
```
118
+
119
+
Make sure that the port is configurable with an environment variable `HTTP_PORT`, and defaults to port `80`.
120
+
121
+
### Dockerise
122
+
123
+
Write a `Dockerfile` for the application. Optionally, make this a bit harder by including a multi-stage build.
Write some simple tests for your server. For writing tests, we'll use [dockertest](https://github.com/ory/dockertest).
145
+
146
+
The principle of `dockertest` is to test against real running services, end to end, in containers. The advantage is that these services can be destroyed after testing and recreated from scratch, so that the tests are highly reproducible.
147
+
148
+
Following [docs here](https://github.com/ory/dockertest) and [example here](https://github.com/olliefr/docker-gs-ping), write some tests.
149
+
150
+
Go dependencies are installed by `go get`.
151
+
152
+
Make sure to `COPY go.sum ./` in your `Dockerfile`. [Read this guide to understand why](https://golangbyexample.com/go-mod-sum-module/).
153
+
154
+
## CI/CD
155
+
156
+
A set of good practices has exists for developing software for production use by thousands or millions of people. One example of this is Continuous Integration & Continuous Deployment, referred to as CI/CD. We're going to focus on the "CI" component of this, which means:
157
+
158
+
- working with version control (Git)
159
+
- running automated checks on the code added to Git (specifically, test)
160
+
- automating the steps required to "build" a version of the application that could be deployed to production (specifically, building a Docker image and pushing it to a shared repository)
161
+
162
+
This automation runs in the cloud — _not_ on developer laptops — so that it is highly reproducible and the same for whoever writes the the code. The idea is that, should the tests fail, the code will not be built or pushed to the repository, so it's harder to push buggy code to production.
163
+
164
+
### Github Action: running tests
165
+
166
+
The system we'll use for CI testing and image creation is [GitHub Actions](https://docs.github.com/en/actions).
167
+
168
+
Follow [this guide on GitHub](https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go) to get a GitHub action testing the code.
169
+
170
+
You'll be adding a single file to the `.github/workflows` directory of the repo.
171
+
172
+
Pay attention to the following:
173
+
174
+
```yml
175
+
# Make sure that the working directory for the tests is correct
176
+
defaults:
177
+
run:
178
+
working-directory: docker-cloud
179
+
```
180
+
181
+
And:
182
+
183
+
```yml
184
+
# Use the right go version file and dependency path
185
+
# Note that these are *not* subject to the working-directory defaults
186
+
- name: Set up Go
187
+
uses: actions/setup-go@v3
188
+
with:
189
+
go-version-file: "docker-cloud/go.mod"
190
+
cache-dependency-path: "docker-cloud/go.sum"
191
+
cache: true
192
+
```
193
+
194
+
### Github Action: publish image
195
+
196
+
TODO: @tgvashworth finish this section
197
+
198
+
Next, we're going build an action that creates and pushes the image to AWS Elastic Container Registry.
199
+
200
+
This is complex.
201
+
202
+
The [guide here](https://benoitboure.com/securely-access-your-aws-resources-from-github-actions) was very helpful.
0 commit comments