mirror of
https://codeberg.org/Mo8it/How_To_Linux.git
synced 2024-11-24 11:01:34 +00:00
Add day 4
This commit is contained in:
parent
968dd27414
commit
1cf6fc0e19
6 changed files with 271 additions and 109 deletions
|
@ -14,4 +14,6 @@
|
|||
- [Notes](day_3/notes.md)
|
||||
- [Tasks](day_3/tasks.md)
|
||||
- [Day 4](day_4/README.md)
|
||||
- [Notes](day_4/notes.md)
|
||||
- [Tasks](day_4/tasks.md)
|
||||
- [Day 5](day_5/README.md)
|
||||
|
|
|
@ -41,7 +41,7 @@ We will use the program `inotifywait`. This program can monitor a directory and
|
|||
1. After printing the script name, run the script!
|
||||
1. Save the standard output and standard error of the script into two separate files in the `logs` directory. If the name of the script is `job.sh` for example, then the output should be in the files `logs/job.sh.out` and `logs/job.sh.err`.
|
||||
|
||||
Tipps:
|
||||
##### Tipps:
|
||||
|
||||
- Take a look at the examples from the sections of this day.
|
||||
- Take care of permissions.
|
||||
|
|
|
@ -274,63 +274,3 @@ sudo firewall-cmd --add-port 80/tcp
|
|||
sudo firewall-cmd --add-port 443/tcp
|
||||
sudo firewall-cmd --runtime-to-permanent
|
||||
```
|
||||
|
||||
## Podman
|
||||
|
||||
```bash
|
||||
# Search for image
|
||||
podman search python
|
||||
|
||||
# Pull image
|
||||
podman pull docker.io/library/python:latest
|
||||
|
||||
# See pulled images
|
||||
podman images
|
||||
|
||||
# Run container and remove it afterwards
|
||||
podman run -it --rm docker.io/library/python:latest bash
|
||||
|
||||
# Create network
|
||||
podman network create NETWORKNAME
|
||||
|
||||
# Create container
|
||||
podman create \
|
||||
--name CONTAINERNAME \
|
||||
--network NETWORKNAME \
|
||||
-e ENVVAR="Some value for the demo environment variable" \
|
||||
--tz local \
|
||||
docker.io/library/python:latest
|
||||
|
||||
# Start container
|
||||
podman start CONTAINERNAME
|
||||
|
||||
# Enter a running container
|
||||
podman exec -it CONTAINERNAME bash
|
||||
|
||||
# Stop container
|
||||
podman stop CONTAINERNAME
|
||||
|
||||
# Generate systemd files
|
||||
podman generate systemd --new --files --name CONTAINERNAME
|
||||
|
||||
# Create directory for user's systemd services
|
||||
mkdir -p ~/.config/systemd/user
|
||||
|
||||
# Place service file
|
||||
mv container-CONTAINERNAME.service ~/.config/systemd/user
|
||||
|
||||
# Activate user's service (container)
|
||||
systemctl --user enable --now container-CONTAINERNAME
|
||||
```
|
||||
|
||||
Keep user's systemd services live after logging out:
|
||||
|
||||
```bash
|
||||
sudo loginctl enable-linger USERNAME
|
||||
```
|
||||
|
||||
Options:
|
||||
|
||||
- `-v`, `--volume`: `SRC_PATH:DEST_PATH:L`. Label should be one of `z`, `z,ro`, `Z` or `Z,ro`.
|
||||
- `--label "io.containers.autoupdate=registry"` for `podman auto-update`
|
||||
- `-p`, `--publish`: `SERVER_PORT:CONTAINER_PORT`
|
||||
|
|
|
@ -107,51 +107,3 @@ After that I add you public key, connect to the server using the host name that
|
|||
Use `scp` and then `rsync` to transfer the files that you did create during the course to the server `linux-lab`.
|
||||
|
||||
Do you notice any differences between the two commands?
|
||||
|
||||
## Task 5: Nextcloud
|
||||
|
||||
In this task you will deploy your own cloud on the server: Nextcloud!
|
||||
|
||||
To do so, we will install Nextcloud as a container using `podman`.
|
||||
|
||||
In this task, you should connect as the user `admin` to the server. **Don't do this task as the user that you did create in the last task!** ⚠️
|
||||
|
||||
To connect as `admin` again, change the user for the host `linux-lab` in `~/.ssh/config` back to `admin` or use `ssh admin@linux-lab` instead of only `ssh linux-lab`.
|
||||
|
||||
You can find more information about the Nextcloud container here: https://hub.docker.com/\_/nextcloud
|
||||
|
||||
Create a directory called `nextcloudN` in the home directory of the user `admin`. `N` at the end stands for the number that you are using in the url to connect to the browser terminal `ttydN.mo8it.xyz`.
|
||||
|
||||
Create a directory called `nextcloudN-db` for the database container. Replace `N` as above!
|
||||
|
||||
Create a container for the database with the following options:
|
||||
|
||||
- Container name: `nextcloudN-db`. Replace `N` as above!
|
||||
- Timezone: `local`
|
||||
- Network: `traefik`
|
||||
- Volume: Mount the directory `nextcloudN-db` that you did create into `/var/lib/postgresql/data` in the container. Use the label `Z`!
|
||||
- The following environment variables:
|
||||
- `POSTGRES_DB=nextcloud`
|
||||
- `POSTGRES_USER=nextcloud`
|
||||
- `POSTGRES_PASSWORD=DB_PASSWORD`. Replace `DB_PASSWORD` with a good password!
|
||||
- Label: `io.containers.autoupdate=registry`
|
||||
- Image: docker.io/library/postgres:alpine
|
||||
|
||||
Create the actual Nextcloud container with the following options:
|
||||
|
||||
- Container name: `nextcloudN`. `N` at the end stands for the number that you are using in the url to connect to the browser terminal `ttydN.mo8it.xyz`.
|
||||
- Timezone: `local`
|
||||
- Network: `traefik`
|
||||
- Volume: Mount the directory `nextcloudN` that you did create into `/var/www/html` in the container. Use the label `Z`!
|
||||
- The same environment variables as for the other container! Use the same `DB_PASSWORD`. Add one more environment variable:
|
||||
- `POSTGRES_HOST=nextcloudN-db`. Replace `N` as above!
|
||||
- Label: `io.containers.autoupdate=registry`
|
||||
- Image: docker.io/library/nextcloud:24-apache
|
||||
|
||||
Create the systemd files for the two containers above.
|
||||
|
||||
Move the systemd files to `~/.config/systemd/user`.
|
||||
|
||||
Enable and start the two containers as user services with `systemctl --user enable --now container-nextcloudN-db` and `systemctl --user enable --now container-nextcloudN`. Replace the `N` as above!
|
||||
|
||||
Visit [https://nextcloudN.jinext.xyz](https://nextcloudN.jinext.xyz) to see if everything did work! Replace the `N` as above!
|
||||
|
|
61
src/day_4/notes.md
Normal file
61
src/day_4/notes.md
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Notes
|
||||
|
||||
## Podman
|
||||
|
||||
```bash
|
||||
# Search for image
|
||||
podman search python
|
||||
|
||||
# Pull image
|
||||
podman pull docker.io/library/python:latest
|
||||
|
||||
# See pulled images
|
||||
podman images
|
||||
|
||||
# Run container and remove it afterwards
|
||||
podman run -it --rm docker.io/library/python:latest bash
|
||||
|
||||
# Create network
|
||||
podman network create NETWORKNAME
|
||||
|
||||
# Create container
|
||||
podman create \
|
||||
--name CONTAINERNAME \
|
||||
--network NETWORKNAME \
|
||||
-e ENVVAR="Some value for the demo environment variable" \
|
||||
--tz local \
|
||||
docker.io/library/python:latest
|
||||
|
||||
# Start container
|
||||
podman start CONTAINERNAME
|
||||
|
||||
# Enter a running container
|
||||
podman exec -it CONTAINERNAME bash
|
||||
|
||||
# Stop container
|
||||
podman stop CONTAINERNAME
|
||||
|
||||
# Generate systemd files
|
||||
podman generate systemd --new --files --name CONTAINERNAME
|
||||
|
||||
# Create directory for user's systemd services
|
||||
mkdir -p ~/.config/systemd/user
|
||||
|
||||
# Place service file
|
||||
mv container-CONTAINERNAME.service ~/.config/systemd/user
|
||||
|
||||
# Activate user's service (container)
|
||||
systemctl --user enable --now container-CONTAINERNAME
|
||||
```
|
||||
|
||||
Keep user's systemd services live after logging out:
|
||||
|
||||
```bash
|
||||
sudo loginctl enable-linger USERNAME
|
||||
```
|
||||
|
||||
Options:
|
||||
|
||||
- `-v`, `--volume`: `SRC_PATH:DEST_PATH:L`. Label should be one of `z`, `z,ro`, `Z` or `Z,ro`.
|
||||
- `--label "io.containers.autoupdate=registry"` for `podman auto-update`
|
||||
- `-p`, `--publish`: `SERVER_PORT:CONTAINER_PORT`
|
207
src/day_4/tasks.md
Normal file
207
src/day_4/tasks.md
Normal file
|
@ -0,0 +1,207 @@
|
|||
# Tasks
|
||||
|
||||
## Compilation in containers
|
||||
|
||||
> 📍 : This task should be done on the Contabo server after connecting with SSH to the user that you did create yesterday on the server (not admin).
|
||||
|
||||
We want to practice compilation and containers, so lets compile in a container!
|
||||
|
||||
In this task, we want to compile the program `tmate`.
|
||||
|
||||
1. Start an Ubuntu container with `podman run -it --rm --name tmate-compiler ubuntu:latest bash`.
|
||||
1. Go to the [website of `tmate`](https://tmate.io/) and find out how to compile from source (there are intructions for compiling on Ubuntu).
|
||||
1. Follow the compilation instructions in the container.
|
||||
1. After compilation, you will find the binary `tmate` in the directory of the git repository.
|
||||
1. Don't exit the container yet, otherwise you will lose what you have done in it. Now open a new terminal (tab) and copy the binary `tmate` from the container to the directory `bin` in your home directory. Use the command `podman cp CONTAINERNAME:SRC_PATH DESTINATION_PATH`.
|
||||
1. Verify that the binary `tmate` was copied to `DESTINATION_PATH` and then exit the container in the first terminal (tab).
|
||||
|
||||
Now write a script called `compile_tmate.sh` that automates what you have done in the container to compile `tmate`. Just copy all the commands that you used in the container to a script.
|
||||
|
||||
Add to the end of the script `mv PATH_TO_TMATE_BINARY_IN_CONTAINER /volumes/bin` to copy the binary to the directory `/volumes/bin` after compilation.
|
||||
|
||||
Create a directory called `scripts` and put the script in it.
|
||||
|
||||
Now write a second script in the parent directory of the directory `scripts`. The second script should automate creating the container that runs the first script.
|
||||
|
||||
Do the following in the second script:
|
||||
|
||||
1. Check if `scripts/compile_tmate.sh` does NOT exist. In this case you should print a useful message that explains why the script terminates and then exit with error code 1.
|
||||
1. Make sure that `scripts/compile_tmate.sh` is executable for the user.
|
||||
1. Create a directory called `bin` (next to the directory `scripts`) if it does not already exist.
|
||||
1. Use the following snippet:
|
||||
|
||||
```bash
|
||||
podman run -it --rm \
|
||||
--name tmate-compiler \
|
||||
-v ./scripts:/volumes/scripts:Z,ro \
|
||||
-v ./bin:/volumes/bin:Z \
|
||||
docker.io/library/ubuntu:latest \
|
||||
/volumes/scripts/compile_tmate.sh
|
||||
```
|
||||
|
||||
It creates a container that runs the script `compile_tmate.sh` and is removed afterwards (because of `--rm`).
|
||||
|
||||
The `scripts` directory is mounted to be able to give the container access to the script `compile_tmate.sh`. The directory is mounted as _read only_ (`ro`) because it will not be modified.
|
||||
|
||||
The `bin` directory is mounted to be able to trasfer the binary into it before the container exits.
|
||||
|
||||
After running the second script, you should see the container compiling and then exiting. At the end, you should find the binary `tmate` in the `bin` directory.
|
||||
|
||||
Now that you have the program `tmate`, find out what it does! Try it with a second person.
|
||||
|
||||
##### Tipps:
|
||||
|
||||
- On debain based distributions like Ubuntu, the package manager is `apt`. Before that you can install any packages with `apt`, you have to run `apt update`. This does not run system updates like `dnf upgrade`. `apt update` does only synchronize the repositories which is needed before installations.
|
||||
- Test if a file exists in bash:
|
||||
|
||||
```bash
|
||||
if [ -f FILE_PATH ]
|
||||
then
|
||||
(...)
|
||||
fi
|
||||
```
|
||||
|
||||
Replace `(...)` with your code. For more information on the option `-f` and other useful options for bash conditions, read the man page of the program `test`: `man test`.
|
||||
|
||||
To test if a file does NOT exist, replace `-f` with `! -f`.
|
||||
- Exit a bash script with error code 1:
|
||||
```bash
|
||||
exit 1
|
||||
```
|
||||
|
||||
## Task: Static website
|
||||
|
||||
> 📍 : In this task, you should connect as the user `admin` to the Contabo server. **Don't do this task as the user that you did create on the server!** ⚠️
|
||||
|
||||
> 📍 : Starting with this task: Asking you to replace `N` means to enter the number that you are using in the URL `ttydN.mo8it.xyz`.
|
||||
|
||||
In this task, you will host a static website which is a website that does not have a backend. A static website is just a set of HTML, CSS (and optionally JavaScript) files.
|
||||
|
||||
To host the website, we need a web server. In this task, we will use the Nginx web server.
|
||||
|
||||
Create a directory `~/nginxN` (replace `N`) with two directories in it: `website` and `conf`.
|
||||
|
||||
Place these two files:
|
||||
|
||||
1. `~/nginxN/conf/nginxN.jinext.xyz.conf` (replace `N`):
|
||||
|
||||
```
|
||||
server {
|
||||
listen 80;
|
||||
server_name nginx0.jinext.xyz;
|
||||
|
||||
location / {
|
||||
root /volumes/website;
|
||||
index index.html;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. `~/nginxN/website/index.html` (replace `N`):
|
||||
|
||||
```
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Demo</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello world!</h1>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Create a Nginx container with the following options:
|
||||
|
||||
- Name: `nginxN`. Replace `N`!
|
||||
- Timezone `tz`: `local`.
|
||||
- Network: `traefik`.
|
||||
- Volumes:
|
||||
- `~/nginx0/website:/volumes/website` with labels `Z,ro`.
|
||||
- `~/nginx0/conf:/etc/nginx/conf.d` with labels `Z,ro`.
|
||||
- Label: `io.containers.autoupdate=registry`
|
||||
- Image: `docker.io/library/nginx:alpine`
|
||||
|
||||
Create the systemd file for the container above.
|
||||
|
||||
Move the systemd file to `~/.config/systemd/user`.
|
||||
|
||||
Enable and start the container as user services with `systemctl --user enable --now container-nginxN`. Replace `N`!
|
||||
|
||||
Visit [https://nginxN.jinext.xyz](https://nginxN.jinext.xyz) to see if everything did work! Replace `N`!
|
||||
|
||||
Now, you can edit `index.html` and add your own HTML content.
|
||||
|
||||
You can also add more files to the directory `website`. If you add a file `test.html` for example, then you should see it under [https://nginxN.jinext.xyz/test](https://nginxN.jinext.xyz/test).
|
||||
|
||||
## Task: Nextcloud
|
||||
|
||||
> 📍 : In this task, you should connect as the user `admin` to the Contabo server. **Don't do this task as the user that you did create on the server!** ⚠️
|
||||
|
||||
In this task you will deploy your own cloud on the server: Nextcloud!
|
||||
|
||||
To do so, we will install Nextcloud as a container using `podman`.
|
||||
|
||||
To connect as `admin` again, change the user for the host `linux-lab` in `~/.ssh/config` back to `admin` or use `ssh admin@linux-lab` instead of only `ssh linux-lab`.
|
||||
|
||||
You can find more information about the Nextcloud container here: https://hub.docker.com/\_/nextcloud
|
||||
|
||||
Create a directory called `nextcloudN` (replace `N`) in the home directory of the user `admin`.
|
||||
|
||||
Create a directory called `nextcloudN-db` (replace `N`) for the database container.
|
||||
|
||||
Create a container for the database with the following options:
|
||||
|
||||
- Container name: `nextcloudN-db`. Replace `N`!
|
||||
- Timezone `tz`: `local`
|
||||
- Network: `traefik`
|
||||
- Volume: Mount the directory `nextcloudN-db` (replace `N`) that you did create into `/var/lib/postgresql/data` in the container. Use the label `Z`!
|
||||
- The following environment variables:
|
||||
- `POSTGRES_DB=nextcloud`
|
||||
- `POSTGRES_USER=nextcloud`
|
||||
- `POSTGRES_PASSWORD=DB_PASSWORD`. Replace `DB_PASSWORD` with a good password!
|
||||
- Label: `io.containers.autoupdate=registry`
|
||||
- Image: `docker.io/library/postgres:alpine`
|
||||
|
||||
Create the actual Nextcloud container with the following options:
|
||||
|
||||
- Container name: `nextcloudN`. `N` at the end stands for the number that you are using in the url to connect to the browser terminal `ttydN.mo8it.xyz`.
|
||||
- Timezone `tz`: `local`
|
||||
- Network: `traefik`
|
||||
- Volume: Mount the directory `nextcloudN` that you did create into `/var/www/html` in the container. Use the label `Z`!
|
||||
- The same environment variables as for the other container! Use the same `DB_PASSWORD`. Add one more environment variable:
|
||||
- `POSTGRES_HOST=nextcloudN-db`. Replace `N`!
|
||||
- Label: `io.containers.autoupdate=registry`
|
||||
- Image: `docker.io/library/nextcloud:24-apache`
|
||||
|
||||
Create the systemd files for the two containers above.
|
||||
|
||||
Move the systemd files to `~/.config/systemd/user`.
|
||||
|
||||
Enable and start the two containers as user services with `systemctl --user enable --now container-nextcloudN-db` and `systemctl --user enable --now container-nextcloudN`. Replace `N`!
|
||||
|
||||
Visit [https://nextcloudN.jinext.xyz](https://nextcloudN.jinext.xyz) to see if everything did work! Replace `N`!
|
||||
|
||||
## Task: Vim game
|
||||
|
||||
In this task, we are going to play a game! 🎮️
|
||||
|
||||
The game is an educational game that lets you learn the very basics of the navigation in Vim/Neovim.
|
||||
|
||||
Play the game on this website: [https://vim-adventures.com](https://vim-adventures.com/)
|
||||
|
||||
## Task: Nvim macros
|
||||
|
||||
In this task, we will learn about the power of macros in Neovim.
|
||||
|
||||
1. Visit [this URL](https://www.randomlists.com/random-names?qty=500), select the generated 500 names with the mouse and copy them.
|
||||
1. Create a new text file and open it with `nvim`.
|
||||
1. Paste the names into the file. You should see 500 lines with a name in each line.
|
||||
1. Record a macro that changes a line in the form `FIRST_NAME LAST_NAME` to `("FIRST_NAME", "LAST_NAME"),`.
|
||||
1. Run the macro on all lines.
|
||||
1. Now go to the beginning of the file (`gg`) and add this line as a first line: `names = [`
|
||||
1. Go to the end of the file (`G`) and add this line as last line: `]`
|
||||
|
||||
Congratulations, you did just convert the names into a form that could be directly used by a Python program! It is a list of tuples now.
|
Loading…
Reference in a new issue