Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs'
import { groupIconVitePlugin } from 'vitepress-plugin-group-icons'
import tailwindcss from '@tailwindcss/vite'
import { loadEnv } from 'vitepress'
import traefikGrammar from './languages/traefik-labels.tmLanguage.json' with { type: 'json' }
const env = loadEnv('', process.cwd())
const sidebar = useSidebar({ spec })

Expand Down Expand Up @@ -650,6 +651,7 @@ export default defineConfig({
light: 'github-light',
dark: 'github-dark',
},
languages: [{ ...traefikGrammar, id: 'traefik', name: 'traefik' }],
// Configure Shiki with SSH language
async shikiSetup(shiki) {
await shiki.loadLanguage('ssh-config')
Expand Down
42 changes: 42 additions & 0 deletions docs/.vitepress/languages/traefik-labels.tmLanguage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "Traefik Labels",
"scopeName": "source.traefik-labels",
"fileTypes": [],
"patterns": [
{ "include": "#comment" },
{ "include": "#entry" }
],
"repository": {
"comment": {
"name": "comment.line.number-sign.traefik-labels",
"match": "#.*$"
},
"placeholder": {
"name": "variable.parameter.traefik-labels",
"match": "<[^>\n]+>"
},
"backtick-string": {
"name": "entity.name.function.traefik-labels",
"match": "`[^`\n]*`"
},
"entry": {
"begin": "^([^=\n]+)(=)",
"beginCaptures": {
"1": {
"patterns": [
{ "include": "#placeholder" },
{ "name": "keyword.other.definition.traefik-labels", "match": "[^<>\n]+" }
]
},
"2": { "name": "punctuation.separator.key-value.traefik-labels" }
},
"end": "$",
"patterns": [
{ "include": "#comment" },
{ "include": "#placeholder" },
{ "include": "#backtick-string" },
{ "name": "string.unquoted.traefik-labels", "match": "[^#<>`\n]+" }
]
}
}
}
6 changes: 0 additions & 6 deletions docs/.vitepress/theme/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@
background-color: var(--coollabs-bg-zinc-300-5) !important;
border: 0.5px solid rgba(0, 0, 0, 0.15) !important;
border-radius: 10px !important;
padding: 0 0 0 0.850rem !important;
margin: 0 !important;
line-height: 1.3 !important;
}

Expand All @@ -57,7 +55,6 @@
.vp-doc pre[class*='language-'] code {
font-weight: 700 !important;
line-height: 1.3 !important;
padding-left: 0 !important;
}

.dark .vp-doc div[class*='language-'],
Expand All @@ -66,8 +63,6 @@
background-color: var(--coollabs-bg-zinc-300-5) !important;
border: 0.5px solid rgba(255, 255, 255, 0.15) !important;
border-radius: 10px !important;
padding: 0 0 0 0.850rem !important;
margin: 0 !important;
line-height: 1.3 !important;
}

Expand All @@ -76,7 +71,6 @@
.dark .vp-doc pre[class*='language-'] code {
font-weight: 600 !important;
line-height: 1.5 !important;
padding-left: 0 !important;
}

/* Right-align copy button at the end of codeblocks */
Expand Down
90 changes: 39 additions & 51 deletions docs/knowledge-base/proxy/traefik/wildcard-certs.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ If you need fine-grained token, like with [Cloudflare](https://go-acme.github.io
1. Setup your wildcard subdomain DNS records, `*.coolify.io`.
2. Go to your Proxy settings (Servers / Proxy menu) and add the following configuration based on your [providers](https://doc.traefik.io/traefik/https/acme/#providers). The example will use `Hetzner` as a provider.

```bash
version: '3.8'
```yaml
name: coolify-proxy
networks:
coolify:
external: true
Expand All @@ -32,15 +32,16 @@ services:
container_name: coolify-proxy
image: 'traefik:v3.6'
restart: unless-stopped
environment:
- HETZNER_API_TOKEN=<API Key>
environment: # [!code focus]
- HETZNER_API_TOKEN=<API Key> # [!code focus]
extra_hosts:
- 'host.docker.internal:host-gateway'
networks:
- coolify
ports:
- '80:80'
- '443:443'
- '443:443/udp'
- '8080:8080'
healthcheck:
test: 'wget -qO- http://localhost:80/ping || exit 1'
Expand All @@ -49,7 +50,7 @@ services:
retries: 5
volumes:
- '/var/run/docker.sock:/var/run/docker.sock:ro'
- '/data/coolify/proxy:/traefik'
- '/data/coolify/proxy/:/traefik'
command:
- '--ping=true'
- '--ping.entrypoint=http'
Expand All @@ -58,28 +59,29 @@ services:
- '--entrypoints.http.address=:80'
- '--entrypoints.https.address=:443'
- '--entrypoints.http.http.encodequerysemicolons=true'
- '--entryPoints.http.http2.maxConcurrentStreams=250'
- '--entrypoints.https.http.encodequerysemicolons=true'
- '--entryPoints.https.http2.maxConcurrentStreams=250'
- '--entrypoints.https.http3'
- '--providers.docker.exposedbydefault=false'
- '--providers.file.directory=/traefik/dynamic/'
- '--providers.file.watch=true'
# use dnschallenge instead of httpchallenge
# - '--certificatesresolvers.letsencrypt.acme.httpchallenge=true'
# - '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http'
- '--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=hetzner'
- '--certificatesresolvers.letsencrypt.acme.dnschallenge.delaybeforecheck=0'
- '--certificatesresolvers.letsencrypt.acme.httpchallenge=true' # [!code --][!code focus]
- '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http' # [!code --][!code focus]
- '--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=hetzner' # [!code ++][!code focus]
- '--certificatesresolvers.letsencrypt.acme.dnschallenge.delaybeforecheck=0' # [!code ++][!code focus]
- '--certificatesresolvers.letsencrypt.acme.storage=/traefik/acme.json'
- '--providers.docker=true'
labels:
- traefik.enable=true
- traefik.http.routers.traefik.entrypoints=http
- traefik.http.routers.traefik.middlewares=traefik-basic-auth@file
- traefik.http.routers.traefik.service=api@internal
- traefik.http.routers.traefik.tls.certresolver=letsencrypt
- traefik.http.routers.traefik.tls.domains[0].main=coolify.io
- traefik.http.routers.traefik.tls.domains[0].sans=*.coolify.io
- traefik.http.routers.traefik.tls.certresolver=letsencrypt # [!code focus]
- traefik.http.routers.traefik.tls.domains[0].main=coolify.io # [!code focus]
- traefik.http.routers.traefik.tls.domains[0].sans=*.coolify.io # [!code focus]
- traefik.http.services.traefik.loadbalancer.server.port=8080
- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
- traefik.http.middlewares.gzip.compress=true
- coolify.managed=true
- coolify.proxy=true
```

> You can also set `env_file` instead of `environment` in the example above, but then you need to create a `.env` file with the `HETZNER_API_TOKEN` variable on the server.
Expand All @@ -94,63 +96,48 @@ If you would like to use one (wildcard) certificate for all of your resources, y

It is useful, because Traefik do not need to generate a new certificate for every resource, so new deployments will be available immediately without waiting for the certificate generation.

- In your application, set your FQDN to a subdomain you would like to use: `https://example.coolify.io`.
- In your application, set your Domain to a subdomain you would like to use and press save: `https://example.coolify.io`.

```bash
traefik.enable=true
traefik.http.routers.<unique_router_name_https>.rule=Host(`example.coolify.io`) && PathPrefix(`/`)
traefik.http.routers.<unique_router_name_https>.entryPoints=https
traefik.http.routers.<unique_router_name_https>.middlewares=gzip
traefik.http.routers.<unique_router_name_https>.service=<unique_service_name>
traefik.http.routers.<unique_router_name_https>.tls=true
traefik.http.services.<unique_service_name>.loadbalancer.server.port=80
traefik.http.routers.<unique_router_name_https>.tls.certresolver=letsencrypt
<ZoomableImage src="/docs/images/applications/domain.webp" alt="Domain input field on Applications" />

<ZoomableImage src="/docs/images/knowledge-base/compose/domain.webp" alt="Domain input field on Services" class="mt-5" />

traefik.http.routers.<unique_router_name_http>.rule=Host(`example.coolify.io`) && PathPrefix(`/`)
traefik.http.routers.<unique_router_name_http>.entryPoints=http
traefik.http.routers.<unique_router_name_http>.middlewares=redirect-to-https
```

### SaaS

Redirect all subdomains to one application. You can use this option if you want to use Coolify as a SaaS provider.

- In your application, leave the FQDN configuration `empty`.
- In your application, leave the Domain field `empty`.
- Add the following custom label configuration:

:::tabs key:saas
== Traefik v3
:::code-group

```bash
```traefik [Traefik v3]
traefik.enable=true
traefik.http.routers.<unique_router_name_https>.rule=HostRegexp(`^.+\.coolify\.io$`)
traefik.http.routers.<unique_router_name_http>.entryPoints=http
traefik.http.routers.<unique_router_name_http>.middlewares=redirect-to-https
traefik.http.routers.<unique_router_name_http>.rule=HostRegexp(`^.+\.coolify\.io$`) # [!code highlight]
traefik.http.routers.<unique_router_name_https>.entryPoints=https
traefik.http.routers.<unique_router_name_https>.middlewares=gzip
traefik.http.routers.<unique_router_name_https>.rule=HostRegexp(`^.+\.coolify\.io$`) # [!code highlight]
traefik.http.routers.<unique_router_name_https>.service=<unique_service_name>
traefik.http.routers.<unique_router_name_https>.tls.certresolver=letsencrypt
traefik.http.services.<unique_service_name>.loadbalancer.server.port=80
traefik.http.routers.<unique_router_name_https>.tls=true

traefik.http.routers.<unique_router_name_http>.rule=HostRegexp(`^.+\.coolify\.io$`)
traefik.http.routers.<unique_router_name_http>.entryPoints=http
traefik.http.routers.<unique_router_name_http>.middlewares=redirect-to-https
traefik.http.services.<unique_service_name>.loadbalancer.server.port=80
```

== Traefik v2

```bash
```traefik [Traefik v2]
traefik.enable=true
traefik.http.routers.<unique_router_name_https>.rule=HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.coolify.io`)
traefik.http.routers.<unique_router_name_http>.entryPoints=http
traefik.http.routers.<unique_router_name_http>.middlewares=redirect-to-https
traefik.http.routers.<unique_router_name_http>.rule=HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.coolify.io`) # [!code highlight]
traefik.http.routers.<unique_router_name_https>.entryPoints=https
traefik.http.routers.<unique_router_name_https>.middlewares=gzip
traefik.http.routers.<unique_router_name_https>.rule=HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.coolify.io`) # [!code highlight]
traefik.http.routers.<unique_router_name_https>.service=<unique_service_name>
traefik.http.routers.<unique_router_name_https>.tls.certresolver=letsencrypt
traefik.http.services.<unique_service_name>.loadbalancer.server.port=80
traefik.http.routers.<unique_router_name_https>.tls=true

traefik.http.routers.<unique_router_name_http>.rule=HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.coolify.io`)
traefik.http.routers.<unique_router_name_http>.entryPoints=http
traefik.http.routers.<unique_router_name_http>.middlewares=redirect-to-https
traefik.http.services.<unique_service_name>.loadbalancer.server.port=80
```

:::
Expand All @@ -159,7 +146,8 @@ traefik.http.routers.<unique_router_name_http>.middlewares=redirect-to-https

> `traefik.http.services.<unique_service_name>.loadbalancer.server.port` should be the same as your application listens on. Port 80 if you use a static deployment.

Read more about [HostRegexp](https://doc.traefik.io/traefik/routing/routers/#hostregexp) rule in the official Traefik documentation.

::: warning Caution
You cannot use both configurations (Normal & SaaS) at the same time on one
server.
Your Application / Service needs to restart for domain changes to take effect.
:::
Binary file added docs/public/images/applications/domain.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading