Skip to content

Commit

Permalink
add reverse proxy config documentation (#267)
Browse files Browse the repository at this point in the history
Hey, since I've been using Actual via Traefik for a few days now, I took
the time to add a little bit to the documentation in that regard. I hope
it fits so far. Please feel free to comment/improve anything.
  • Loading branch information
ptpu authored Dec 3, 2023
1 parent 36969de commit 941838c
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 58 deletions.
7 changes: 5 additions & 2 deletions .github/actions/spelling/allow/keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ AQL
autocompletes
Blix
caniuse
Cardless
categorygroup
Certbot
clsx
codemirror
commandlet
Cardless
Crd
crdt
creditcards
Expand All @@ -37,6 +38,7 @@ Kroger
kubectl
kubernetes
ldaplogin
letsencrypt
libofx
linting
lte
Expand Down Expand Up @@ -67,6 +69,7 @@ subreaper
subtransaction
subtransactions
tini
traefik
Upstash
useb
usernames
Expand All @@ -75,5 +78,5 @@ Venmo
WSL
Xxxxx
ynab
YNAB
Ynab
YNAB
1 change: 1 addition & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ SVGR
swc
ubuntu
VRT
websecure
2 changes: 1 addition & 1 deletion docs-sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const sidebars = {
type: 'doc',
id: 'config/index',
},
items: ['config/https'],
items: ['config/https', 'config/reverse-proxies'],
},
{
type: 'category',
Expand Down
12 changes: 9 additions & 3 deletions docs/config/https.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ title: Activating HTTPS

You’ll need to enable HTTPS on your home server in order to safely use all of Actual’s features. **You don’t need to follow these steps** if you run the server on your own computer and only access it through `localhost`, or if you’re using a cloud provider that handles HTTPS for you. There are a few different ways to get HTTPS to work, depending on what you’d prefer to do.

1. Use a self-signed certificate. This is the easiest way to get HTTPS working, but it will cause your browser to display a warning that the certificate is invalid. Additionally, if anyone gets access to this certificate, they can intercept most secure traffic on your computer.
Both methods refer to not exposing Actual on the internet. If this is desired refer to [Using a Reverse Proxy](reverse-proxies).

## Use a self-signed certificate

Use a self-signed certificate. This is the easiest way to get HTTPS working, but it will cause your browser to display a warning that the certificate is invalid. Additionally, if anyone gets access to this certificate, they can intercept most secure traffic on your computer.
- A command line tool like [mkcert](https://github.com/FiloSottile/mkcert) can automate this process.
- Alternately, you can manually generate the certificates. Install OpenSSL for your operating system, then run `openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout selfhost.key -out selfhost.crt` in a terminal to generate the certificate and private key. You’ll need to enter a two-letter country code to get the `.crt` file to be generated, but you can leave the rest of the fields blank (just hit enter at each prompt). Move the `selfhost.key` and `selfhost.crt` files a location accessible to the Actual server.
2. Connect your server to a domain you control and make it public to the Internet. You could use a tool like [certbot](https://certbot.eff.org) to generate a valid certificate once you have the domain set up.
3. Use a service like [Tailscale](https://tailscale.com/kb/1153/enabling-https/) or [Caddy](https://caddyserver.com/docs/automatic-https#dns-challenge) that allows you to create a valid HTTPS certificate without having to expose your server to the wider internet.

## Obtain certificate without exposing to the internet
Use a service like [Tailscale](https://tailscale.com/kb/1153/enabling-https/) or [Caddy](https://caddyserver.com/docs/automatic-https#dns-challenge) that allows you to create a valid HTTPS certificate without having to expose your server to the wider internet.

## Update Actual Configuration
Once you have the certificate, you’ll need to configure Actual to use it. There are two ways to do this:

1. **Configuring with `config.json`**: Create a `config.json` file in the same folder where you run Actual (or `/data` if you’re using a Docker container). Put the paths to the `.key` and `.crt` files in the file. Note: if you’re using Docker or a similar container environment, make sure the paths are accessible to the container. For example:
Expand Down
109 changes: 109 additions & 0 deletions docs/config/reverse-proxies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
title: Using a Reverse Proxy
---

# Using a Reverse Proxy

If you want to expose Actual to the internet, you should hide it behind a reverse proxy with SSL enabled.
There are a series of tools that can be used for this purpose. This configuration page is dynamic, so that new tools and their configuration can be added continuously.

In our examples, the Actual Server should be published under the domain **budget.example.org**.

:::note
The **basic configurations** provided here are only suggestions for implementing a reverse proxy configuration. Additional security mechanisms should then be activated/implemented for the tool selected in each case.
:::

## Traefik

Our example shows a working configuration for Traefik and Actual Server using Docker - as documented in [Install Actual/Docker](../install/docker.md)

```yaml title="docker-compose.yml"
services:
traefik:
image: traefik:latest
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- "./traefik.yaml:/etc/traefik/traefik.yaml"
- "./traefik/data:/data"
- "/var/run/docker.sock:/var/run/docker.sock"

actual-server:
image: actualbudget/actual-server:latest
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.actual-server.rule=Host(`budget.example.org`)"
- "traefik.http.routers.actual-server.entrypoints=websecure"
volumes:
- ./actual-data:/data
restart: unless-stopped
```
```yaml title="traefik.yaml"
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
websecure:
address: ":443"
http:
tls:
certResolver: le

providers:
docker: {}

certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: /data/letsencrypt.json
httpChallenge:
entryPoint: web
```
Please refer to the [official documentation](https://doc.traefik.io/traefik/user-guides/docker-compose/basic-example/) for further details.
## NGINX
```nginx title="NGINX Example Config"
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name budget.*;

include /config/nginx/ssl.conf;
client_max_body_size 0;

# With SSL via Let's Encrypt
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

location / {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;

set $upstream_app actual-server;
set $upstream_port 5006;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
}
```

The SSL certificate is issued by Let's Encrypt. The [Certbot](https://certbot.eff.org/instructions) tool provides options for automatic updating upon expiration.
At the very least you will need to adapt `server_name` and the `ssl_certificate/ssl_certificate_key` paths to match your setup.
Please refer to their [official documentation](https://nginx.org/en/docs/) for further details.
52 changes: 0 additions & 52 deletions docs/install/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,55 +92,3 @@ $ docker stop my_actual_budget && docker container rm my_actual_budget && docker
## Test connection within local network

On another PC within the local network connect to http://_serverIP_:_chosenPort_

## Expose to the Internet with NGINX

<details><summary>Example NGINX config</summary>

```nginx
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name budget.*;
include /config/nginx/ssl.conf;
client_max_body_size 0;
# enable for ldap auth, fill in ldap details in ldap.conf
#include /config/nginx/ldap.conf;
# enable for Authelia
#include /config/nginx/authelia-server.conf;
location / {
# enable the next two lines for http auth
#auth_basic "Restricted";
#auth_basic_user_file /config/nginx/.htpasswd;
# enable the next two lines for ldap auth
#auth_request /auth;
#error_page 401 =200 /ldaplogin;
# enable for Authelia
#include /config/nginx/authelia-location.conf;
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app actual_budget;
set $upstream_port 5006;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
}
```

</details>

Using nginx web UI:

- Scheme: `http`
- Forward Hostname/IP: `actual_budget`
- Forward Port: `5006`

0 comments on commit 941838c

Please sign in to comment.