Skip to main content
podman
June 24, 2024

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

  1. Create new user
1
2
3
4
useradd -m -s /bin/bash poduser
passwd poduser
# Optional for sudo privileges
usermod -aG sudo poduser
  1. 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.

  1. 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
  1. 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
  1. 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
  1. 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
  1. Reboot system to check rootless and linger
1
sudo systemctl reboot

then visit http://192.168.1.143:9000

  1. 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
  1. Sistemi yeniden başlatıp 80 numaralı porttan test ediyoruz.
1
sudo systemctl reboot

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

  1. podman machine reset
  2. podman machine init --log-level debug --now
  3. Wait for the grub menu to come up, then hit e in the 2-second window it gives you.
  4. Edit the line beginning with “linux” and append the “nopku” flag.
  5. 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