Skip to content

Commit

Permalink
Setup ant-gateway for service
Browse files Browse the repository at this point in the history
  • Loading branch information
kaspar-p committed May 5, 2024
1 parent d2e81df commit 5f6c76c
Show file tree
Hide file tree
Showing 12 changed files with 247 additions and 74 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ rust-project.json

# secrets
*.env*
secrets/*
!secrets/.gitkeep

# Added by cargo
target
Expand Down
18 changes: 18 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ services:
secrets:
- twitter_creds
- database_creds

ant-data-farm:
build:
context: ./projects/ant-data-farm
Expand All @@ -26,6 +27,23 @@ services:
- ./projects/ant-data-farm/database-files:/var/lib/postgresql/data
secrets:
- database_creds

ant-gateway:
container_name: ant-gateway
build:
context: ./projects/ant-gateway
dockerfile: Dockerfile
args:
- FQDN=beta.typesofants.org
- ANT_WORKER_NUM=002
- WEBSERVER_PORT=3499
- SSL_CERT_PATH=./data/beta.typesofants.org/cert.pem
- SSL_KEY_PATH=./secrets/ssl/beta.typesofants.org/key.pem
restart: always
ports:
- "80:80"
- "443:443"

secrets:
twitter_creds:
file: ./.env.twitter
Expand Down
10 changes: 8 additions & 2 deletions docs/developer-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ There are the following components:
"doesn't exist" at runtime, just like source code doesn't exist at runtime.
It's statically compiled into a bunch of JavaScript, CSS, and HTML as a part
of the build process, and those files are served by the webserver.
- `ant-gateway`: The reverse proxy. Only a single machine can be responsible for
answering requests directed towards a domain, and then fan-out to the
individual webservers from there. It's possible that this is the same machine
as the webserver itself. It is an NGINX webserver running in a docker
container. Certificates are always a pain, I've downloaded the secret ones for
`beta.typesofants.org` and those are being used.
- `ant-host-agent`: is another webserver, a binary that runs on each host.
Usually bound to port 4499, has a single usable route today `/ping` that
returns the string `healthy ant`. It's used for an extremely basic monitoring
Expand All @@ -46,8 +52,8 @@ The following components are more experimental, may never see the light of day:
- `ant-building-projects`: The build servers, for eventual CI/CD deployments.
Making changes currently involves _taking down_ the process and then rebooting
it, or at least restarting the daemon that starts that process. This is fine
for a web server that likely has many hosts running the same binary, but for
something like a database not that fine. This would likely be a web server
for a webserver that likely has many hosts running the same binary, but for
something like a database not that fine. This would likely be a webserver
listening on a host, and would checkout, build, and store build artifacts.
Those artifacts would be stored until the next time a deployment is needed.
- `ant-owning-artifacts`: IDK. Probably the same as the previous one, but
Expand Down
106 changes: 92 additions & 14 deletions docs/libre-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,52 @@

Unbox the board, in my case I had a Libre AML-S905X-CC.

Following https://medium.com/@johnhebron/setting-up-a-le-potato-raspberry-pi-alternative-with-ubuntu-server-22-04-linux-from-scratch-8b7c22c8e4b1
download the version, I did `ubuntu-22.04.3-preinstalled-server-arm64+aml-s905x-cc.img.xz`
unzipped it with
Following
<https://medium.com/@johnhebron/setting-up-a-le-potato-raspberry-pi-alternative-with-ubuntu-server-22-04-linux-from-scratch-8b7c22c8e4b1>
download the version, I did
`ubuntu-22.04.3-preinstalled-server-arm64+aml-s905x-cc.img.xz` unzipped it with

```bash
unxz ubuntu-22.04.3-preinstalled-server-arm64+aml-s905x-cc.img.xz
```

Using Balena Etcher (`brew install balenaetcher`) plug in the microsd card and flash it. Plug in Ethernet _before_ power, to initialize on the same wifi. Find it with:
Using Balena Etcher (`brew install balenaetcher`) plug in the microSD card and
flash it. Plug in Ethernet _before_ power, to initialize on the same wifi. Find
it with:

```bash
sudo arp-scan --localnet
```

And SSH in with `ubuntu@<ip>`. Mine was `192.168.2.53`. Then change the password to any temporary ubuntu password! Then, run (this will take a while):
And SSH in with `ubuntu@<ip>`. Mine was `192.168.2.53`. Then change the password
to any temporary ubuntu password! Then, run (this will take a while):

```bash
sudo apt update
supo apt upgrade
sudo apt upgrade
sudo snap install docker

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
nvm install --lts

source ~/.bashrc
```

And in `/etc/cloud/cloud.cfg` change `preserve_hostname: false` to `true`. Change the hostname to the one you decide on for this machine. Others are named `antworker<num>`. Set it with:
And in `/etc/cloud/cloud.cfg` change `preserve_hostname: false` to `true`.
Change the hostname to the one you decide on for this machine. Others are named
`antworker<num>`. Set it with:

```bash
export ANT_HOSTNAME=antworker<num>
sudo hostnamectl set-hostname $ANT_HOSTNAME
sudo cat /etc/hostname
```
and make sure it's the right output. Also `cat /etc/hosts/ and make sure there is a line like:

and make sure it's the right output. Also `cat /etc/hosts/ and make sure there
is a line like:

```txt
127.0.1.1 $ANT_HOSTNAME
Expand All @@ -44,7 +61,8 @@ and that's it!

## User setup, networking

Create an `ant` user on the host, and rename the `ubuntu` group to the `ants` group:
Create an `ant` user on the host, and rename the `ubuntu` group to the `ants`
group:

```bash
sudo adduser ant
Expand All @@ -58,15 +76,21 @@ Add the `ant` user to be able to `sudo` by adding via `visudo`:
ant ALL=(ALL:ALL) ALL
```

To get DNS working, go to the [CloudFlare Domain](https://dash.cloudflare.com/3196bd788e22028260c62531239ac7c2/typesofants.org/dns/records) and add a record for `antworker<num>.hosts.typesofants.org` pointing to the LOCAL IP. This makes local lookups work, but doesn't expose anything.
To get DNS working, go to the
[CloudFlare Domain](https://dash.cloudflare.com/3196bd788e22028260c62531239ac7c2/typesofants.org/dns/records)
and add a record for `antworker<num>.hosts.typesofants.org` pointing to the
LOCAL IP. This makes local lookups work, but doesn't expose anything.

To get the SSH key you have working to login to that user, locally from your Mac on the network, run:
To get the SSH key you have working to login to that user, locally from your Mac
on the network, run:

```bash
ssh-copy-id -i ~/.ssh/id_typesofants_ed25519 ant@<hostname>.hosts.typesofants.org
```

Please! Test logging into this machine with `ssh2ant <hostname_or_num>` and make sure it works before logging out again! Finally, restart the various services we have changed with, on the new host:
Please! Test logging into this machine with `ssh2ant <hostname_or_num>` and make
sure it works before logging out again! Finally, restart the various services we
have changed with, on the new host:

```bash
sudo systemctl restart sshd
Expand All @@ -91,23 +115,27 @@ git checkout v1.0
```

Install the utilities defined in the package:

```bash
echo 'export PATH="$PATH:/home/ant/types-of-ants/bin"' >> ~/.bashrc && source ~/.bashrc
```

Install Cargo and Rust:

```bash
sudo snap install rustup --classic && \
rustup default stable
```

And build the project. This will take a long time, especially on these slow ass machines.
And build the project. This will take a long time, especially on these slow ass
machines.

```bash
cargo build
df
```

## Daemonization
## Daemonization of `ant-host-agent`

First, we setup ant-host-agent with a .env file:

Expand Down Expand Up @@ -143,3 +171,53 @@ and enable it with:
sudo systemctl enable ant-host-agent.service
sudo systemctl start ant-host-agent.service
```

## Daemonization of `ant-on-the-web`

We also need a .env file here, with the port and some database credentials. For
the file `./projects/ant-on-the-web/.env`, fill in the details:

```txt
DB_PG_USER=...
DB_PG_NAME=...
DB_PG_PASSWORD=...
DB_PG_PORT=7000
DB_HOST=...
```

Then, we make `ant-on-the-web` a systemd service:

```bash
sudo nano /etc/systemd/system/ant-on-the-web.service
```

with the content:

```txt
[Unit]
Description=The typesofants web server!
[Service]
Type=simple
ExecStart=/home/ant/types-of-ants/target/debug/ant-on-the-web
WorkingDirectory=/home/ant/types-of-ants/projects/ant-on-the-web/server
Restart=always
[Install]
WantedBy=multi-user.target
```

And enable it with:

```bash
sudo systemctl enable ant-on-the-web.service && \
sudo systemctl start ant-on-the-web.service
```

## Reserve the local dynamic IP

To keep this local IP reserved on the network so it doesn't change anymore, go
to <http://192.168.2.1> > My Devices > Ethernet, and select the current
antworker.

Make sure to select the IP it is on as _Reserved_.
40 changes: 40 additions & 0 deletions docs/production-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Production Guide

Notes I take as I attempt to deploy various services to various hosts

## Production guide for `ant-on-the-web`

Install dependencies and build the project with

```bash
cd ./projects/ant-on-the-web/website
npm ci
npm run build
```

This will take a while, and will create a `./out` directory with static HTML,
CSS, and JavaScript build artifacts. Copy these into the right location with:

```bash
mv ./out ../server/static
```

for the Rust webserver to pick them up. Build the rust webserver with:

```bash
cd ../server
cargo build
```

which will also take a long time. It should be daemonized on this host (see
[./libre-notes.md]), and we can restart it with:

```bash
sudo systemctl restart ant-on-the-web.service
```

## Production guide for `ant-gateway`

First, make sure that this host is the one being port-forwarded to on the local
network. By going to <http://192.168.2.1> > Advanced > Port Forwarding, make
sure that the right host is pointed to.
4 changes: 2 additions & 2 deletions projects/ant-gateway/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
data/certbot/*
!data/certbot/.gitkeep
secrets/*
!secrets/.gitkeep
18 changes: 16 additions & 2 deletions projects/ant-gateway/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
FROM nginx
COPY ./data/nginx/app.conf /etc/nginx/nginx.conf
COPY ./index.html /etc/nginx/html/index.html

ARG SSL_KEY_PATH
ARG SSL_CERT_PATH
ARG FQDN
ARG ANT_WORKER_NUM=002
ARG WEBSERVER_PORT=3499

# Copy the templates nginx.conf into the container
COPY ./data/nginx.conf.mo /tmp/ant-on-the-web/nginx.conf.mo
RUN curl -sSL https://raw.githubusercontent.com/tests-always-included/mo/master/mo -o mo
RUN chmod +x ./mo
RUN ./mo /tmp/ant-on-the-web/nginx.conf.mo > /etc/nginx/nginx.conf

# Copy the public and private keys into the container
COPY "$SSL_CERT_PATH" "/ant-on-the-web/${FQDN}/cert.pem"
COPY "$SSL_KEY_PATH" "/ant-on-the-web/${FQDN}/key.pem"
28 changes: 28 additions & 0 deletions projects/ant-gateway/data/beta.typesofants.org/cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN CERTIFICATE-----
MIIEnDCCA4SgAwIBAgIUHGJFDqopEjM0lAvBMuabWUhn3wMwDQYJKoZIhvcNAQEL
BQAwgYsxCzAJBgNVBAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMTQw
MgYDVQQLEytDbG91ZEZsYXJlIE9yaWdpbiBTU0wgQ2VydGlmaWNhdGUgQXV0aG9y
aXR5MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlh
MB4XDTI0MDUwNTE3MTcwMFoXDTM5MDUwMjE3MTcwMFowYjEZMBcGA1UEChMQQ2xv
dWRGbGFyZSwgSW5jLjEdMBsGA1UECxMUQ2xvdWRGbGFyZSBPcmlnaW4gQ0ExJjAk
BgNVBAMTHUNsb3VkRmxhcmUgT3JpZ2luIENlcnRpZmljYXRlMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt2URedumhEtmIdVozv40n6LvtnJ5xJGM4ADd
eGa8zfKGpe41F9RmQmi3nl6+CSbeBlwQh25ZrpYq4DtFPE+MKmDaac1a8EEdGyJF
jeWtkE38RbKRS/ekcHtN+FrU3dgRSuEAwS7SX/s5bKz8Y9UiXozX0A3X0S/xxTOV
wJwkg/SaG1K9+eaZkqzS0sp3JpwMM0U558MDGv2QqerG2Am487xDG7C6hlp9vdFG
P0JBfy3ec9EIm033J9v8gl7xhsO6uF1y3Ql0mQyovTBZPIgmXQ/63rORK0uZR1OT
QE9/Ip+KCKc7IZA2/HCuh/8dOdrN+Fkg8ykec88YcnCp7zGBCwIDAQABo4IBHjCC
ARowDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
ATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQbOQ2DNs9brQMR+HOBT8QdPmEtmTAf
BgNVHSMEGDAWgBQk6FNXXXw0QIep65TbuuEWePwppDBABggrBgEFBQcBAQQ0MDIw
MAYIKwYBBQUHMAGGJGh0dHA6Ly9vY3NwLmNsb3VkZmxhcmUuY29tL29yaWdpbl9j
YTAfBgNVHREEGDAWghRiZXRhLnR5cGVzb2ZhbnRzLm9yZzA4BgNVHR8EMTAvMC2g
K6AphidodHRwOi8vY3JsLmNsb3VkZmxhcmUuY29tL29yaWdpbl9jYS5jcmwwDQYJ
KoZIhvcNAQELBQADggEBAL+JfVcOFCiTSioBuJBbx6NZDfuttOoT20Wdq4ycXoU9
SNMn8STMzHnr/HhllUIHr+Cvzgsyccgoj8qCcK4N4hcyIx718O/cyDeRema137N3
GpbV/HrSOdvoIqJ7c63ahiKF/83M1BKmkTOA1WWgUD8gmtYibp22pmbCT/8C9gVz
rdrqcL1hphMdoD2KXX3+jMu3gy2eGB3bTw4KoHqD1GmRJViBsuV1Pr5ZG+or7z97
j8hZeXF/tKc7kdBGBOANYc19Vobg8eQNu0LGhAere4uMcZBOgQ6v4QF/h8gNig7O
F7Thjx4FpKCQmQNrXNZcq0ypwhe7DZiY3VP8FpYNorI=
-----END CERTIFICATE-----

41 changes: 41 additions & 0 deletions projects/ant-gateway/data/nginx.conf.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
events {

}

http {
server {
listen 80;
server_name {{FQDN}};
return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{FQDN}};

location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;

proxy_redirect off;
proxy_pass https://antworker{{ANT_WORKER_NUM}}.hosts.typesofants.org:{{WEBSERVER_PORT}};
}

ssl_certificate /ant-on-the-web/{{FQDN}}/cert.pem;
ssl_certificate_key /ant-on-the-web/{{FQDN}}/key.pem;

# SSL configuration
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;

ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
}
}
Loading

0 comments on commit 5f6c76c

Please sign in to comment.