Compare commits
55
Commits
9d62ba5279
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ee5a2cfb0 | ||
|
|
f6cfb706da | ||
|
|
7d4f8ca9c5 | ||
|
|
3b661a698e | ||
|
|
132cc91d06 | ||
|
|
0fbe068197 | ||
|
|
2ebf7ca958 | ||
|
|
08c4c78c8e | ||
|
|
9ce6a93b99 | ||
|
|
a20dc43559 | ||
|
|
d56192ce0d | ||
|
|
28ff6a9fdc | ||
|
|
2ea01a8824 | ||
|
|
fe775a5a7e | ||
|
|
33eb9d7748 | ||
|
|
81486654de | ||
|
|
7228c8c131 | ||
|
|
977cfb2197 | ||
|
|
0e98866699 | ||
|
|
596aa4c3f2 | ||
|
|
e5f765dba1 | ||
|
|
6a9e5a5b68 | ||
|
|
d04b908996 | ||
|
|
80b92acd7a | ||
|
|
2cdda03224 | ||
|
|
840fd46a73 | ||
|
|
b7e130a24e | ||
|
|
3b2d0335bd | ||
|
|
29f0490924 | ||
|
|
e447f6d775 | ||
|
|
001f2cd741 | ||
|
|
a8521ad139 | ||
|
|
3a0ee27b6f | ||
|
|
3c9eac23b4 | ||
|
|
bba89d706a | ||
|
|
1098ba0c38 | ||
|
|
60a9109389 | ||
|
|
8d3d9518fa | ||
|
|
321d3303a4 | ||
|
|
d9eb55708c | ||
|
|
67c0ee9cba | ||
|
|
74945b5618 | ||
|
|
dd83e47654 | ||
|
|
4527246427 | ||
|
|
0992e183aa | ||
|
|
154b9f2ebd | ||
|
|
ebe9063687 | ||
|
|
24987e25b4 | ||
|
|
e302605d47 | ||
|
|
22178fa47a | ||
|
|
d2a5bb90da | ||
|
|
abc2dabd34 | ||
|
|
f929547a91 | ||
|
|
ae3f68b96a | ||
|
|
2231626fb6 |
+4
-4
@@ -1,16 +1,16 @@
|
|||||||
# stalwart
|
# stalwart
|
||||||
STALWART_PUBLIC_URL=https://m.example.org
|
STALWART_PUBLIC_URL=https://post.example.org
|
||||||
OIDC_KEY=GENERATE_STRING # openssl rand -hex 32
|
OIDC_KEY=GENERATE_STRING # openssl rand -hex 32
|
||||||
OIDC_SIGNATURE_KEY=GENERATE_PEM # openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:secp384r1 -pkeyopt ec_param_enc:named_curve
|
OIDC_SIGNATURE_KEY=GENERATE_PEM # openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:secp384r1 -pkeyopt ec_param_enc:named_curve # ONE LINE, IN QUOTES, SEPARATED BY \n
|
||||||
|
|
||||||
# bulwark
|
# bulwark
|
||||||
JMAP_SERVER_URL=https://m.example.org
|
JMAP_SERVER_URL=https://post.example.org
|
||||||
SESSION_SECRET=GENERATE_STRING # openssl rand -hex 32
|
SESSION_SECRET=GENERATE_STRING # openssl rand -hex 32
|
||||||
SETTINGS_SYNC_ENABLED=true
|
SETTINGS_SYNC_ENABLED=true
|
||||||
ADMIN_PASSWORD=GENERATE_PASSWORD # tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 20; echo
|
ADMIN_PASSWORD=GENERATE_PASSWORD # tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 20; echo
|
||||||
|
|
||||||
# vykar
|
# vykar
|
||||||
VYKAR_LABEL=borgbase
|
VYKAR_LABEL=borgbase
|
||||||
VYKAR_URL=https://myrepo.repo.borgbase.com
|
VYKAR_URL=https://REPO.repo.borgbase.com
|
||||||
VYKAR_ACCESS_TOKEN=ACCESS_TOKEN
|
VYKAR_ACCESS_TOKEN=ACCESS_TOKEN
|
||||||
VYKAR_ENCRYPTION_SECRET=GENERATE_STRING # openssl rand -hex 32
|
VYKAR_ENCRYPTION_SECRET=GENERATE_STRING # openssl rand -hex 32
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
.env
|
*.env
|
||||||
|
|||||||
@@ -3,14 +3,35 @@
|
|||||||
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
|
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
# }
|
# }
|
||||||
|
|
||||||
mail.yaoi.dog {
|
atom.town {
|
||||||
|
root * /srv/home
|
||||||
|
encode zstd
|
||||||
|
|
||||||
|
# /index.html -> /
|
||||||
|
@indexhtml path_regexp idx ^(.*/)index\.html$
|
||||||
|
redir @indexhtml {re.idx.1} permanent
|
||||||
|
|
||||||
|
# /something.html -> /something
|
||||||
|
@html path_regexp strip ^(.+)\.html$
|
||||||
|
redir @html {re.strip.1} permanent
|
||||||
|
|
||||||
|
# something -> something.html
|
||||||
|
try_files {path} {path}.html {path}/index.html
|
||||||
|
|
||||||
|
file_server
|
||||||
|
|
||||||
|
@assets path /assets/*
|
||||||
|
header @assets Cache-Control "public, max-age=604800, immutable"
|
||||||
|
}
|
||||||
|
|
||||||
|
post.atom.town {
|
||||||
reverse_proxy stalwart:8080
|
reverse_proxy stalwart:8080
|
||||||
}
|
}
|
||||||
|
|
||||||
post.yaoi.dog {
|
mail.atom.town {
|
||||||
reverse_proxy bulwark:3000
|
reverse_proxy bulwark:3000
|
||||||
}
|
}
|
||||||
|
|
||||||
git.yaoi.dog {
|
git.atom.town {
|
||||||
reverse_proxy forgejo:3000
|
reverse_proxy gitea:3000
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,146 +1,14 @@
|
|||||||
# thingy!
|
# atom.town
|
||||||
|
|
||||||
some kind of hosting setup
|
here, you will be at home.
|
||||||
|
|
||||||
## setup
|
## directory
|
||||||
|
|
||||||
1. log into the vps, make sure it's fedora (or else 🔪)
|
- [setup](docs/setup.md)
|
||||||
2. create a new admin user
|
- [caddy](docs/services/caddy.md)
|
||||||
- `sudo useradd -m -G wheel admin`
|
- [stalwart](docs/services/stalwart.md)
|
||||||
- `sudo passwd admin`
|
- [bulwark](docs/services/bulwark.md)
|
||||||
- `sudo su - admin`
|
- [gitea](docs/services/gitea.md)
|
||||||
3. use the system setup script, and log out
|
- [backups](docs/backups.md)
|
||||||
- `sudo dnf install git -y`
|
- [misc](docs/misc.md)
|
||||||
- `git clone https://gitlab.com/futile/thingy`
|
- [todo](docs/todo.md)
|
||||||
- `./thingy/scripts/system-setup.sh`
|
|
||||||
- `exit`
|
|
||||||
4. log in again, populate the `.env` and start everything up
|
|
||||||
- `cd thingy`
|
|
||||||
- `micro .env`
|
|
||||||
- `docker compose up`
|
|
||||||
5. continue with service-specific setups .....
|
|
||||||
|
|
||||||
## services
|
|
||||||
|
|
||||||
specifics for everything
|
|
||||||
|
|
||||||
**currently serving**
|
|
||||||
|
|
||||||
- via docker
|
|
||||||
- **caddy** – http server & reverse proxy
|
|
||||||
- **stalwart** – mailserver
|
|
||||||
- **bulwark** – webmail
|
|
||||||
- via caddy
|
|
||||||
- `mail.yaoi.dog` – mail (server & admin dash)
|
|
||||||
- `post.yaoi.dog` – mail (webmail)
|
|
||||||
|
|
||||||
**dns setup**
|
|
||||||
|
|
||||||
| type | host | value | notes |
|
|
||||||
|-------|-----------|---------------------------- |----------------------------|
|
|
||||||
| `A` | `@` | `<ip>` | apex domain |
|
|
||||||
| `A` | `mail` | `<ip>` | mailserver |
|
|
||||||
| `A` | `post` | `<ip>` | webmail |
|
|
||||||
| `A` | `git` | `<ip>` | forgejo |
|
|
||||||
| `CAA` | `@` | `0 issue "letsencrypt.org"` | allow caddy to issue certs |
|
|
||||||
|
|
||||||
### caddy
|
|
||||||
|
|
||||||
todo
|
|
||||||
|
|
||||||
### stalwart
|
|
||||||
|
|
||||||
**first setup**
|
|
||||||
|
|
||||||
1. server identity
|
|
||||||
- server hostname: `mail.yaoi.dog`
|
|
||||||
- default email domain: `yaoi.dog`
|
|
||||||
- automatically obtain tls certificate: `true`
|
|
||||||
- generate email signing keys: `true`
|
|
||||||
2. storage
|
|
||||||
- main data storage: `rocksdb`
|
|
||||||
- path: `/var/lib/stalwart/`
|
|
||||||
3. account directory
|
|
||||||
- directory type: `use internal`
|
|
||||||
4. logging
|
|
||||||
- log destination: `console`
|
|
||||||
5. automatic dns management
|
|
||||||
- dns server type: `porkbun`
|
|
||||||
- description: `porkbun`
|
|
||||||
|
|
||||||
**further setup**
|
|
||||||
|
|
||||||
- settings -> security -> allowed ips
|
|
||||||
- added `172.18.0.0/24`; reason: `internal`
|
|
||||||
- settings -> network -> http -> security
|
|
||||||
- permissive cors policy: `true` **[restart needed]**
|
|
||||||
- settings -> authentication -> oidc provider
|
|
||||||
- oauth settings
|
|
||||||
- key: `secret read from environment variable`
|
|
||||||
- variable name: `OIDC_KEY`
|
|
||||||
- openid connect
|
|
||||||
- signature algorithm: `ECDSA using P-384 and SHA-384`
|
|
||||||
- signature key: `secret read from environment variable`
|
|
||||||
- variable name: `OIDC_SIGNATURE_KEY`
|
|
||||||
|
|
||||||
**useful links**
|
|
||||||
|
|
||||||
- https://stalw.art/docs
|
|
||||||
- https://testconnectivity.microsoft.com/tests/Imap/input
|
|
||||||
- https://mail-tester.com
|
|
||||||
|
|
||||||
### bulwark
|
|
||||||
|
|
||||||
todo
|
|
||||||
|
|
||||||
**useful links**
|
|
||||||
|
|
||||||
- https://bulwarkmail.org/docs
|
|
||||||
|
|
||||||
### forgejo
|
|
||||||
|
|
||||||
todo
|
|
||||||
|
|
||||||
## backups
|
|
||||||
|
|
||||||
backups are done with [vykar](https://vykar.borgbase.com) to [borgbase](https://borgbase.com)
|
|
||||||
|
|
||||||
always remember to `docker compose stop` before doing any of this!
|
|
||||||
|
|
||||||
**creating**
|
|
||||||
|
|
||||||
- if on a new borgbase repo, run `vykar init` first
|
|
||||||
- to back up, run `sudo vykar backup` (sudo required as we are accessing `/var/lib/docker/volumes/`)
|
|
||||||
- to back up automatically, run `sudo EDITOR=micro crontab -e` and add the following:
|
|
||||||
```
|
|
||||||
TZ=UTC
|
|
||||||
0 * * * * /home/admin/thingy/scripts/volume-backup.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
**restoring**
|
|
||||||
|
|
||||||
the restore process is kind of fucked up but doable
|
|
||||||
|
|
||||||
- restore on new system
|
|
||||||
- run `vykar list` to find a snapshot to use
|
|
||||||
- `sudo rm -rf /var/lib/docker/volumes/`
|
|
||||||
- then `sudo vykar restore abcd1234 /var/lib/docker/volumes/`
|
|
||||||
- figure out the UID:GID for all containers and `sudo chown -R UID:GID /var/lib/docker/volumes/.../_data/` their respective volumes
|
|
||||||
- restore on same system
|
|
||||||
- run `vykar list` to find a snapshot to use
|
|
||||||
- then `sudo vykar restore abcd1234 /var/lib/docker/volumes/`
|
|
||||||
|
|
||||||
## todo
|
|
||||||
|
|
||||||
- further secure the server (ratelimiting, hardening...)
|
|
||||||
- more services
|
|
||||||
- ~~forgejo (need to change host ssh port)~~
|
|
||||||
- vaultwarden
|
|
||||||
- ~~tie all services together with an sso~~
|
|
||||||
- use postgres for everything
|
|
||||||
|
|
||||||
## misc
|
|
||||||
|
|
||||||
**useful commands**
|
|
||||||
|
|
||||||
- `docker exec <service> env`
|
|
||||||
|
|||||||
+6
-5
@@ -9,6 +9,7 @@ services:
|
|||||||
- "443:443/udp"
|
- "443:443/udp"
|
||||||
volumes:
|
volumes:
|
||||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro,z
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro,z
|
||||||
|
- ./home:/srv/home/
|
||||||
- caddy-data:/data
|
- caddy-data:/data
|
||||||
- caddy-config:/config
|
- caddy-config:/config
|
||||||
networks:
|
networks:
|
||||||
@@ -54,9 +55,9 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- stalwart
|
- stalwart
|
||||||
|
|
||||||
forgejo:
|
gitea:
|
||||||
image: codeberg.org/forgejo/forgejo:16
|
image: docker.gitea.com/gitea:1.27.0
|
||||||
container_name: forgejo
|
container_name: gitea
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- USER_UID=1000
|
- USER_UID=1000
|
||||||
@@ -64,7 +65,7 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "22:22"
|
- "22:22"
|
||||||
volumes:
|
volumes:
|
||||||
- forgejo-data:/data
|
- gitea-data:/data
|
||||||
networks:
|
networks:
|
||||||
- services
|
- services
|
||||||
|
|
||||||
@@ -77,7 +78,7 @@ volumes:
|
|||||||
bulwark-config:
|
bulwark-config:
|
||||||
bulwark-state:
|
bulwark-state:
|
||||||
bulwark-telemetry:
|
bulwark-telemetry:
|
||||||
forgejo-data:
|
gitea-data:
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
services:
|
services:
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
## backups
|
||||||
|
|
||||||
|
backups are done with [vykar](https://vykar.borgbase.com) to [borgbase](https://borgbase.com)
|
||||||
|
|
||||||
|
always remember to `docker compose stop` before doing any of this!
|
||||||
|
|
||||||
|
**creating**
|
||||||
|
|
||||||
|
- if on a new borgbase repo, run `vykar init` first
|
||||||
|
- to back up, run `sudo vykar backup` (sudo required as we are accessing `/var/lib/docker/volumes/`)
|
||||||
|
- to back up automatically, run `sudo EDITOR=micro crontab -e` and add the following:
|
||||||
|
```
|
||||||
|
TZ=UTC
|
||||||
|
0 6 * * * /home/admin/atom.town/scripts/volume-backup.sh cold
|
||||||
|
0 0,12,18 * * * /home/admin/atom.town/scripts/volume-backup.sh hot
|
||||||
|
```
|
||||||
|
|
||||||
|
**restoring**
|
||||||
|
|
||||||
|
the restore process is kind of fucked up but doable
|
||||||
|
|
||||||
|
- restore on new system
|
||||||
|
- run `vykar list` to find a snapshot to use
|
||||||
|
- `sudo rm -rf /var/lib/docker/volumes/`
|
||||||
|
- then `sudo vykar restore abcd1234 /var/lib/docker/volumes/`
|
||||||
|
- figure out the UID:GID for all containers and `sudo chown -R UID:GID /var/lib/docker/volumes/.../_data/` their respective volumes
|
||||||
|
- restore on same system
|
||||||
|
- run `vykar list` to find a snapshot to use
|
||||||
|
- then `sudo vykar restore abcd1234 /var/lib/docker/volumes/`
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
## misc
|
||||||
|
|
||||||
|
**useful commands**
|
||||||
|
|
||||||
|
- `docker exec <service> env`
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
### bulwark
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> **todo** // detail setup
|
||||||
|
|
||||||
|
**useful links**
|
||||||
|
|
||||||
|
- https://bulwarkmail.org/docs
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
### caddy
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> **todo** // detail setup
|
||||||
|
|
||||||
|
**useful links**
|
||||||
|
|
||||||
|
- https://caddyserver.com/docs/
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
### gitea
|
||||||
|
|
||||||
|
**initial setup**
|
||||||
|
|
||||||
|
- database settings
|
||||||
|
- database type: `sqlite3`
|
||||||
|
- path: `/data/gitea/gitea.db`
|
||||||
|
- general settings
|
||||||
|
- site title: `atom.town`
|
||||||
|
- server domain: `git.atom.town`
|
||||||
|
- ssh server port: `22`
|
||||||
|
- gitea base url: `https://git.atom.town/`
|
||||||
|
- enable update checker: `true`
|
||||||
|
- email settings
|
||||||
|
- smtp host: `post.atom.town`
|
||||||
|
- smtp port: `465`
|
||||||
|
- send email as: `"Gitea" <system@atom.town>`
|
||||||
|
- smtp username: `system@atom.town`
|
||||||
|
- smtp password: `<password>`
|
||||||
|
- enable email notifications: `true`
|
||||||
|
- server and third-party service settings
|
||||||
|
- enable openid sign-in: `false`
|
||||||
|
- disable self-registration: `false`
|
||||||
|
- allow registration only through external services: `true`
|
||||||
|
- enable openid self-registration: `true`
|
||||||
|
- hidden email domain: `git.atom.town`
|
||||||
|
- password hash algorithm: `argon2`
|
||||||
|
</details>
|
||||||
|
|
||||||
|
**further setup**
|
||||||
|
|
||||||
|
- admin settings -> identity & access -> authentication sources
|
||||||
|
- add authentication source
|
||||||
|
- authentication type: `OAuth2`
|
||||||
|
- authentication name: `Stalwart`
|
||||||
|
- oauth2 provider: `OpenID Connect`
|
||||||
|
- client id (key): `gitea`
|
||||||
|
- client secret: `<secret_from_stalwart>`
|
||||||
|
- openid connect auto discovery url: `https://post.atom.town/.well-known/openid-configuration`
|
||||||
|
|
||||||
|
**useful links**
|
||||||
|
|
||||||
|
- https://docs.gitea.com/
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
### stalwart
|
||||||
|
|
||||||
|
**initial setup**
|
||||||
|
|
||||||
|
1. server identity
|
||||||
|
- server hostname: `post.atom.town`
|
||||||
|
- default email domain: `atom.town`
|
||||||
|
- automatically obtain tls certificate: `true`
|
||||||
|
- generate email signing keys: `true`
|
||||||
|
2. storage
|
||||||
|
- main data storage: `rocksdb`
|
||||||
|
- path: `/var/lib/stalwart/`
|
||||||
|
3. account directory
|
||||||
|
- directory type: `use internal`
|
||||||
|
4. logging
|
||||||
|
- log destination: `console`
|
||||||
|
5. automatic dns management
|
||||||
|
- dns server type: `porkbun`
|
||||||
|
- description: `porkbun`
|
||||||
|
|
||||||
|
**further setup**
|
||||||
|
|
||||||
|
- settings -> security -> allowed ips
|
||||||
|
- added `172.18.0.0/16`; reason: `docker internal`
|
||||||
|
- settings -> network -> http -> security
|
||||||
|
- permissive cors policy: `true` **[restart needed]**
|
||||||
|
- settings -> authentication -> oidc provider
|
||||||
|
- oauth settings
|
||||||
|
- key: `secret read from environment variable`
|
||||||
|
- variable name: `OIDC_KEY`
|
||||||
|
- openid connect
|
||||||
|
- signature algorithm: `ECDSA using P-384 and SHA-384`
|
||||||
|
- signature key: `secret read from environment variable`
|
||||||
|
- variable name: `OIDC_SIGNATURE_KEY`
|
||||||
|
- management -> directory -> oauth clients
|
||||||
|
- create oauth client
|
||||||
|
- client id: `gitea`
|
||||||
|
- description: `Gitea`
|
||||||
|
- client secret: `<generate_secret>`
|
||||||
|
- redirect uris: `https://git.atom.town/user/oauth2/Stalwart/callback`
|
||||||
|
|
||||||
|
**useful links**
|
||||||
|
|
||||||
|
- https://stalw.art/docs
|
||||||
|
- https://testconnectivity.microsoft.com/tests/Imap/input
|
||||||
|
- https://mail-tester.com
|
||||||
|
</details>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
## setup
|
||||||
|
|
||||||
|
1. log into the vps, make sure it's fedora (or else 🔪)
|
||||||
|
2. create a new admin user
|
||||||
|
- `sudo useradd -m -G wheel admin`
|
||||||
|
- `sudo passwd admin`
|
||||||
|
- `sudo su - admin`
|
||||||
|
3. use the system setup script, and log out
|
||||||
|
- `sudo dnf install git -y`
|
||||||
|
- `git clone https://git.atom.town/atom/town && mv town atom.town`
|
||||||
|
- `./atom.town/scripts/system-setup.sh`
|
||||||
|
- `exit`
|
||||||
|
4. log in again, populate the `.env` and start everything up
|
||||||
|
- `cd atom.town`
|
||||||
|
- `micro .env`
|
||||||
|
- `docker compose up`
|
||||||
|
5. continue with service-specific setups .....
|
||||||
|
|
||||||
|
## services
|
||||||
|
|
||||||
|
specifics for everything
|
||||||
|
|
||||||
|
**currently serving**
|
||||||
|
|
||||||
|
- via docker
|
||||||
|
- **caddy** – http server & reverse proxy
|
||||||
|
- **stalwart** – mailserver
|
||||||
|
- **bulwark** – webmail
|
||||||
|
- **gitea** – git server
|
||||||
|
- via caddy
|
||||||
|
- `atom.town` - homepage
|
||||||
|
- `post.atom.town` – mailserver, mail admin, and oidc
|
||||||
|
- `mail.atom.town` – webmail
|
||||||
|
- `git.atom.town` – git
|
||||||
|
|
||||||
|
**dns setup**
|
||||||
|
|
||||||
|
| type | host | value | notes |
|
||||||
|
|-------|-----------|---------------------------- |----------------------------|
|
||||||
|
| `A` | `@` | `<ip>` | apex domain |
|
||||||
|
| `A` | `post` | `<ip>` | mailserver |
|
||||||
|
| `A` | `mail` | `<ip>` | webmail |
|
||||||
|
| `A` | `git` | `<ip>` | gitea |
|
||||||
|
| `CAA` | `@` | `0 issue "letsencrypt.org"` | allow caddy to issue certs |
|
||||||
|
| `MX` | `@` | `post.atom.town.` / `10` | mail record |
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
## todo
|
||||||
|
|
||||||
|
- [ ] put branding on more stuff (images, themes...)
|
||||||
|
- [ ] further secure the server (ratelimiting, hardening...)
|
||||||
|
- [ ] (maybe) user sites or pages hosting
|
||||||
|
- [ ] (maybe) gitea actions runner
|
||||||
|
- [ ] more services
|
||||||
|
- [x] gitea (need to change host ssh port)
|
||||||
|
- [ ] vaultwarden
|
||||||
|
- [x] write terms of service & privacy policy
|
||||||
|
- [x] figure out best way to store .env, other credentials, and various secrets
|
||||||
|
- [x] tie all services together with an sso
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 166 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
@@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>atom.town</title>
|
||||||
|
<link rel="stylesheet" href="style/fonts.css">
|
||||||
|
<link rel="stylesheet" href="style/reset.css">
|
||||||
|
<link rel="stylesheet" href="style/style.css">
|
||||||
|
<link rel="icon" type="image/avif" href="assets/logo_icon.avif">
|
||||||
|
<link rel="preload" as="image" href="assets/clouds.avif">
|
||||||
|
<link rel="preload" as="font" href="assets/InterVariable-Italic.woff2" crossorigin>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<img src="assets/logo.avif" class="logo" />
|
||||||
|
<div class="flex flex-col gap-8 mt-4">
|
||||||
|
<p class="font-light">hello, and welcome to atom.town. here, you will be at home.</p>
|
||||||
|
<div class="flex flex-col w-fit">
|
||||||
|
<a href="https://mail.atom.town" target="_blank" class="font-normal pop big">webmail</a>
|
||||||
|
<a href="https://git.atom.town" target="_blank" class="font-normal pop big">git</a>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col w-fit">
|
||||||
|
<a href="terms-privacy.html" class="font-normal pop big">terms & privacy</a>
|
||||||
|
<a href="setup.html" class="font-normal pop big">setup</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>atom.town</title>
|
||||||
|
<link rel="stylesheet" href="style/fonts.css">
|
||||||
|
<link rel="stylesheet" href="style/reset.css">
|
||||||
|
<link rel="stylesheet" href="style/style.css">
|
||||||
|
<link rel="icon" type="image/avif" href="assets/logo_icon.avif">
|
||||||
|
<link rel="preload" as="image" href="assets/clouds.avif">
|
||||||
|
<link rel="preload" as="font" href="assets/InterVariable-Italic.woff2" crossorigin>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<img src="assets/logo.avif" class="logo" />
|
||||||
|
<div class="flex flex-col gap-8 mt-4 max-w-md">
|
||||||
|
<p class="font-light">things that are useful to know</p>
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<h2 class="font-heavy big">email</h2>
|
||||||
|
<ul class="font-light">
|
||||||
|
<li>the mailserver lives at <b>post.atom.town</b></li>
|
||||||
|
<li>incoming mail uses <b>imap</b> with <b>ssl/tls</b> on port <b>993</b></li>
|
||||||
|
<li>outgoing mail uses <b>smtp</b> with <b>ssl/tls</b> on port <b>465</b></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="font-light">
|
||||||
|
<li>the mailserver also has a few other functions. it is an admin dashboard, which anyone can use to configure their own email account, and also the oidc (auth) provider.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<a href="/index.html" class="self-start font-normal pop">← back</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/* http://rsms.me/inter/font-files/InterVariable.woff2 */
|
||||||
|
@font-face {
|
||||||
|
font-family: InterVariable;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url("../assets/InterVariable.woff2") format('woff2');
|
||||||
|
}
|
||||||
|
/* http://rsms.me/inter/font-files/InterVariable-Italic.woff2 */
|
||||||
|
@font-face {
|
||||||
|
font-family: InterVariable;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 100 900;
|
||||||
|
font-display: swap;
|
||||||
|
src: url("../assets/InterVariable-Italic.woff2") format('woff2');
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/* CSS reset (https://www.joshwcomeau.com/css/custom-css-reset) */
|
||||||
|
*, *::before, *::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
*:not(dialog) {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
html {
|
||||||
|
interpolate-size: allow-keywords;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
line-height: 1.5;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
img, picture, video, canvas, svg {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
input, button, textarea, select {
|
||||||
|
font: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
p, h1, h2, h3, h4, h5, h6 {
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
text-wrap: pretty;
|
||||||
|
}
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
text-wrap: balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root, #__next {
|
||||||
|
isolation: isolate;
|
||||||
|
}
|
||||||
|
/* CSS reset */
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
:root {
|
||||||
|
font-family: InterVariable, sans-serif;
|
||||||
|
font-feature-settings: 'liga' 1, 'calt' 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
background: url("../assets/clouds.avif"), linear-gradient(180deg, hwb(230 20% 0%) 0%, hwb(230 90% 0%) 110%);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover, cover;
|
||||||
|
background-attachment: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-height: 100dvh;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p, a, li, ul, h2 {
|
||||||
|
color: white;
|
||||||
|
font-style: italic;
|
||||||
|
font-size: 20px;
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: "» ";
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tailwind lite */
|
||||||
|
:root { --space: 4px; }
|
||||||
|
|
||||||
|
.flex { display: flex; }
|
||||||
|
.flex-col { flex-direction: column; }
|
||||||
|
|
||||||
|
.gap-2 { gap: calc(var(--space) * 2); }
|
||||||
|
.gap-4 { gap: calc(var(--space) * 4); }
|
||||||
|
.gap-8 { gap: calc(var(--space) * 8); }
|
||||||
|
|
||||||
|
.mt-4 { margin-top: calc(var(--space) * 4); }
|
||||||
|
|
||||||
|
.self-start { align-self: flex-start; }
|
||||||
|
|
||||||
|
.justify-between { justify-content: space-between; }
|
||||||
|
|
||||||
|
.w-fit { width: fit-content; }
|
||||||
|
|
||||||
|
.items-center { align-items: center; }
|
||||||
|
|
||||||
|
.font-extralight { font-weight: 200; }
|
||||||
|
.font-light { font-weight: 300; }
|
||||||
|
.font-normal { font-weight: 400; }
|
||||||
|
.font-heavy { font-weight: 500; }
|
||||||
|
|
||||||
|
.max-w-md {
|
||||||
|
max-width: calc(var(--space) * 180);
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
max-width: calc(var(--space) * 360);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* tailwind lite */
|
||||||
|
|
||||||
|
.small {
|
||||||
|
font-size: 16px;
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.big {
|
||||||
|
font-size: 24px;
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
font-size: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop {
|
||||||
|
transform-origin: left center;
|
||||||
|
transition: transform 0.1s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pop:hover {
|
||||||
|
transform: scale(1.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover {
|
||||||
|
text-decoration: underline dotted;
|
||||||
|
text-decoration-thickness: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
object-fit: contain;
|
||||||
|
align-self: flex-start;
|
||||||
|
max-height: 64px;
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
max-height: 128px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>atom.town</title>
|
||||||
|
<link rel="stylesheet" href="style/fonts.css">
|
||||||
|
<link rel="stylesheet" href="style/reset.css">
|
||||||
|
<link rel="stylesheet" href="style/style.css">
|
||||||
|
<link rel="icon" type="image/avif" href="assets/logo_icon.avif">
|
||||||
|
<link rel="preload" as="image" href="assets/clouds.avif">
|
||||||
|
<link rel="preload" as="font" href="assets/InterVariable-Italic.woff2" crossorigin>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<img src="assets/logo.avif" class="logo" />
|
||||||
|
<div class="flex flex-col gap-8 mt-4 max-w-md">
|
||||||
|
<p class="font-light">atom.town is an exclusive club of like-minded individuals. by using atom.town, you agree to everything stated on this page.</p>
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<h2 class="font-heavy big">terms</h2>
|
||||||
|
<ul class="font-light">
|
||||||
|
<li>you will not use atom.town in any way that would negatively impact other users, nor anyone else.</li>
|
||||||
|
<li>you will not use atom.town for bulk file storage (storing large files, or large volumes of files), even if such capabilities are present.</li>
|
||||||
|
<li>for any projects you host (or contribute to) on atom.town, llm usage will be <span title="while atom.town welcomes llms as a useful tool, they should be utilised sparingly, as it is all too easy to fall into the pit of overuse." class="hover">sparse</span>. largely unsupervised or unreviewed code is strongly prohibited.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<h2 class="font-heavy big">privacy</h2>
|
||||||
|
<ul class="font-light">
|
||||||
|
<li>atom.town is hosted on a <a href="https://datalix.eu/privacypolicy" target="_blank">datalix</a> server in germany. atom.town uses <a href="https://www.borgbase.com/privacy" target="_blank">borgbase</a> for backups (which are encrypted before upload).</li>
|
||||||
|
<li>atom.town (for now, indefinitely) collects ip addresses, account details, and any user data only for the purposes of system administration and provision of services.</li>
|
||||||
|
<li>atom.town does not share, nor ever will share any information it collects with any third parties, beyond what is absolutely necessary to run the service.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<a href="/index.html" class="self-start font-normal pop">← back</a>
|
||||||
|
<p class="font-extralight small">updated 2026-07-24 (<a href="https://git.atom.town/atom/town/commits/branch/main/home/terms-privacy.html" target="_blank" class="small">history</a>)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+9
-11
@@ -19,14 +19,12 @@ function banner() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# https://patorjk.com/software/taag/#p=display&f=Small+Slant
|
|
||||||
cat << 'EOF'
|
cat << 'EOF'
|
||||||
__ __ _
|
__ __
|
||||||
/ /_/ / (_)__ ___ ___ __
|
___ _/ /____ __ _ / /____ _ _____
|
||||||
/ __/ _ \/ / _ \/ _ `/ // /
|
/ _ `/ __/ _ \/ ' \_/ __/ _ \ |/|/ / _ \
|
||||||
\__/_//_/_/_//_/\_, /\_, /
|
\_,_/\__/\___/_/_/_(_)__/\___/__,__/_//_/
|
||||||
/___//___/
|
..... brought to you by futile
|
||||||
..... brought to you by futile
|
|
||||||
|
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
@@ -80,7 +78,7 @@ banner bottom "updated system"
|
|||||||
|
|
||||||
# install misc
|
# install misc
|
||||||
banner top "installing misc packages"
|
banner top "installing misc packages"
|
||||||
sudo dnf install -y micro btop fastfetch policycoreutils-python-utils
|
sudo dnf install -y micro btop gdu fastfetch policycoreutils-python-utils
|
||||||
curl -fsSL https://vykar.borgbase.com/install.sh | sh
|
curl -fsSL https://vykar.borgbase.com/install.sh | sh
|
||||||
banner bottom "installed misc packages"
|
banner bottom "installed misc packages"
|
||||||
|
|
||||||
@@ -111,14 +109,14 @@ banner bottom "installed cron"
|
|||||||
banner top "configuring sshd"
|
banner top "configuring sshd"
|
||||||
sudo tee /etc/ssh/sshd_config << 'EOF'
|
sudo tee /etc/ssh/sshd_config << 'EOF'
|
||||||
Include /etc/ssh/sshd_config.d/*.conf
|
Include /etc/ssh/sshd_config.d/*.conf
|
||||||
Port 67
|
Port 66
|
||||||
PermitRootLogin no
|
PermitRootLogin no
|
||||||
PasswordAuthentication no
|
PasswordAuthentication no
|
||||||
KbdInteractiveAuthentication no
|
KbdInteractiveAuthentication no
|
||||||
EOF
|
EOF
|
||||||
sudo semanage port -a -t ssh_port_t -p tcp 67
|
sudo semanage port -a -t ssh_port_t -p tcp 66
|
||||||
sudo systemctl restart sshd
|
sudo systemctl restart sshd
|
||||||
banner bottom "configuring sshd"
|
banner bottom "configuring sshd"
|
||||||
|
|
||||||
# finish
|
# finish
|
||||||
echo -e "done! please log out and log back in with \e[1;5mssh -p 67 $(id -un)@$(curl -s https://checkip.amazonaws.com)\e[0m\n"
|
echo -e "done! please log out and log back in with \e[1;5mssh -p 66 $(id -un)@$(curl -s https://checkip.amazonaws.com)\e[0m\n"
|
||||||
|
|||||||
@@ -1,26 +1,37 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
WORKING_DIR="/home/admin/thingy" # todo: better
|
WORKING_DIR="/home/admin/atom.town" # todo: better
|
||||||
LOG_FILE="/var/log/volume-backup.log"
|
LOG_FILE="/var/log/volume-backup.log"
|
||||||
|
|
||||||
function log() {
|
function log() {
|
||||||
echo "[$(date -Iseconds)] $*" | tee -a "$LOG_FILE"
|
echo "[$(date -Iseconds)] $*" | tee -a "$LOG_FILE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MODE="${1:-}"
|
||||||
|
if [[ "$MODE" != "cold" && "$MODE" != "hot" ]]; then
|
||||||
|
log "usage: $0 [cold|hot]" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
function cleanup() {
|
function cleanup() {
|
||||||
log "cleanup: starting docker services"
|
if [[ "$MODE" == "cold" ]]; then
|
||||||
docker compose start || true
|
log "starting docker services"
|
||||||
|
docker compose start || true
|
||||||
|
fi
|
||||||
log "└───── backup finished ─────┘"
|
log "└───── backup finished ─────┘"
|
||||||
}
|
}
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
|
|
||||||
log "┌────── backup started ─────┐"
|
log "┌────── backup started ─────┐"
|
||||||
|
log "mode: $MODE"
|
||||||
|
|
||||||
cd "$WORKING_DIR"
|
cd "$WORKING_DIR"
|
||||||
|
|
||||||
log "stopping docker services"
|
if [[ "$MODE" == "cold" ]]; then
|
||||||
docker compose stop
|
log "stopping docker services"
|
||||||
|
docker compose stop
|
||||||
|
fi
|
||||||
|
|
||||||
log "running backup"
|
log "running backup"
|
||||||
/usr/local/bin/vykar backup
|
/usr/local/bin/vykar backup 2>&1 | tee -a "$LOG_FILE"
|
||||||
|
|||||||
Reference in New Issue
Block a user