Xtrendence / Cryptofolio

Track your cryptocurrency holdings/portfolio with an open-source web, mobile, and desktop application, along with a self-hosted RESTful API.
https://xtrendence.github.io/Cryptofolio/
GNU Affero General Public License v3.0
321 stars 59 forks source link

Nginx config? #53

Closed tandy-1000 closed 3 years ago

tandy-1000 commented 3 years ago

I'm trying to set this up on my server using Nginx, here is my config so far that I have created based on the Apache config:

server {
  listen 8006;

  location / {
    root /var/www/cryptfolio/website/;
    proxy_set_header Host $http_host;
  }

  location /api {
    alias /var/www/cryptfolio/api/;
  }
}

Upon loading the login page these messages are shown in the browser console:

Invalid JSON. main.js:2548:13
Invalid JSON. main.js:1444:12
Invalid JSON. main.js:2548:13
Invalid JSON. main.js:171:12
TypeError: MutationObserver.observe: One of 'childList', 'attributes', 'characterData' must not be false. kanji_content_detect.js:24:26

When attempting to login with password 'admin', POST requests result in error 405, meaning I can't login. The console shows:

POST http://server.local:8006/api/account/login.php?platform=web
[HTTP/1.1 405 Not Allowed 163ms]

If the discussions tab was enabled I would post this there, but if you have any suggestions / corrections for setting this up with Nginx I would appreciate it!

Xtrendence commented 3 years ago

I think it may be a permission issue. Could you run chown -R www-data:www-data /var/www/html/ and report back whether or not that fixed it? Thank you!

Xtrendence commented 3 years ago

If it's not a Docker container, you may need to run that with sudo.

tandy-1000 commented 3 years ago

The root folder /var/www/cryptofolio/ is owned by www-data:www-data, but the issue persists. Yep, it's not a docker container.

I also forgot to say that the 'Invalid JSON' popup shows when entering a password too.

Xtrendence commented 3 years ago

What do you see if you open the /var/www/cryptofolio/api/data/ directory? Are there any JSON files or is it empty? If it's empty, then it suggests the PHP script doesn't have permission to write data to that folder for some reason. If there are files in there, then if you don't already have any data, maybe try deleting them and open the website in your browser again and try logging in to regenerate the files.

tandy-1000 commented 3 years ago

It is empty, that's interesting.

Xtrendence commented 3 years ago

So the PHP script that handles logging in automatically generates a default account and empty settings files etc. if it doesn't find any existing ones. In this case, it fails to do so as it seems to be lacking the proper permissions. Apache runs as the user you assign to it (I think www-data by default). So the reason NGINX fails is probably because it isn't running as www-data, so you'd need to see what user and group NGINX runs as, and chown the directory again with the proper user and group.

Xtrendence commented 3 years ago

This might help: https://serverfault.com/questions/433265/how-do-i-change-the-nginx-user

tandy-1000 commented 3 years ago

My /etc/nginx/nginx.conf has www-data set as the user, so it's strange it doesn't work.

My nginx.conf is almost identical to this.

Xtrendence commented 3 years ago

Any chance it could be the 2nd step from that link?

  1. PHP-FPM Edit php-fpm.conf and set user and group to www-data. user - Unix user of processes. Default "www-data" group - Unix group of processes. Default "www-data"
Xtrendence commented 3 years ago

Oooo, perhaps it's this: https://stackoverflow.com/questions/44414122/nginx-file-put-contents-permission-denied

Could you chmod the directories with 777?

tandy-1000 commented 3 years ago

chmod 777 didnt help sadly. I will try set the user / group in php-fpm.conf.

tandy-1000 commented 3 years ago

The user and group in /etc/php/7.4/fpm/pool.d/www.conf is www-data (and nginx.conf is using /run/php/php7.4-fpm.sock).

Xtrendence commented 3 years ago

That's interesting... Since I use Apache myself and haven't used NGINX before, the only knowledge I can base my replies on is mostly speculation based on how the other web server software works. Could you maybe check these answers out as well and see if they apply to your situation? Specifically this bit? image_673

Xtrendence commented 3 years ago

Not sure if it needs to be ec2-user or www-data or what honestly, but the issue at its core is NGINX, and as an extension PHP not having the permission to write to directories owned by www-data, so perhaps the actual var/lib/nginx directory belonging to a different user/group affects that?

tandy-1000 commented 3 years ago

I think it must be something wrong with the nginx.conf, (or a bug?) because I am using Nginx to host recipes, and baikal, which both use PHP.

Xtrendence commented 3 years ago

It has to be something with permissions and user groups, whether it's the NGINX configuration or the directories etc. I think we can rule out Cryptofolio's code simply because it doesn't actually do anything that could cause a bug, like all it does is just create some files and fill them with data, and since it works on macOS, Windows, Linux, Docker Linux images and so on, and since the data directory is empty, it means that ultimately, file_put_contents isn't working. I suspect that if you made a test.php file with just:

<?php file_put_contents("test.txt", "testing"); ?>

It wouldn't actually create a text file with the word "testing" inside.

The only possible thing I could imagine going wrong with the PHP code of Cryptofolio itself is hashing the default password before writing it to the file. So if the test.php file works, let me know, and I'll do more research to see why password_hash() could fail on NGINX.

Xtrendence commented 3 years ago

Test.zip

Perhaps try putting this PHP file in the Cryptofolio api folder, and open it in your browser. If it displays a blank page without the word "testing", then it is indeed a permission issue or a configuration one.

tandy-1000 commented 3 years ago

I just added that file under api, and when visiting the url, it serves the test.php, Firefox offers to save it.

Xtrendence commented 3 years ago

Does it output the word "testing"?

tandy-1000 commented 3 years ago

Firefox doesn't take me to it, it just tries to download it.

Xtrendence commented 3 years ago

That's interesting... It's meant to just be a completely blank page with the word "testing" written on it. Check the api folder, is there a test.txt file?

tandy-1000 commented 3 years ago

Nope

tandy-1000 commented 3 years ago

I just tested Chromium, same result as FF

tandy-1000 commented 3 years ago

Do you happen to have a matrix account? We could discuss this issue there if you would prefer?

Xtrendence commented 3 years ago

I'd prefer to discuss it here just because if someone else runs into this issue, then they can see the path we took to solve it.

Also, that does confirm then that it's not Cryptofolio's code at least, but it does mean there's something up with NGINX. I just found out NGINX might not support PUT and DELETE requests by default either and might require something called HttpDavModule. Although in this case the login is a POST request and the test.php thing is GET. But Cryptofolio does use PUT and DELETE for other stuff, so even if we fixed this, there might be other issues in the future.

Is there any chance you could use Apache or is that off the table? If you absolutely can't, then I could try to set up my own NGINX server and see if I can get it to work, but that'd take some time as it'd be my first time using NGINX.

tandy-1000 commented 3 years ago

That makes sense.

Interesting, I could try Apache, but I would rather not, I am currently running both Nginx and Caddy on the ARM SBC server, and I wouldn't want to switch to a more resource heavy server.

Do you have experience with caddy? I could try port the apache config to that instead?

Xtrendence commented 3 years ago

I do not unfortunately. I do have another idea though. Is it possible that after changing the permissions and stuff, you forgot to restart NGINX? I know I forget stuff like that sometimes so worth a shot asking.

tandy-1000 commented 3 years ago

I see. Nope, I've been restarting the service to see changes. Thanks for all your help btw.

Xtrendence commented 3 years ago

It's okay. My friend suggested something else too that actually seems like it could be the issue. Could you ensure that PHP execution is turned on? Because if the test.php file was served as a download, then it suggests that PHP files aren't actually being executed.

Xtrendence commented 3 years ago

So perhaps your NGINX server isn't actually listening/running PHP files, just HTML. https://askubuntu.com/questions/134666/what-is-the-easiest-way-to-enable-php-on-nginx

Xtrendence commented 3 years ago

He also sent this link, and mentioned that it seems as though your nginx.conf seems to have an issue as far as passing the PHP files to be processed goes, so step 5 from here: https://stackoverflow.com/questions/25591040/nginx-serves-php-files-as-downloads-instead-of-executing-them/26668444#26668444

Xtrendence commented 3 years ago

He also said to make sure that the chown was indeed recursive, and that the api/data directory specifically does in fact belong to www-data:www-data.

tandy-1000 commented 3 years ago

The chown was recursive, here is the default config, everything seems fairly similar to that url. I restarted php-fpm and nginx and no change on test.php.

#D I E T - P I
# /etc/nginx/sites-available/default

server {
        listen 1080 default_server;
        listen [::]:1080 default_server;

        root /var/www;
        index index.php index.html index.htm index.nginx-debian.html;

        server_name "$hostname";

        include /etc/nginx/sites-dietpi/*.conf;

        location / {
                try_files $uri $uri/ =404;
        }

        location ~ \.php(?:$|/) {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/run/php/php7.4-fpm.sock;
                include fastcgi_params;
        }

}
tandy-1000 commented 3 years ago

I'll also add that baikal and recipes are working fine, I am able to login and such.

Xtrendence commented 3 years ago

Could I ask what your Linux distro is? I'll give it a shot and see if I can get an NGINX server up and running, and then share my configuration files and permission settings etc.

tandy-1000 commented 3 years ago

Debian unstable / DietPi.

Thank you for the effort.

Xtrendence commented 3 years ago

It's okay man, I'll be back in a bit then and hopefully I'll have some answers. If I can't figure it out then you might unfortunately have to set up Apache or something.

Xtrendence commented 3 years ago

So with the default nginx.conf, and with the /var/www/html directory chown-ed by www-data:www-data, I got test.php to work. Before the chown, test.txt wouldn't get created. I'll attach both my nginx.conf and /etc/nginx/sites-available/default. Hopefully this'll help, but as I'm not serving multiple sites, I can't really help further. All I can really confirm is that it's a permission issue. image_674

Configuration.zip

Xtrendence commented 3 years ago

You can ignore the screenshot of the CLI, that's just to show the permissions and whatnot of the files in case it's helpful. I was simply refreshing test.php in my browser between the ls commands. The copying was just to download the files from my host OS and upload them here easily since the content of html was already being served.

Xtrendence commented 3 years ago

This is the guide I followed to set up NGINX too in case it helps at all: https://www.raspberrypi.org/documentation/remote-access/web-server/nginx.md

tandy-1000 commented 3 years ago

Holy crap I fixed it, it was really simple.

First thing was to rename the cryptfolio root folder to html.

My final cryptfolio.conf looks like this:

server {
        listen 8006;
        root /var/www/cryptfolio/html/;

        location / {
                root /var/www/cryptfolio/html/website/;
                try_files $uri $uri/ /index.php?q=$uri&$args;
        }

        location /api {
                alias /var/www/cryptfolio/html/api/;
        }
        location ~ \.php(?:$|/) {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        }
}

Can I make a PR with documentation on how to make a manual install?

Xtrendence commented 3 years ago

That's great to hear! And I can add it to the Wiki and credit you for it by tagging your username, but PRs are just for Docker stuff which at this point can't really be improved upon, and I don't really add documentation as source code files to avoid having too many files for people to needlessly download. Originally I just wanted the root of the repo having the README, api, website, mobile, and desktop to keep it really simple and clean.

If you do a write up for NGINX, then I'll make a new Wiki page called Manual Installation Guide, put your write up there, credit you for it, and link it in the README for anyone else looking to manually serve it.

tandy-1000 commented 3 years ago

Should I post the markdown here then when I've finished?

tandy-1000 commented 3 years ago

Could you set this up so that we can link to the latest source code package with a generic link?

https://docs.github.com/en/github/administering-a-repository/releasing-projects-on-github/linking-to-releases

Manual Installation

Download the latest release of the source:

wget https://github.com/Xtrendence/Cryptofolio/releases/latest/source_code.zip

Create the folders in your web dir:

mkdir /var/www/cryptofolio mkdir /var/www/cryptofolio/html

Move the files and give the NGINX user permissions:

mv Cryptofolio/api /var/www/cryptofolio/html mv Cryptofolio/website /var/www/cryptofolio/html chown -R www-data:www-data /var/www/cryptofolio

Create NGINX config

/etc/nginx/conf.d/cryptofolio.conf/

server {
        listen 8006;
        root /var/www/cryptofolio/html/;

        location / {
                root /var/www/cryptofolio/html/website/;
                try_files $uri $uri/ /index.php?q=$uri&$args;
        }

        location /api {
                alias /var/www/cryptofolio/html/api/;
        }
        location ~ \.php(?:$|/) {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        }
}

Reload NGINX:

systemctl reload nginx

Xtrendence commented 3 years ago

Thank you, I'll post this on the Wiki in a bit. And yes, I think I just need to make a ZIP out of the website and api folders, and give it a generic name so that it doesn't have the version in it. I'll do that in a bit as well, just finishing off the date picker for the mobile app right now. Thank you for the help!

tandy-1000 commented 3 years ago

Awesome, great project btw, I have just set it up, haven't imported all of my transactions as it is quite a long process. It would be nice to have some sort of automatic importer maybe based on scanning a wallet? I understand if this is out of the project scope though. I've also noticed something strange in that settings seem to reset when restarting nginx / browser? I will examine this in the future and make an issue if necessary.

In relation to the manual install, a reverse proxy setup might also be a good thing to document, once you add the wiki I may add something about that.

Xtrendence commented 3 years ago

Settings are saved with localStorage, so if you use incognito or otherwise have disabled browser storage or the browser doesn't support it, then settings won't be saved.

Here's the page on the Wiki: https://github.com/Xtrendence/Cryptofolio/wiki/Manual-Installation

If you want to add anything, then feel free to contact me and I'll do so. I don't really want to moderate the Wikis so in general I don't want to open them up to being publicly edited.

As far as the import thing goes, I'm adding support for 120+ exchanges in the next release hopefully, so they can be imported that way. Otherwise, I'd record a few transaction of different types, then export the CSV file so you have a template of what the import feature expects, then you can just edit the CSV file if it's easier than using the Cryptofolio GUI.

Edit: Also, thank you for the compliment, it's much appreciated! :)

tandy-1000 commented 3 years ago

I see, I'll add an exception on my browser then. Fair enough, will do. Wow that's nice, what about for wallets on DeFI networks like BSC?

Xtrendence commented 3 years ago

I'm looking into that as well, I'll have to see how hard it would be to maintain. My main concern with adding too many features is that my third year of university will start in September, and I won't have much time to actively maintain the project. So my primary focus is to not add any features that could break if a 3rd party API or something were to change. I don't want people to get locked out or receive errors from the app and be forced to wait until I fix it. Of course I have to make exceptions for stuff like CoinGecko's API which powers the whole thing pretty much, but I'd like to keep external dependencies to a minimum. Thankfully, the support for exchanges is easy to do thanks to CCXT, so I'd have to see how DEX and DeFi networks provide APIs etc.

Also, if you ever want to see what features are planned or are coming with future releases, there's a project board to keep things organized. :)

tandy-1000 commented 3 years ago

That makes sense, also same about uni :). I will keep an eye out.