# Docker commands

## Local

Docker commands to create the local containers.

`docker build -t pa4kev/portfolio-reactjs-full:latest -f Dockerfile . && docker push pa4kev/portfolio-reactjs-full:latest`

## Server (Enaga)

### GNU/Linux

* Create user, set password, set shell and add to sudo group.

`useradd -m <user>`

`passwd <user>`

`chsh -s /bin/bash <user>`

`adduser <user> sudo`

* Then create an `.ssh` folder for `<user>` in the home folder and create a file called `authorized_keys` as the public key on the local machine. Then copy the contents of the public key to the new file.

* Update the hostname.

`hostnamectl set-hostname enaga`

`vim /etc/hosts`

* [Install docker](https://docs.docker.com/engine/install/debian/#install-using-the-convenience-script)

* Allow docker to be run without sudo commands. (Log out and back in later)

`sudo gpasswd -a $USER docker`

* Install Nginx

`sudo apt-get update`

`sudo apt-get install nginx`

* Copy the nginx configuration file with `scp` to the server.

* Move the nginx configuration file to: `sites-available`.

`sudo mv matsubara.nl /etc/nginx/sites-available/matsubara.nl`

* Create a symbolic link to: `sites-enabled`.

`sudo ln -s /etc/nginx/sites-available/matsubara.nl matsubara.nl`

* Now the certificates need to be created, these are already used by the configuration file, so you cannot restart nginx at this moment. Run the related `docker` commands first to create the certificates. Make sure that the DNS points to the correct IP address before creating the certificates.

### Docker

To no longer require `sudo` for docker, use:

`sudo groupadd docker`

`sudo gpasswd -a $USER docker`

### Docker network

You can create a custom [network](https://docs.docker.com/reference/cli/docker/network/). Note that docker already has some default network called **bridge** that you can use. But note that DNS [host name resolving](https://forums.docker.com/t/cant-resolve-docker-container-names-have-to-use-docker-ip-address/138753) only works on custom networks.

* To list all networks:

`docker network ls`

* Create a custom network:

`docker network create -d bridge uguisu`

* To add an existing container to a network:

`docker network connect uguisu container-name`

* Or specify in the run command:

`docker run --network=uguisu`

* Inspect a network with:

`docker inspect uguisu`

* Inspect which networks are connected to a container:

`docker inspect container-name | grep "Network"`

### Postgres database

* Create a [postgres database container](https://hub.docker.com/_/postgres).

`docker run -d --name database -e POSTGRES_USER=gitea -e POSTGRES_PASSWORD=password -e POSTGRES_DB=gitea -v ./volume-postgres:/var/lib/postgresql/data postgres:17.4-bookworm`

* Import the database SQL export file. [Copy](https://docs.docker.com/reference/cli/docker/container/cp/) the backup file to the container and then run **psql** to import it.

`docker cp backup.sql database:/backup.sql`

`docker exec -it database bash`

`psql --username=gitea gitea < backup.sql`

### Website containers

`docker pull pa4kev/portfolio-reactjs-full`

if required, run certbot to set the certificates.

* First stop Nginx, as it is using port 80

`sudo systemctl stop nginx.service`

* Run this container, I doubt that i am understanding how it works properly though.

`docker run -it --rm -p 80:80 --name certbot -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/certbot certonly --standalone --break-my-certs -d matsubara.nl -d www.matsubara.nl -d pa4kev.nl -d www.pa4kev.nl -d michelaben.nl -d www.michelaben.nl -d gitea.matsubara.nl -d hakyll.matsubara.nl -d hvwocomhelmond.nl -d www.hvwocomhelmond.nl`

`docker run -it --rm --name certbot --net webproxy -v $(pwd)/letsencrypt:/etc/letsencrypt -v $(pwd)/letsencrypt-lib:/var/lib/letsencrypt certbot/certbot certonly --standalone --preferred-challenges http -d matsubara.nl -d www.matsubara.nl -d pa4kev.nl -d www.pa4kev.nl -d michelaben.nl -d www.michelaben.nl -d gitea.matsubara.nl -d hakyll.matsubara.nl -d hvwocomhelmond.nl -d www.hvwocomhelmond.nl`

* Start Nginx again.

`sudo systemctl start nginx.service`

* Run the portfolio container.

`docker run -t -d --name react -p 8080:80 -v /var/www/html:/var/www/html pa4kev/portfolio-reactjs-full`

* `-t` foreground mode
* `-d` detached mode

### Hakyll site

#### Commands:

Inside `~/projecten/websites/portfolio/portfolio`:

`cabal new-run site rebuild`

`cabal new-run site watch`

#### Local:

`docker build -t pa4kev/portfolio-hakyll:latest -f Dockerfile . && docker push pa4kev/portfolio-hakyll:latest`

#### Server:

`docker pull pa4kev/portfolio-hakyll`

`docker run -t -d --name hakyll -p 8081:80 pa4kev/portfolio-hakyll`

### Icon

* [How to convert a square SVG to all-size ICO?](https://graphicdesign.stackexchange.com/questions/77359/how-to-convert-a-square-svg-to-all-size-ico)

`inkscape -w 16 -h 16 -o 16.png master.svg`
`inkscape -w 32 -h 32 -o 32.png master.svg`
`inkscape -w 48 -h 48 -o 48.png master.svg`

`sudo apt-get install imagemagick`

`convert 16.png 32.png 48.png icon.ico`

## Nginx

`sudo vim /etc/nginx/sites-available/matsubara.nl`

`sudo nginx -t`

`sudo systemctl reload nginx`

## Gitea

* Run the [Gitea container](https://hub.docker.com/r/gitea/gitea).

`docker run -d --name gitea --network=uguisu -p 3000:3000 -p 222:22 -v ./gitea:/data -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro gitea/gitea:1.23.5`

* Adjust settings for gitea.

`docker exec -it gitea bash`

`vi ./data/gitea/conf/app.ini`

* Applied this setting. See also: [Gitea config cheatsheet](https://docs.gitea.com/next/administration/config-cheat-sheet)

`DISABLE_REGISTRATION = true`

* Then restart the container.

`docker container restart gitea`

## VS Code User Snippets

[VS Code user snippets](https://code.visualstudio.com/docs/editing/userdefinedsnippets)

File > Preferences > Configure Snippets

```JSON
"Responsive figure block": {
    "scope": "html, markdown",
    "prefix": "fig",
    "body": [
      "<figure class=\"text-center\">",
      "  <picture class=\"d-flex justify-content-center\">",
      "    <source media=\"(max-width: 510px)\"",
      "     srcset=\"${1:base}-w240.webp\" />",
      "    <source media=\"(max-width: 850px)\"",
      "     srcset=\"${1:base}-w480.webp\" />",
      "    <img src=\"${1:base}-w800.webp\"",
      "         alt=\"${2:caption}\"",
      "         class=\"img-fluid\" />",
      "  </picture>",
      "  <figcaption class=\"figure-caption mt-2\">",
      "    <a href=\"${1:base}-w800.webp\">",
      "    ${2:caption}</a>",
      "    </a>",
      "  </figcaption>",
      "</figure>"
    ],
    "description": "Insert responsive figure"
  }
```

## React

Bootstrap: `npm install bootstrap`

Routing: `npm install react-router-dom`

Dark mode: [https://www.makeuseof.com/how-to-add-dark-mode-to-a-react-application/](https://www.makeuseof.com/how-to-add-dark-mode-to-a-react-application/)

Emoji component: [https://medium.com/@seanmcp/%EF%B8%8F-how-to-use-emojis-in-react-d23bbf608bf7](https://medium.com/@seanmcp/%EF%B8%8F-how-to-use-emojis-in-react-d23bbf608bf7)

HTML parsing: `npm install html-react-parser`

Markdown to JSX documentation:
* https://github.com/quantizor/markdown-to-jsx
* https://markdown-to-jsx.quantizor.dev/

Markdown to JSX install: `npm install markdown-to-jsx`

https://www.npmjs.com/package/html-react-parser

Convert SVG to React component: https://svg2jsx.com/

Syntax highlighting: `npm install react-syntax-highlighter`

[react-syntax-highlighter documentation](https://www.npmjs.com/package/react-syntax-highlighter)

## Node

List outdated packages: `npm outdated`

Update all dependancies: `npm update`

## Elm

`elm init`

`npm init -y`

`elm install mdgriffith/elm-ui`

`elm install elm-community/random-extra`

Add to `package.json`
```
"scripts": {
    "dev": "elm-live src/Main.elm -- --debug --output=index.js",
},
"devDependencies": {
    "elm-live": "^4.0.2"
}
```

`npm install`

You can now run for development:
`npm run dev`

`elm make src/Main.elm --output=index.js`

## Haskell

`cabal init --interactive`

`cabal update`

`cabal new-install hakyll`

Add hakyll to `.cabal` file, then build it: `cabal build`.

`~/.local/bin/hakyll-init portfolio`

Inside the `portfolio` directory:

* `cabal new-install`

* `cabal new-run site <command>`, `build` or `watch`


## Documentation

[Create React App](https://github.com/facebook/create-react-app)

[React documentation](https://reactjs.org/)

[Boostrap 5.2 documentation](https://getbootstrap.com/docs/5.2/getting-started/introduction/)

[MySqlConnector documentation](https://mysqlconnector.net/tutorials/connect-to-mysql/)

[connectionstrings.com](https://www.connectionstrings.com/mysql-connector-net-mysqlconnection/)

[Giraffe F# web framework](https://github.com/giraffe-fsharp/Giraffe)

[Docker hub - Node](https://hub.docker.com/_/node/)

[Docker hub - Nginx](https://hub.docker.com/_/nginx)

---

### Code Splitting

This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)

### Analyzing the Bundle Size

This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)

### Making a Progressive Web App

This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)

### Advanced Configuration

This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)

### Deployment

This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)

### `npm run build` fails to minify

This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
