Compare commits

...

18 Commits

Author SHA1 Message Date
a05fcb8ade docs: some more updates 2025-07-11 10:28:52 +02:00
6313bc5ec7 docs: add section on dev services 2025-07-11 10:26:51 +02:00
21abbe97ed chore: remove services from repo 2025-07-11 09:56:02 +02:00
6582a72b43 chore: upgrade traefik 2025-06-11 10:15:49 +02:00
86085039ff feat: update readme add example 2025-05-13 11:51:10 +02:00
beb4088c51 feat: update readme 2025-05-13 11:22:45 +02:00
9f40e247b9 feat: update readme 2025-05-13 11:22:15 +02:00
a46b00bd07 feat: update readme 2025-05-13 11:19:49 +02:00
90587ed5d1 feat: update readme 2025-05-13 11:18:39 +02:00
3f6b504dfc feat: update readme 2025-05-13 11:18:15 +02:00
0db871b63f feat: update readme 2025-05-13 11:16:00 +02:00
55eb86ff0c feat: update readme 2025-05-13 11:09:35 +02:00
ed099f6f1a Update README.md 2025-05-12 19:07:41 +02:00
30e207a87c feat: add some links to README.md 2025-05-12 15:15:22 +02:00
7b881e5da1 Update README.md 2025-05-12 14:51:42 +02:00
69b2ddf40b fix: remove unecessary comma 2025-05-12 14:45:37 +02:00
f13cdaff60 feat: add custom domain per service section to readme 2025-05-12 14:45:27 +02:00
4915eac171 fix: spelling 2025-05-12 14:30:29 +02:00
9 changed files with 63 additions and 125 deletions

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@
/config/traefik/dynamic/*
!/config/traefik/dynamic/ssl.yaml
!/config/traefik/dynamic/dashboard.yaml
services/

View File

@@ -2,7 +2,7 @@
<img src="https://git.max-richter.dev/attachments/3cea8ffa-57cc-4faf-a973-7a3b34a012e0" width="30%"/>
<h2 align="center">LocalCerts</h2>
<p align="center">
Automatic HTTPS and local domain routing for Docker Compose services using Traefik and Step-CA.
Automatic HTTPS and local domain routing for Docker Compose services using <a href="https://github.com/traefik/traefik">Traefik</a>, <a href="https://github.com/mageddo/dns-proxy-server">DPS</a> and <a href="https://github.com/smallstep/certificates">Step-CA</a>.
</p>
<p align="center">
Created by <a href="https://github.com/Sajito">@Sajito</a>
@@ -15,15 +15,28 @@
1. Clone this repository and navigate into the directory.
2. Start the services:
```bash
```shell
docker compose up -d
```
3. Trust the Step-CA root certificate:
```bash
curl -k https://localhost:9000/roots.pem -o roots.pem
Download the `roots.pem` from [https://localhost:9000/roots.pem](https://localhost:9000/roots.pem) and trust it on your system.
This is necessary for the certificates to be trusted by your browser.
- Linux
```shell
sudo trust anchor --store roots.pem
rm roots.pem
```
- Windows
```powershell
Import-Certificate -FilePath "roots.pem" -CertStoreLocation "Cert:\LocalMachine\Root"
```
- macOS
```shell
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain roots.pem
```
## How to Use
@@ -49,7 +62,7 @@ labels:
> For each overwritten port you need to specify a custom `service-label` `traefik.http.services.[service-label]`. Otherwise the custom port will not be detected.
- If certificates are not renewed or have expired
```bash
```shell
docker compose up -d --force-recreate traefik
```
@@ -60,62 +73,67 @@ docker compose up -d --force-recreate traefik
For example `dev.cool` 😎
Replace `.dev.local` with your custom domain suffix in the `config/traefik/traefik.yml` file:
```yaml
...
```diff
docker:
defaultRule: |
Host(`{{ trim (index .Labels "serviceName") }}.dev.cool`) {{range $i, $domain := splitList "," (index .Labels "serviceDomains")}}{{if ne $domain ""}}|| Host(`{{$domain}}`){{end}}{{end}}
...
- Host(`{{ trim (index .Labels "serviceName") }}.dev.local`) {{range $i, $domain := splitList "," (index .Labels "serviceDomains")}}{{if ne $domain ""}}|| Host(`{{$domain}}`){{end}}{{end}}
+ Host(`{{ trim (index .Labels "serviceName") }}.dev.cool`) {{range $i, $domain := splitList "," (index .Labels "serviceDomains")}}{{if ne $domain ""}}|| Host(`{{$domain}}`){{end}}{{end}}
constraints: LabelRegex(`serviceName`, `.+`) && !Label(`com.docker.compose.oneoff`, `True`)
```
Replace `.dev.local` with your custom domain suffix in the `config/dns/config.sample.json` file:
```json
...
{
```diff
{
"id": 2,
"hostname": ".dev.cool",
- "hostname": ".dev.local",
+ "hostname": ".dev.cool",
"ip": "",
"target": "host.docker",
"ttl": 3600,
"type": "CNAME"
}
...
```
Remove the dns_config volume
```bash
docker compose down
docker compose volukme rm dns_config
docker compose up -d
Restart the docker services to apply the changes:
```shell
docker compose up -d --force-recreate
```
### Custom Domain Per Service
If you want a single service to have a custom domain you can use the `serviceDomains` label. This will override the default domain suffix:
```yaml
labels:
serviceName: my-app
serviceDomains: my-app.very.cool
```
The service would now be reachable at `https://my-app.very.cool` and `https://my-app.dev.local`.
### Certificate Lifetime
To ensure Traefik has enough time to renew certificates, increase their duration:
```bash
```shell
docker compose exec step step ca provisioner update acme \
--x509-min-dur=20m \
--x509-max-dur=8760h \
--x509-default-dur=2160h
```
### Use the preconfigured services
### Create a shell script to start/stop general services
If you use the preconfigured services, you can add the following snippet to you `.bashrc/.zshrc` to easily start, stop, and manage the services.
I often use tools like dbgate to interact with databases. For such utilities, I maintain a services/compose.yml file in this directory, where each service is defined with a custom profile. This setup allows me to start and stop individual services as needed.
```bash
If you use the preconfigured services, you can add the following snippet to you `.bashrc`/`.zshrc` to easily start, stop, and manage the services. Make sure to update the `PROJECT_DIR` variable to point to the correct directory.
```shell
dev () {
PROJECT_DIR="$HOME/Projects/dev/services"
case "$1" in
(start) shift
docker compose -f "$PROJECT_DIR/docker-compose.yml" --profile "$@" up -d ;;
docker compose -f "$PROJECT_DIR/compose.yml" --profile "$@" up -d ;;
(restart) shift
docker compose -f "$PROJECT_DIR/docker-compose.yml" --profile "$@" restart ;;
docker compose -f "$PROJECT_DIR/compose.yml" --profile "$@" restart ;;
(stop) shift
docker compose -f "$PROJECT_DIR/docker-compose.yml" --profile "$@" down --remove-orphans ;;
docker compose -f "$PROJECT_DIR/compose.yml" --profile "$@" down --remove-orphans ;;
(logs) shift
docker compose -f "$PROJECT_DIR/docker-compose.yml" --profile "$@" logs -f ;;
docker compose -f "$PROJECT_DIR/compose.yml" --profile "$@" logs -f ;;
(*) echo "Usage: dev {start|restart|stop|logs} [services...]" ;;
esac
}

View File

@@ -0,0 +1,6 @@
services:
dns:
volumes:
- /etc:/host/etc
environment:
MG_RESOLVCONF: /host/etc/resolv.conf

View File

@@ -19,7 +19,7 @@ services:
ipv4_address: 172.157.5.249
traefik:
image: traefik:3.3
image: traefik:3.4.1
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock

View File

@@ -38,4 +38,4 @@
]
}
]
},
}

0
services/.gitignore vendored
View File

View File

@@ -1,67 +0,0 @@
services:
mailpit:
profiles:
- mail
image: axllent/mailpit
ports:
- 1025:1025
environment:
MP_UI_BIND_ADDR: "0.0.0.0:8085"
labels:
serviceName: mail
traefik.http.services.mail.loadbalancer.server.port: 8085
datasette:
ports:
- 8001:8001
volumes:
- datasette:/mnt
image: datasetteproject/datasette
command: datasette -p 8001 -h 0.0.0.0 --plugins-dir=/mnt/plugins/ --config default_page_size:500 /mnt/data/qs-monitor-usage.db
profiles:
- data
labels:
serviceName: data
traefik.http.services.data.loadbalancer.server.port: 8001
silverbullet:
profiles:
- notes
image: ghcr.io/silverbulletmd/silverbullet:v2
volumes:
- ~/Notes:/space
labels:
serviceName: notes
db:
profiles:
- db
build: docker
image: dbgate/dbgate:beta-alpine
labels:
serviceName: db
volumes:
- dbgate:/root/.dbgate
grafana:
profiles:
- logs
image: grafana/grafana:11.2.0
environment:
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_BASIC_ENABLED=false
- GF_FEATURE_TOGGLES_ENABLE=accessControlOnCall lokiLogsDataplane exploreLogsShardSplitting
- GF_PLUGINS_PREINSTALL_DISABLED=true
- GF_INSTALL_PLUGINS=https://storage.googleapis.com/integration-artifacts/grafana-lokiexplore-app/grafana-lokiexplore-app-latest.zip;grafana-lokiexplore-app
labels:
serviceName: grafana
volumes:
- ./provisioning/grafana:/etc/grafana/provisioning
extra_hosts:
- 'host.docker.internal:host-gateway'
volumes:
dbgate: ~
datasette: ~

View File

@@ -1,8 +0,0 @@
apiVersion: 1
datasources:
- name: gdev-loki
type: loki
uid: gdev-loki
access: proxy
url: http://host.docker.internal:3100

View File

@@ -1,12 +0,0 @@
apiVersion: 1
apps:
- type: "grafana-lokiexplore-app"
org_id: 1
org_name: "Grafana"
disabled: false
jsonData:
apiUrl: http://default-url.com
isApiKeySet: true
secureJsonData:
apiKey: secret-key