Add a second domain
$ grim server:add-domain shop www.shop.example.com
The shop is live on shop.example.com and now it should answer on www.shop.example.com too, or on the .cz the client bought last week. A second domain has to be known in three places: the host's nginx, Traefik's routing rule and the certificate. Editing one of them by hand gives you a 404 from Traefik or a certificate warning. grim server:add-domain changes all three together.
Usage
$ grim server:add-domain shop www.shop.example.com # vhost, routing and certificate
$ grim server:add-domain shop shop.example.cz --force-dns # DNS sits behind a proxyRun it from anywhere. The project must have been added with grim server:add-project from this machine, because the primary domain and the host are read from your ~/.grim/servers.json. Point the new domain's DNS at the server before you start.
Arguments and options
Attach an additional domain (alias) to an existing project — same upstream, expanded SSL cert
Usage
grim server:add-domain [--host HOST] [--env ENV] [--no-ssl] [--force-vhost] [--force-dns] [--] <project> <domain>Arguments
| Argument | Description |
|---|---|
project |
Project name (as registered in servers.json) (required) |
domain |
New domain to add as an alias (required) |
Options
| Option | Description |
|---|---|
--host=HOST |
Server host or alias (auto-resolved from servers.json when omitted) |
--env=ENV |
Environment (production, staging, …) (default: production) |
--no-ssl |
Skip certbot — render the vhost only |
--force-vhost |
Bypass the "domain already on another vhost" pre-flight |
--force-dns |
Skip the DNS A-record check (split-horizon / proxy DNS) |
What it actually does
Two checks come first, and either can stop the run before the server is changed.
- Checks DNS from your machine. The new domain must resolve, and to an address the server also has. Skipped with
--no-ssland--force-dns. - Looks for the domain in other vhosts on the server, the same check
grim server:add-projectmakes. - Rewrites the stack's nginx vhost with the new name next to the primary one, and reloads nginx.
- Rewrites the Traefik rule in the project's
docker-compose.ymlso that it matches every domain, and recreates the project's nginx container only. The app, the queue and the scheduler keep running. - Widens the certificate. Runs
certbot --expandfor the primary domain and every alias, so one certificate covers them all. Skipped with--no-ssl. - Saves the alias in
servers.json. From theregrim server:add-project,grim server:upgradeandgrim server:sync-composepick it up, so a later run of those does not drop it.
The summary lists the primary domain, every alias and the state of the certificate.
Pitfalls
Staging is its own stack
--env=staging works on /opt/<project>-staging and on the vhost grim-<project>-staging.conf, the stack that grim server:add-project --env=staging made. The production vhost is not read and not written. Without --env the command means production, also when staging is the only environment you registered; then it stops with Project "shop" not found in env "production". Run `grim server:add-project` first.
DNS behind a proxy fails the check
shop.example.cz resolves to 198.51.100.7 but the host 203.0.113.10 resolves to 203.0.113.10 — they need to share an IP. is the right answer for a typo in the record and the wrong one for a domain behind Cloudflare or split DNS. When you know the traffic arrives at the server, pass --force-dns. A domain with no record at all stops with shop.example.cz has no A record. Check DNS, or pass --force-dns to bypass.
It is built for Let's Encrypt
The vhost this command writes has no place for a certificate of your own. On a project added with --cert and --key it leaves the site on plain HTTP. Run grim server:add-project again afterwards, without --cert: it keeps the installed certificate, writes the HTTPS block back and includes the new alias. The certificate itself must already cover the new name.
A second domain is served, not redirected
Both names reach the same app, and APP_URL in the server's .env still names the primary one. If the alias should redirect to the primary domain, that is the app's job.
A failed certificate does not fail the run
Read the SSL row of the summary. The vhost is rewritten before certbot runs, and it is certbot that writes the HTTPS block into it. On failed the primary domain is without that block as well, until the certbot command printed below the table succeeds. Repeat it at once.
--no-ssl takes HTTPS off the whole project
For the same reason. With --no-ssl the vhost is rewritten and certbot never runs, so a project that had a certificate is left on plain HTTP. Use the flag only on a project that was added with --no-ssl itself.
After it finishes
Open the new domain in a browser. Running the command again with a domain that is already attached is safe: it writes the same vhost and asks certbot for the same list of names.
Related spells
grim server:add-project
Give a project a home
Prepare one environment of a project on a production server, with its database, nginx vhost, certificate, compose stack and .env.
grim server:auth
Put a password on a site
Switch HTTP Basic Auth on or off for a deployed project, in the host nginx that stands in front of it.
grim server:remove-project
Tear a project down
Remove one environment of a project from its server, with its containers, volumes, database, vhost, certificate and directory.
grim server:upgrade
Refresh a project's server files
Send the current docker-compose.yml and in-container nginx config to a project's server, without deploying a new image.