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
title: Deploy AdminForth to EC2 with terraform on GitHub actions with self-hosted Docker Registry
3
+
title: IaaC Deploy setup to Amazon EC2 with GitHub actions, Deocker, terraform and self-hosted Docker Registry
4
4
authors: ivanb
5
5
tags: [aws, terraform, github-actions]
6
6
---
7
7
8
-
This guid shows how to deploy AdminFforth to Amazon EC2 with Docker and Terraform involving Registry.
8
+
This guide shows how to deploy own Docker apps (with AdminForth as example) to Amazon EC2 instance with Docker and Terraform involving Docker self-hosted registry.
9
+
10
+
Needed resources:
11
+
- GitHub actions Free plan which includes 2000 minutes per month (1000 of 2-minute builds per month - more then enough for many projects, if you are not running tests etc). Extra builds would cost `0.008$` per minute.
12
+
- AWS account where we will auto-spawn EC2 instance. We will use t3a.small instance (2 vCPUs, 2GB RAM) which costs `~14$` per month in `us-east-1` region (cheapest region).
13
+
- $2 per month for EBS gp2 storage (20GB) for EC2 instance
14
+
15
+
This is it, registry will be auto-spawned on EC2 instance, so no extra costs for it. Also GitHub storage is not used, so no extra costs for it.
16
+
17
+
The setup has next features:
18
+
- Build process is done using IaaC approach with HashiCorp Terraform, so almoast no manual actions are needed from you. Every resource including EC2 server instance is described in code which is commited to repo and should not be manually clicked.
19
+
- Docker build process is done on GitHub actions, so EC2 server is not overloaded
20
+
- Changes in infrastructure including changing server type, adding S3 Bucket, changing size of sever Disk is also done in code and can be done by commiting code to repo.
21
+
- Docker images and cache are stored on EC2 server, so no extra costs for Docker registry are needed.
22
+
- Total build time for average commit to AdminForth app (with vite rebuilds) is around 2 minutes.
23
+
24
+
<!-- truncate -->
25
+
26
+
27
+
# Building on CI versus building on EC2?
9
28
10
29
Previously we had a blog post about [deploying AdminForth to EC2 with Terraform without registry](/blog/compose-ec2-deployment-github-actions/). That method might work well but has a significant disadvantage - build process happens on EC2 itself and uses EC2 RAM and CPU. This can be a problem if your EC2 instance is well-loaded without extra free resources. Moreover, low-end EC2 instances have a small amount of RAM and CPU, so build process which involves vite/tsc/etc can be slow or even fail.
11
30
@@ -22,9 +41,6 @@ Quick difference between approaches from previous post and current post:
22
41
| Disadvantages | Build on EC2 requires additional server RAM / overloads CPU | More terraform code is needed. registry cache might require small extra space on EC2 |
23
42
24
43
25
-
26
-
<!-- truncate -->
27
-
28
44
## Chellenges when you build on CI
29
45
30
46
A little bit of theory.
@@ -35,11 +51,11 @@ When you move build process to CI you have to solve next chellenges:
35
51
36
52
### Delivering images
37
53
38
-
### Exporing images to tar files
54
+
####Exporing images to tar files
39
55
40
56
Simplest option which you can find is save docker images to tar files and deliver them to EC2. We can easily do it in terraform (using `docker save -o ...` command on CI and `docker load ...` command on EC2). However this option has a significant disadvantage - it is slow. Docker images are big (always include all layers, without any options), so it takes infinity to do save/load and another infinity to transfer them to EC2 (via relatively slow rsync/SSH and relatively GitHub actions outbound connection).
41
57
42
-
### Docker registry
58
+
####Docker registry
43
59
44
60
Second and right option which we will use here - involve Docker registry. Docker registry is a repository which stores docker images. It does storing in a smart way - it stores layers, so if you will update last layer and push it from CI to registry, only last layer will be pushed to registry and then pulled to EC2.
45
61
To give you row compare - whole-layers image might took `1GB`, but last layer created by `npm run build` command might take `50MB`. And most builds you will do only last layer changes, so it will be 20 times faster to push/pull last layer than whole image.
@@ -65,8 +81,7 @@ So when build-in Docker cache can't be used, there is one alternative - Docker B
65
81
So BuildKit allows you to connect external storage. There are several options, but most sweet for us is using Docker registry as cache storage (not only as images storage). However drowback appears here.
66
82
Previously we used docker compose to run our app, it can be used to both build and deploy images, but has [issues with external cache connection](https://github.com/docker/compose/issues/11072#issuecomment-1848974315). While they are not solved we have to use `docker buildx bake` command to build images. It is not so bad, but is another point of configuration which we will cover in this post.
67
83
68
-
# Practice - deploy AdminForth to EC2 with terraform on GitHub actions with self-hosted Docker Registry
69
-
84
+
# Practice - deploy setup
70
85
71
86
Assume you have your AdminForth project in `myadmin`.
72
87
@@ -86,7 +101,6 @@ RUN --mount=type=cache,target=/tmp npx tsx bundleNow.ts
86
101
CMD ["npm", "run", "startLive"]
87
102
```
88
103
89
-
90
104
## Step 2 - compose.yml
91
105
92
106
create folder `deploy` and create file `compose.yml` inside:
@@ -144,6 +158,7 @@ Create `deploy/.gitignore` file with next content:
144
158
*.tfstate.*
145
159
*.tfvars
146
160
tfplan
161
+
.env.live
147
162
```
148
163
149
164
## Step 5 - Main terraform file main.tf
@@ -158,7 +173,7 @@ Create file `main.tf` in `deploy` folder:
# force Terraform to reinitialize the backend without migrating the state.
617
636
terraform init -reconfigure
618
637
terraform plan -out=tfplan
@@ -629,4 +648,102 @@ Go to your GitHub repository, then `Settings` -> `Secrets` -> `New repository se
629
648
- `VAULT_SSH_PUBLIC_KEY`- make `cat ~/.ssh/id_rsa.pub` and paste to GitHub secrets
630
649
631
650
632
-
Now you can push your changes to GitHub and see how it will be deployed automatically.
651
+
Now you can push your changes to GitHub and see how it will be deployed automatically.
652
+
653
+
654
+
### Adding secrets
655
+
656
+
Once you will have sensitive tokens/passwords in your apps you have to store them in a secure way.
657
+
658
+
Simplest way is to use GitHub secrets.
659
+
660
+
Let's imagine you have `OPENAI_API_KEY` which will be used one of AI-powered plugins of adminforth. We can't put this key to the code, so we have to store it in GitHub secrets.
661
+
662
+
Open your GitHub repository, then `Settings` -> `Secrets` -> `New repository secret` and add `VAULT_OPENAI_API_KEY` with your key.
663
+
664
+
Now open GitHub actions file and add it to the `env` section:
Copy file name to clipboardExpand all lines: adminforth/documentation/docs/tutorial/05-Plugins/11-oauth.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,16 +20,16 @@ You need to get the client ID and client secret from your OAuth2 provider.
20
20
For Google:
21
21
1. Go to the [Google Cloud Console](https://console.cloud.google.com)
22
22
2. Create a new project or select an existing one
23
-
3. Go to "APIs & Services" → "Credentials"
23
+
3. Go to `APIs & Services` → `Credentials`
24
24
4. Create credentials for OAuth 2.0 client IDs
25
25
5. Select application type: "Web application"
26
26
6. Add your application's name and redirect URI
27
-
7.Set the redirect URI to`http://your-domain/oauth/callback`
27
+
7.In "Authorized redirect URIs", add next URI: `https://your-domain/oauth/callback`,`http://localhost:3500/oauth/callback`. Please remember to include BASE_URL in the URI if you are using it in project e.g. `https://your-domain/base/oauth/callback`
0 commit comments