Server/Web
The Trilium wiki actually has a really good section on installing a server/web instance so I'll only really be expanding on the docker installation method.
Docker Compose#
Since the wiki only goes over a simple docker run
command, I figured a fully-fledged docker compose file might be useful to people.
version: "3.8"
services:
trilium:
image: zadam/trilium:0.60-latest
container_name: trilium
volumes:
- /path/to/data:/home/node/trilium-data
restart: unless-stopped
You should replace 0.60-latest
with the version of Trilium you want to run. You should also replace /path/to/data
with the location you want to store your Trilium data. Without providing a volume like this, your data will not be guaranteed to be saved. You can use your XDG_CONFIG_HOME
but do keep in mind the filesizes can get pretty large in the trilium-data
folder so pick your location accordingly. Lastly, change the restart
directive as you see fit. Having it as unless-stopped
is good if you expect it to always be running.
If you want the data saved from Trilium to be saved as your local user, you'll need to add some environment variables to the mix. Add this environment
config to the same level as volumes
.
environment:
- USER_UID=1001
- USER_GID=1001
Obviously, replace these values with your own. You can check them via id -u
and id -g
respectively.
Reverse Proxy (Traefik)#
There has been a lot of issues opened on GitHub about trying to use Trilium with SSL. My best recommendation for that is to use a reverse proxy like Traefik. This will not be an exhaustive guide on Traefik, but it should be enough to get you going with SSL and Trilium.
Docker Compose#
version: "3.8"
services:
traefik:
image: traefik:2.10
container_name: traefik
ports:
- "80:80" # The HTTP port
- "443:443" # The HTTPS port
volumes:
# Lets traefik view docker labels
- /var/run/docker.sock:/var/run/docker.sock
# Static config file
- /path/to/traefik.yml:/etc/traefik/traefik.yml
# Where to store the SSL certificate
- /path/to/acme.json:/acme.json
networks:
- traefik-proxy
networks:
traefik-proxy:
name: traefik-proxy
external: true
Obviously once again adjust the paths as make sense on your machine. You'll notice at the bottom there is an external network defined, so let's go ahead and create that with docker network create -b bridge traefik-proxy
. Creating it outside of the compose file means it will still exist regardless of whether the compose files are up or down. This can be a good thing to maintain configurations between moving things around.
Traefik Config#
But now we need to create the static configuration file we defined in the compose file.
# /path/to/traefik.yml
global:
checkNewVersion: true # optional
sendAnonymousUsage: false # optional
entryPoints:
web:
address: :80
# This http block is optional, it forces https via redirect
http:
redirections:
entryPoint:
to: web-secure
scheme: https
permanent: true
web-secure:
address: :443
providers:
docker:
endpoint: unix:///var/run/docker.sock
watch: true
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /path/to/acme.json
httpChallenge:
entryPoint: web
Make sure you update the paths accordingly, and take a look at the comments to customize to your preference. Also make sure the email is valid!
Update Trilium Compose#
If we now take our Trilium docker compose file from earlier and update it to work with Traefik, it might look a little something like this:
version: "3.8"
services:
trilium:
image: zadam/trilium:0.60-latest
container_name: trilium
volumes:
- /path/to/data:/home/node/trilium-data
restart: unless-stopped
networks:
- traefik-proxy
labels:
# Tell traefik to proxy this
- traefik.enable=true
# Define an SSL router
- traefik.http.routers.trilium.entrypoints=web-secure
# Tell Traefik to listen for yourdomain.com
- traefik.http.routers.trilium.rule=Host(`yourdomain.com`)
# Define letsencrypt as our SSL method
- traefik.http.routers.trilium.tls.certresolver=letsencrypt
# Route traffic into port 8080 of this container
- traefik.http.services.trilium.loadbalancer.server.port=8080
networks:
traefik-proxy:
name: traefik-proxy
external: true
I think the comments in the file do a good job at explaining, but I'll point out some important changes. First notice the top-level networks
directive that matches the one from our Traefik file. That's important to make sure we're using the correct internal network in this compose file. Next notice the networks
directive on the container itself. This maps the top-level network to this container so the traffic is proxied by Traefik. Lastly there is the labels
directive which is what Traefik looks at to configure how to proxy this container. For details, refer back to the comments in the file itself.
Put It All Together#
Multiple Composes#
Multiple files may seem like overkill for this case with just two containers, but setting it up like this allows you to scale and add more to your server while all still being proxied by Traefik with SSL. And since we already have everything in separate files, this is the easiest to do. Just run docker compose up
on each the Traefik and Trilium compose files. Because the network we created was created externally, it doesn't actually matter what order you start them in. Once Traefik starts up, it takes over the network and starts proxying requests.
You should be able to see it at https://yourdomain.com
without any port value or SSL issues thanks to Traefik!
Single Compose#
We can go ahead and combine both of these into one large docker-compose.yml
.
version: "3.8"
services:
traefik:
image: traefik:2.10
container_name: traefik
ports:
- "80:80" # The HTTP port
- "443:443" # The HTTPS port
volumes:
# Lets traefik view docker labels
- /var/run/docker.sock:/var/run/docker.sock
# Static config file
- /path/to/traefik.yml:/etc/traefik/traefik.yml
# Where to store the SSL certificate
- /path/to/acme.json:/acme.json
networks:
- traefik-proxy
trilium:
image: zadam/trilium:0.60-latest
container_name: trilium
volumes:
- /path/to/data:/home/node/trilium-data
restart: unless-stopped
networks:
- traefik-proxy
labels:
# Tell traefik to proxy this
- traefik.enable=true
# Define an SSL router
- traefik.http.routers.trilium.entrypoints=web-secure
# Tell Traefik to listen for yourdomain.com
- traefik.http.routers.trilium.rule=Host(`yourdomain.com`)
# Define letsencrypt as our SSL method
- traefik.http.routers.trilium.tls.certresolver=letsencrypt
# Route traffic into port 8080 of this container
- traefik.http.services.trilium.loadbalancer.server.port=8080
networks:
traefik-proxy:
name: traefik-proxy
external: true
Then use docker compose up
to start things up. You should be able to see it at https://yourdomain.com
without any port value or SSL issues thanks to Traefik!