Ghostfolio Install
Description:
So I needed an excuse to follow the Rocky verus Alma
debate that has been going on since the Centos issue (basically instead of being a downstream disto for RHEL they are moving it upstream which will make it less stable, at least in theory) so I decided to create a server using Hyper-V and install Ghostfolio on Rocky 8 as a test. Here are my notes.
To Resolve:
-
Create VM and run the command to allow virtualization:
Set-Vmprocessor -Vmname ghostfolio -ExposeVirtualizationExtensions $True
-
Update:
sudo dnf update --refresh
-
Install EPEL:
1 2
sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm sudo dnf update --refresh
-
Install docker/git:
1 2 3
sudo dnf install -y dnf-utils git sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install -y docker-ce
- So I had an issue where when I copied the URL it pasted with a
1~
on the end so when I went to install docker it saiddocker not found
or something. - I then ran a
sudo dnf repolist
and founddownload.docker.com_linux_centos_docker-ce.repo1_.repo
in the list of repos. - So I googled
dnf remove repo
and found a bunch of links on how to disable the repo but the idea is to do something like:
1 2 3 4 5 6 7 8 9
rpm -qa |grep -i repo-name rpm -e some-repository-rpm-package # If RPM-package not found then simply remove repo file with following command: # rm /etc/yum.repos.d/repo-file.repo # so this removed the repo from the repolist rm /etc/yum.repos.d/download.docker.com_linux_centos_docker-ce.repo1_.repo
- So I ran the docker install again and this time it worked since it found the correct package from the repo.
- So I had an issue where when I copied the URL it pasted with a
-
So now that it is installed, let’s start it
sudo systemctl start docker
and enable itsudo systemctl enable docker
- verify:
sudo systemctl list-unit-files | grep docker
showsdocker.service
isenabled
- verify:
-
Add firewall rules for docker:
1 2
sudo firewall-cmd --zone=public --add-masquerade --permanent sudo firewall-cmd --reload
-
Download/install docker-compose:
1 2
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
-
Next, we add our user account to the
docker
group so we don’t have to keep usingsudo
:1 2
sudo usermod -aG docker gerry id gerry # see docker in list
-
Now we can run a test container:
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
mkdir ~/my-app cd ~/my-app mkdir src cd src vi ./simple_server.py #paste in: #!/usr/bin/env python from http.server import HTTPServer, SimpleHTTPRequestHandler def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler): """Entrypoint for python server""" server_address = ("0.0.0.0", 8000) httpd = server_class(server_address, handler_class) print("launching server...") httpd.serve_forever() if __name__ == "__main__": run() #exit # So this should start the webserver, but first let's give it a page to feed us: echo "hello from container port 8000" > a.html # now go back up a level to dockerfile directory cd .. vi dockerfile #paste in: FROM python:3.8 ENV SRC_DIR /usr/bin/src/webapp/src COPY src/* ${SRC_DIR}/ WORKDIR ${SRC_DIR} ENV PYTHONUNBUFFERED=1 CMD ["python", "simple_server.py"] # exit; See https://automationadmin.com/2020/12/docker-with-python-image for explanation of the dockerfile # this will build the docker app: docker build -t myapp . # This will spin up a container based off the build in detached mode: docker run -d -p 8000:8000 --name myapp-running myapp
-
Now we can run a second container so we can see how Docker keeps static copies of data in each container:
1 2 3 4 5 6 7 8 9 10 11
cd ./src vi a.html # change the port to 8005 # exit vi simple_server.py # change the port to 8005 # exit cd .. docker build -t myapp2 . # This will spin up a container based off the build in detached mode: docker run -d -p 8005:8005 --name myapp2-running myapp2
-
Now from another machine on the network, open up a browser and go to the URLs and you should see the two containers running on different ports:
http://192.168.10.10:8000/a.html
andhttp://192.168.10.10:8005/a.html
-
So after this what I did was practice different docker commands by spinning up containers and deleting them, viewing them, stopping them, etc.
- First, to view containers that are running, run:
docker ps
- To see all containers regardless of status:
docker ps -a
. This is important because you CANNOT reuse a container name or image name so you have to delete container or image if you want to use them again. - The longer way to view containers:
docker container ls
- To delete a container:
docker rm 4743b12994cb --force
. In this case4743b12994cb
was the container id and I used--force
because the container was running. If you stop it first you should be able to delete cleanly. You can also pass in the container name. - To stop a container:
docker stop myapp2-running
. You can usestart
andrestart
as well. - Apparently, the previous commands are shorter ways of writing out
docker container rm
ordocker container stop
ordocker container $subcommand
- First, to view containers that are running, run:
-
So containers are one thing, but another thing is
images
or builds.- First, to view images, run
docker image ls
- To delete an image:
docker image rm myapp --force
- First, to view images, run
-
Also, if you expose a container but the outside can’t reach it, it could be your host’s firewalls so you need to make sure to do the usual:
1 2
firewall-cmd --add-port=8005/tcp --permanent firewall-cmd --reload
-
As you can imagine, we have only scratched the surface of docker. See the full list of commands you can run to manage containers and play around to learn more. I will in future posts.
-
Okay, so I have a VM and I have docker, let’s get started …
-
First, let’s make a directory for our project:
mkdir ~/ghost && cd ~/ghost
-
Pull the repo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
ssh-keygen -t rsa -b 4096 -C "gerry@automationadmin.com" # Add the key to your SSH Agent for Auth: ssh-add ~/.ssh/id_rsa # Could not open a connection to your authentication agent. eval `ssh-agent -s` ssh-add -l #The agent has no identities. ssh-add ~/.ssh/id_rsa # Identity added: /home/gerry/.ssh/id_rsa (gerry@automationadmin.com) cat ~/.ssh/id_rsa.pub # Add the ssh key to your github account. # Clone the repo by the following: git clone git@github.com:ghostfolio/ghostfolio.git
- Edit the
./env
secrets:- Type:
vi ./env
, enter your secrets where it says to, save and exit.
- Type:
-
Pull the image:
docker-compose --env-file ./.env -f docker/docker-compose.yml up -d
- Running
docker container ls
shows 3 containers running: redis, postgres, and ghostfolio.
- Running
-
Setup the DB
docker-compose --env-file ./.env -f docker/docker-compose.yml exec ghostfolio yarn database:setup
-
Open
http://192.168.10.10:3333
in your browser and accomplish these steps:- Create a new user via Get Started (this first user will get the role ADMIN)
- Go to the Admin Control Panel and click Gather All Data to fetch historical data
- Click Sign out and check out the Live Demo
-
I then wrote some Powershell files to test adding transactions via REST API:
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
Function Get-GhostToken { [CmdletBinding()] Param ( [string]$AccountID ) $URL = "http://192.168.10.10:3333/api/v1/auth/anonymous/" + $AccountID $headers = @{ } $body = @{} $params = @{ "Headers" = $headers "Body" = $body "Method" = "GET" "URI" = $URL } [Net.ServicePointManager]::SecurityProtocol = "Tls12, Tls11, Tls, Ssl3" $req = Invoke-RestMethod @params return $($req.authToken) } Function Add-Record { [CmdletBinding()] Param ( [string]$AuthToken ) $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $headers.Add("Content-Type", "application/json") $headers.Add("Accept", "application/json") $headers.Add("Authorization", "Bearer $AuthToken") $bodyArray = @() $body = [ordered]@{ "currency" = "USD" "date" = "2018-05-06T00:00:00.000Z" "dataSource" = "MANUAL" "fee" = 0 "quantity" = 1 "symbol" = "VTSAX" "type" = "BUY" "unitPrice" = 50 } $bodyArray += $body $bodyJson = $bodyArray | ConvertTo-Json #Write-Verbose $bodyJson $params = @{ "Headers" = $headers "Body" = $bodyJson "Method" = "Post" "URI" = "http://192.168.10.10:3333/api/v1/order" "ContentType" = "application/json" } [Net.ServicePointManager]::SecurityProtocol = "Tls12, Tls11, Tls, Ssl3" $req = Invoke-RestMethod @params -Verbose return $req } $AccountID = "my-account-number" $Token = Get-GhostToken -AccountID $AccountID $Record = Add-Record -AuthToken $Token -Verbose Write-Output $Record
- From here, you just need to export CSV files from your financial institutions, create a powershell script to read them in using
import-csv
and then do anAdd-Record
function call with the values. I didn’t want to go this far as I just wanted a simple setup for now. Maybe will update in the future.
- From here, you just need to export CSV files from your financial institutions, create a powershell script to read them in using
Comments