Usage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| brew install podman
podman info
podman machine init
podman machine init --rootful
podman machine init -m 4096 --disk-size 150
podman machine init --cpus 8 --memory 16384 --disk-size 60 --image=docker://quay.io/podman/machine-os:5.7
podman machine set --memory 4096
podman machine start
podman machine start --log-level debug
podman machine ls
podman machine ls | detect columns
podman machine ls | detect columns | select NAME
podman search redis | detect columns
podman search redis --filter=is-official
podman run -d -p 8080:80 docker.io/library/nginx
podman ps -q
podman kill CONTAINER_ID_OR_NAME
|
Rootless
- Create new user
1
2
3
4
| useradd -m -s /bin/bash poduser
passwd poduser
# Optional for sudo privileges
usermod -aG sudo poduser
|
- Switch to new user
Bundan sonra systemctl --user olarak kullanacağız. Bu nedenle sudo veya su - poduser çalışmayacak.
Çalışması için çıkış yapıp ssh/konsol üzerinden oluşturduğumuz kullanıcı ile yeniden giriş yapmamız gerekiyor.
- Podman rootless test
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| podman pull nginx:latest
podman inspect nginx:latest | grep uid
mkdir nginx-data
podman unshare chown -R 101:101 nginx-data/
sudo vim nginx-data/index.html (add some html content)
podman run -d --name web -p 9000:80 -v /home/poduser/nginx-data:/usr/share/nginx/html:Z nginx
#to get ip address
ss -plant
ip a
#open the port
sudo firewall-cmd --add-port=9000/tcp --permanent
sudo firewall-cmd --reload
#visit http://192.168.1.143:9000
|
- systemd settings
1
2
3
| mkdir -p ~/.config/systemd/user && cd ~/.config/systemd/user
podman generate systemd --name web --files --new
ls # we will have the container-web.service
|
- Linger settings
SSH logout sonrası container’ların ölmemesi için Linger’ı açacağız.
1
2
3
| loginctl show-user poduser | grep Linger # Linger=no
loginctl enable-linger poduser
loginctl show-user poduser | grep Linger # Linger=yes
|
- systemctl
1
2
3
4
5
6
| #Tüm dosyalarımızı yeniden yüklemek için
systemctl --user daemon-reload
#container-web.service için
systemctl --user enable container-web.service
systemctl --user start container-web.service
systemctl --user status container-web.service
|
- Reboot system to check rootless and linger
then visit http://192.168.1.143:9000
- Port 80/443
80/443 numaralı portlardan yanıt almak istiyoruz. Rootless user 1024 altı portlara bind edemez. Root olarak şunlar yapılacak.
8a. Nginx settings
1
2
3
4
5
| apt install nginx
systemctl enable --now nginx.service
systemctl status nginx.service
vim /etc/nginx/conf.d/web.conf # paste the following
nginx -s reload
|
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
| # Redirect all HTTP traffic to HTTPS
server {
listen 80;
server_name 192.168.1.143 example.com www.example.com;
# Redirect to HTTPS
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443 ssl http2;
server_name 192.168.1.143 example.com www.example.com;
# SSL configuration
ssl_certificate /etc/nginx/ssl/example.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
# Recommended SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers HIGH:!aNULL:!MD5;
# Root directory
root /var/www/html;
index index.html index.htm;
# Logs
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Main location block
location / {
try_files $uri $uri/ =404;
}
# Example: reverse proxy to backend app (e.g., Node.js, Java, etc.)
location /api/ {
proxy_pass http://192.168.1.143:9000/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Optional: gzip compression
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}
|
8b. Firewall settings
Nginx proxy ile 80->9000 yönlendirmesi yaptığımız için 9000 numaralı porta artık ihtiyacımız yok, kaldırabiliriz.
1
2
| firewall-cmd --list-all
firewall-cmd --remove-port=9000/tcp --permanent
|
8c. http ve https servislerini açıyoruz
1
2
3
4
| firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent
firewall-cmd --reload
firewall-cmd --list-all | grep services # http ve https trafiğini kabul ediyor artık
|
- Sistemi yeniden başlatıp 80 numaralı porttan test ediyoruz.
then visit http://192.168.1.143
Quadlet
Quadlet configuration files are used to define containers, volumes, or networks. These files are stored in ~/.config/containers/systemd/ for user-level configurations (rootless) or /etc/containers/systemd/ for system-wide configurations (rootful).
Configuring the Host
systemd
1
2
3
| loginctl enable-linger <rootless_containers_user>
# Check if linger is enabled
loginctl show-user <rootless_containers_user> | grep Linger
|
If linger is not enabled, systemd will stop a user’s processes when the user logs out.
sysctl
1
| sysctl net.ipv4.ip_unprivileged_port_start=<rootless_port_start>
|
If ports are needed, such as 80 or 22, sysctl needs to know that unprivileged users can use these ports. This is a security feature to prevent unprivileged users from using ports below 1024.
You can modify the net.ipv4.ip_unprivileged_port_start sysctl to change the lowest port. For example sysctl net.ipv4.ip_unprivileged_port_start=443 allows rootless Podman containers to bind to ports >= 443.
Generate and Manage the Systemd Service
After creating the Quadlet configuration file, you need to reload systemd and start the service:
You can remove --user flag if you are using rootful podman machine.
1
2
3
4
5
6
7
8
9
10
11
| # Reload systemd
systemctl --user daemon-reload
# Start the service
systemctl --user start nginx.container
# Check the status of the service
systemctl --user status nginx.container
# Enable the service on Boot
systemctl --user enable nginx.container
|
Troubleshooting
1
| /usr/lib/systemd/system-generators/podman-system-generator --user --dryrun
|
This systemd command checks the Quadlet files for syntax. If successful, it will generate systemd units for the containers defined in the Quadlet configuration files. If it fails, it will print the errors to the console.
Errors
podman push image got Error: unexpected EOF
For full debug logs
1
2
| podman machine ssh
podman push registry.gitlab.com/[GROUP]/[PROJECT] --log-level debug
|
The memory usage during a push is more than the default installation. Increase VM memory to 4GB.
If you want to create a new podman machine
1
2
3
4
| podman machine stop
podman machine rm
podman machine init -m 4096
podman machine start
|
If you want to modify existing podman machine
1
2
3
| podman machine stop
podman machine set --memory 4096
podman machine start
|
podman machine start hangs on MacOS Intel (x86_64)
https://github.com/containers/podman/issues/25121#issuecomment-2764487184
podman machine resetpodman machine init --log-level debug --now- Wait for the grub menu to come up, then hit
e in the 2-second window it gives you. - Edit the line beginning with “
linux” and append the “nopku” flag. - Ctrl-X to boot.
https://github.com/containers/podman/issues/25121#issuecomment-2653583685
As a temporary workaround, switch to using the image version 5.7, which is functioning properly on my Intel-based MacOS:
To create a rootful machine
1
| podman machine init --rootful
|
Optional resources:
1
| podman machine init --rootful --cpus 4 --memory 4096 --disk-size 50 --image=docker://quay.io/podman/machine-os:5.7
|