Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vpkopylov/7082831a106dfbec4084d8ffb0772f5b to your computer and use it in GitHub Desktop.
Save vpkopylov/7082831a106dfbec4084d8ffb0772f5b to your computer and use it in GitHub Desktop.
How to setup Firefly III in docker with https support (using NGINX and let's encrypt)

This gist is based on another one but it's slightly restructured for better readability. Also docker-compose config is simplified and to avoid breaking changes the specific version (version 6) of Firefly is used.

Prerequisites

  1. VPS/server with any modern OS that supports docker
  2. A domain name with A record pointed to this server
  3. Ports 80 and 443 allowed in firewall

Nginx setup

First we will setup Nginx and ssl certs and next Firefly itself. We put nginx and firefly configs in separate folders to isolate private services, and because nginx can potentially be used to proxy other services. External nginx-proxy network is created to connect Firefly and Nginx containers.

  1. Create nginx-proxy folder somewhere and docker-compose.yml file inside it, put the following into the file:
docker-compose.yml
version: '3.3'
services:
  nginx-proxy:
    image: nginxproxy/nginx-proxy:alpine
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./current/public:/usr/share/nginx/html
      - ./certs:/etc/nginx/certs:ro
      - ./vhost:/etc/nginx/vhost.d
      - /var/run/docker.sock:/tmp/docker.sock:ro
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"
  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    restart: always
    environment:
      NGINX_PROXY_CONTAINER: nginx-proxy
      NGINX_DOCKER_GEN_CONTAINER: nginx-proxy
    volumes:
      - ./current/public:/usr/share/nginx/html
      - ./certs:/etc/nginx/certs:rw
      - ./vhost:/etc/nginx/vhost.d
      - /var/run/docker.sock:/var/run/docker.sock:ro
networks:
  default:
    external:
      name: nginx-proxy
  1. Create an external network first and then start docker-compose
docker network create nginx-proxy
docker-compose up -d

Firefly III setup

  1. Create firefly-iii folder next to nginx-proxy one and docker-compose.yml file in it. Put the following into the file This configuration is based on the offical example, you might also want to check it out.
docker-compose.yml
version: '3.3'

services:
  app:
    image: fireflyiii/core:version-6
    hostname: app
    container_name: firefly_iii_core
    restart: always
    volumes:
      - firefly_iii_upload:/var/www/html/storage/upload
    env_file: .env
    networks:
      - firefly_iii
      - nginx-proxy
    expose:
      - 8080
    depends_on:
      - db
  db:
    image: mariadb
    hostname: db
    container_name: firefly_iii_db
    restart: always
    env_file: .db.env
    networks:
      - firefly_iii
    volumes:
      - firefly_iii_db:/var/lib/mysql
  cron:
    image: alpine
    restart: always
    container_name: firefly_iii_cron
    command: sh -c "echo \"0 3 * * * wget -qO- http://app:8080/api/v1/cron/REPLACEME\" | crontab - && crond -f -L /dev/stdout"
    networks:
      - firefly_iii

volumes:
   firefly_iii_upload:
   firefly_iii_db:

networks:
  firefly_iii:
    driver: bridge
  nginx-proxy:
    external: true
  1. Create .env file in the same folder. It will contain firefly container's env vars. Copy/paste the contents from the official example:
  2. Add the following to the file:
VIRTUAL_HOST=your_domain
VIRTUAL_PORT=8080
LETSENCRYPT_HOST=your_domain
LETSENCRYPT_EMAIL=your_domain_admin_email
  1. Replace your_domain and your_domain_admin_email with the appropriate values. Please note, that these vars are required for nginx-proxy and letsencrypt. They are deliberately set on firefly container and not in the nginx config, because of the way how nginx-proxy works. It uses docker api to analyze changes in another containers configuration, seachers for specific vars and creates configuration files automatically based on them. Similarly setting LETSENCRYPT_HOST and LETSENCRYPT_EMAIL vars on some container triggers letsencrypt to download and setup ssl certs.

  2. Set TRUSTED_PROXIES var in .env file to **, it's required for using reverse proxies such as nginx.

  3. Change DEFAULT_LANGUAGE, DEFAULT_LOCALE and TZ vars if needed. Check the other vars in the file.

  4. Follow the docs to setup .db.env file.

  5. Setup cron jobs

  6. You may also want to setup email notifications and backups

  7. Start docker-compose

docker-compose up -d
  1. After that letsencrypt container should pick up your settings, issue and setup ssl certificates in nginx. Similarly nginx should start to proxy web clients. You may now go to https://your_domain and login to Firefly. If something is not working check out logs with docker-compose logs
@lucaslgr
Copy link

I want to run three application behind NGINX as a reverse proxy. Firefly III, PiHole and HomeAssistant. I've been trying it just with NGINX image and the other applications images, but I can't reach my goal.
Also, I want to run it just locally, in a local server, and I'll export the access to these applications through a VPN (Tailscale), so, I won't have a public domain, I just want to use virtual hosts that will work like domains for my local network and to the devices connected in my VPN.
Do you have some ideia whether is it possible using this approach with the nginx-proxy container?

Thanks in advance

@vpkopylov
Copy link
Author

@lucaslgr as said in this reply you should be fine with nginx-proxy, as long as your dns environment resolves a host configured in VIRTUAL_HOST to the host running nginx-proxy. Public domain is not a requirement, just don't use let's encrypt part.

@lucaslgr
Copy link

lucaslgr commented Apr 19, 2024

Thank you, @vpkopylov

Do you have any idea why it doesn't work when I set VIRTUAL_HOST=anydomain or VIRTUAL_HOST=anysubdomain.anydomain?
it just worked when I set VIRTUAL_HOST=anysubdomain.localhost

@vpkopylov
Copy link
Author

Hard to say without knowning the details of you environment. Maybe your dns service doesn't resolve anysubdomain.anydomain to the host with docker/nginx. In the internet environment usually you have to setup mapping from the domain to the host/IP with VPS using your domain registrar site. What software in your system is responsible to resolving anysubdomain.anydomain to the host where with nginx?

@lucaslgr
Copy link

Maybe your dns service doesn't resolve anysubdomain.anydomain to the host with docker/nginx
I'm not using any DNS server in my LAN. But, I thought that NGINX did this mapping part, like when it generates this nginx.conf file below:
image

Doesn't do it?
I mean, how it can map the VIRTUAL_HOST=anysubdomain.localhost and can't map just a single domain like VIRTUAL_HOST=anydomain once to solve the subdomain, firstly it needs to be able to solve the main domain before.

Another doubt that I have, if you could help me with that. As I told you before, I'm currently able to access my apps through nginx-proxy using VIRTUAL_HOST=anysubdomain.localhost. But I'm not finding a way to access my apps from another device in LAN. If I use my server LAN IP and 80 port I can reach NGINX perfectly, but, how can I access my apps once they are mapped with a subdomain that just exists inside my server?
🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment