aboutsummaryrefslogtreecommitdiff
path: root/content/posts/2022-07-18-firefly-install.md
blob: 4dfd008cb3afbed1f50049b9cd97e0b93f3cb2ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
---
title: "Running firefly3 on alpine"
date: 2022-07-18
tags: ['alpine', 'linux', 'php', 'nginx']
---

**Disclaimer:** before starting be aware that I'm not a sysadmin nor I have a
deep knowledge in security. This is me reporting the steps I did as a learning
experiment, so take this tutorial as your own risk.

I have a pretty decent knowledge in container tecnology, I maintain several
container on my local server for many applications. However I've decided to
take a step back and learn a bit more how those applications are really
deployed and kept without containers, and first candidate being firefly3[^1]. I
have it currently running on container but let's install in a disctributions.

For the distro of choice I'll pick alpine, for its small footprint and the use
of OpenRC (nothing against systemd though).

*I don't want to extend this tutorial to cover every single part, so for the
next steps I'll assume that you have a running instance of PostgreSQL and
Alpine.*

## Dependencies

First we need to install all the necessary packages to get firefly running.
Let's go through them and check are they are used for.

```shell
apk add curl tar gzip
```

cURL is needed to download the source code from Github and tar gzip are for
extracting the compressed code.

```shell
apk add composer
```

 Composer is a dependency manager for PHP. It is required to download the
 dependencies of the project.

 Now we need to download the list of dependencies list in the site[^2].

```
 Extra packages
 Install the following PHP modules:
    PHP BCMath Arbitrary Precision Mathematics
    PHP Internationalization extension
    PHP Curl
    PHP Zip
    PHP Sodium
    PHP GD
    PHP XML
    PHP MBString
    PHP whatever database you're gonna use.
```

For those we have the following alpine packages:

```shell
apk add \
    php8 \
    php8-curl \
    php8-zip \
    php8-sodium \
    php8-gd \
    php8-xml \
    php8-mbstring \
    php8-bcmath \
    php8-pgsql
```

But that is not everything, I don't If I lack knowledge in the PHP stack but
the applicatoin will later complain about a lot of missing dependencies, those
being:

```shell
apk add \
    php8-fileinfo \
    php8-intl \
    php8-session \
    php8-simplexml \
    php8-tokenizer \
    php8-xmlwriter \
    php8-dom \
    php8-pdo_pgsql \
    php8-shmop
```

A tip that may as well help you later. Some of those not listed packages are
described in the their project for the docker image[^3] and its base image[^4].
It can also help with describing the necessary steps.

As the next step we need to install the pieces of software that will actually
run the project:

```shell
apk add nginx php8-fpm
```
Nginx will act as reverse proxy and php8-fpm will actually run the project. You
can use lighttpd as well as some others.

## Deploying the code

Now we have all necessary packages, lets download the project into on server,
grab the latest release from Github, at the time of this writing is `5.7.9`.
Download into the `/var/www/firefly`. The folder location is kinda up you, I
think nginx itself has another default folder for its sites, but I always use
www folder to store the projects.

```shell
mkdir -p /var/www/firefly
```

Create the folder then download/extract the source code:

```shell
curl -SL https://github.com/firefly-iii/firefly-iii/archive/refs/tags/5.7.9.tar.gz | \
    tar zxC /var/www/firefly --strip-components 1
```

This piece of code was taken from the dockerfile[^5].

Now move to the `/var/www/firefly` and install its dependencies with composer:
```shell
cd /var/www/firefly
composer install --prefer-dist --no-dev --no-scripts
```

## Config files

### Firefly

Firefly makes the process of setting up the connection strings and other
configuration quite easy. We'll only need to create an `.env` file with all the
information needed. Fill the information according with your setup:

```ini
# /var/wwww/firefly/.env

DB_CONNECTION=pgsql
DB_HOST=localhost
DB_PORT=5432
DB_DATABASE=firefly
DB_USERNAME=admin
DB_PASSWORD=admin
APP_KEY=<RANDON_KEY>
```

To generate a random key just run:

```shell
head /dev/urandom | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 32 && echo
```

Once you have set it up we need to bootstrap the project:

```shell
php artisan config:cache
```

To update the cached configuration. If everything is setup properly the process
finish successfully.

```shell
php artisan firefly-iii:create-database
php artisan migrate:refresh --seed
php artisan firefly-iii:upgrade-database
```

To bootstrap the database.

### Nginx

We will need to edit the nginx config file to find and run the project, add
the following server inside of `/etc/nginx/http.d/`, by default nginx will read
all `.config` inside of that folder. Just like the www folder this is more a
personal choice, you have some room to choose where you want to config this
server.

```shell
# /etc/nginx/http.d/firefly.conf
server {
    listen 8080;
    server_name localhost;


    root /var/www/firefly/public;

    location ~ \.php$ {
        try_files $uri $uri/ =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass 127.0.0.1:9000;
        include fastcgi.conf;
    }

    location / {
      try_files $uri /index.php$is_args$args;
    }
}
```

This will set up the process in the port 8080. It is just an exemple, adapt it
to your needs.

### Services

Now that we have everything set up we can start the service to serve firefly:

```shell
rc-service php-fpm8 start
rc-service nginx start
```

`http://localhot:8080/` (or your server's hostname) should be up and running.

[^1]: https://www.firefly-iii.org/
[^2]: https://docs.firefly-iii.org/firefly-iii/installation/self_hosted/?mtm_campaign=docu-internal&mtm_kwd=self_hosted
[^3]: https://dev.azure.com/Firefly-III/_git/MainImage
[^4]: https://dev.azure.com/firefly-iii/_git/BaseImage
[^5]: https://dev.azure.com/Firefly-III/MainImage/_git/MainImage?path=/Dockerfile&version=GC520b8f865ea623a8625fe64e9f583406849be91a&line=14&lineEnd=15&lineStartColumn=1&lineEndColumn=1&lineStyle=plain&_a=contents