用 Podman Compose 管理容器
Podman 容器
![](/data/attachment/album/202102/16/222143wch1jx781x4ec47w.jpg)


容器很棒，让你可以将你的应用连同其依赖项一起打包，并在任何地方运行。从 2013 年的 Docker 开始，容器已经让软件开发者的生活变得更加轻松。


Docker 的一个缺点是它有一个中央守护进程，它以 root 用户的身份运行，这对安全有影响。但这正是 Podman 的用武之地。Podman 是一个 [无守护进程容器引擎](https://podman.io)，用于开发、管理和在你的 Linux 系统上以 root 或无 root 模式运行 OCI 容器。


下面这些文章可以用来了解更多关于 Podman 的信息：


* [使用 Podman 以非 root 用户身份运行 Linux 容器](/article-10156-1.html)
* [在 Fedora 上使用 Podman 的 Pod](https://fedoramagazine.org/podman-pods-fedora-containers/)
* [在 Fedora 中结合权能使用 Podman](/article-12859-1.html)


如果你使用过 Docker，你很可能也知道 Docker Compose，它是一个用于编排多个可能相互依赖的容器的工具。要了解更多关于 Docker Compose 的信息，请看它的[文档](https://docs.docker.com/compose/)。


### 什么是 Podman Compose？


[Podman Compose](https://github.com/containers/podman-compose) 项目的目标是作为 Docker Compose 的替代品，而不需要对 docker-compose.yaml 文件进行任何修改。由于 Podman Compose 使用<ruby> 吊舱 <rt>  pod </rt></ruby> 工作，所以最好看下“吊舱”的最新定义。



> 
> 一个“<ruby> 吊舱 <rt>  pod </rt></ruby> ”（如一群鲸鱼或豌豆荚）是由一个或多个[容器](https://kubernetes.io/docs/concepts/containers/)组成的组，具有共享的存储/网络资源，以及如何运行容器的规范。
> 
> 
> [Pods - Kubernetes 文档](https://kubernetes.io/docs/concepts/workloads/pods/)
> 
> 
> 


（LCTT 译注：容器技术领域大量使用了航海比喻，pod 一词，意为“豆荚”，在航海领域指“吊舱” —— 均指盛装多个物品的容器。常不翻译，考虑前后文，可译做“吊舱”。）


Podman Compose 的基本思想是，它选中 `docker-compose.yaml` 文件里面定义的服务，为每个服务创建一个容器。Docker Compose 和 Podman Compose 的一个主要区别是，Podman Compose 将整个项目的容器添加到一个单一的吊舱中，而且所有的容器共享同一个网络。如你在例子中看到的，在创建容器时使用 `--add-host` 标志，它甚至用和 Docker Compose 一样的方式命名容器。


### 安装


Podman Compose 的完整安装说明可以在[项目页面](https://github.com/containers/podman-compose)上找到，它有几种方法。要安装最新的开发版本，使用以下命令：



```
pip3 install https://github.com/containers/podman-compose/archive/devel.tar.gz

```

确保你也安装了 [Podman](https://podman.io/getting-started/installation)，因为你也需要它。在 Fedora 上，使用下面的命令来安装Podman：



```
sudo dnf install podman

```

### 例子：用 Podman Compose 启动一个 WordPress 网站


想象一下，你的 `docker-compose.yaml` 文件在一个叫 `wpsite` 的文件夹里。一个典型的 WordPress 网站的 `docker-compose.yaml` （或 `docker-compose.yml`） 文件是这样的：



```
version: "3.8"
services:
  web:
    image: wordpress
    restart: always
    volumes:
      - wordpress:/var/www/html
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: magazine
      WORDPRESS_DB_NAME: magazine
      WORDPRESS_DB_PASSWORD: 1maGazine!
      WORDPRESS_TABLE_PREFIX: cz
      WORDPRESS_DEBUG: 0
    depends_on:
      - db
    networks:
      - wpnet
  db:
    image: mariadb:10.5
    restart: always
    ports:
      - 6603:3306

    volumes:
      - wpdbvol:/var/lib/mysql

    environment:
      MYSQL_DATABASE: magazine
      MYSQL_USER: magazine
      MYSQL_PASSWORD: 1maGazine!
      MYSQL_ROOT_PASSWORD: 1maGazine!
    networks:
      - wpnet
volumes:
  wordpress: {}
  wpdbvol: {}

networks:
  wpnet: {}

```

如果你用过 Docker，你就会知道你可运行 `docker-compose up` 来启动这些服务。Docker Compose 会创建两个名为 `wpsite_web_1` 和 `wpsite_db_1` 的容器，并将它们连接到一个名为 `wpsite_wpnet` 的网络。


现在，看看当你在项目目录下运行 `podman-compose up` 时会发生什么。首先，一个以执行命令的目录命名的吊舱被创建。接下来，它寻找 YAML 文件中定义的任何名称的卷，如果它们不存在，就创建卷。然后，在 YAML 文件的 `services` 部分列出的每个服务都会创建一个容器，并添加到吊舱中。


容器的命名与 Docker Compose 类似。例如，为你的 web 服务创建一个名为 `wpsite_web_1` 的容器。Podman Compose 还为每个命名的容器添加了 `localhost` 别名。之后，容器仍然可以通过名字互相解析，尽管它们并不像 Docker 那样在一个桥接网络上。要做到这一点，使用选项 `-add-host`。例如，`-add-host web:localhost`。


请注意，`docker-compose.yaml` 包含了一个从主机 8080 端口到容器 80 端口的 Web 服务的端口转发。现在你应该可以通过浏览器访问新 WordPress 实例，地址为 `http://localhost:8080`。


![WordPress Dashboard](/data/attachment/album/202102/16/222143atcbb6hh8e77h7cl.png)


### 控制 pod 和容器


要查看正在运行的容器，使用 `podman ps`，它可以显示 web 和数据库容器以及吊舱中的基础设施容器。



```
CONTAINER ID  IMAGE                               COMMAND               CREATED      STATUS          PORTS                                         NAMES
a364a8d7cec7  docker.io/library/wordpress:latest  apache2-foregroun...  2 hours ago  Up 2 hours ago  0.0.0.0:8080-&amp;gt;80/tcp, 0.0.0.0:6603-&amp;gt;3306/tcp  wpsite_web_1
c447024aa104  docker.io/library/mariadb:10.5      mysqld                2 hours ago  Up 2 hours ago  0.0.0.0:8080-&amp;gt;80/tcp, 0.0.0.0:6603-&amp;gt;3306/tcp  wpsite_db_1
12b1e3418e3e  k8s.gcr.io/pause:3.2

```

你也可以验证 Podman 已经为这个项目创建了一个吊舱，以你执行命令的文件夹命名。



```
POD ID        NAME             STATUS    CREATED      INFRA ID      # OF CONTAINERS
8a08a3a7773e  wpsite           Degraded  2 hours ago  12b1e3418e3e  3

```

要停止容器，在另一个命令窗口中输入以下命令：



```
podman-compose down

```

你也可以通过停止和删除吊舱来实现。这实质上是停止并移除所有的容器，然后再删除包含的吊舱。所以，同样的事情也可以通过这些命令来实现：



```
podman pod stop podname
podman pod rm podname

```

请注意，这不会删除你在 `docker-compose.yaml` 中定义的卷。所以，你的 WordPress 网站的状态被保存下来了，你可以通过运行这个命令来恢复它。



```
podman-compose up

```

总之，如果你是一个 Podman 粉丝，并且用 Podman 做容器工作，你可以使用 Podman Compose 来管理你的开发和生产中的容器。




---


via: <https://fedoramagazine.org/manage-containers-with-podman-compose/>


作者：[Mehdi Haghgoo](https://fedoramagazine.org/author/powergame/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
Containers are awesome, allowing you to package your application along with its dependencies and run it anywhere. Starting with Docker in 2013, containers have been making the lives of software developers much easier.

One of the downsides of Docker is it has a central daemon that runs as the root user, and this has security implications. But this is where Podman comes in handy. Podman is a [daemonless container engine](https://podman.io) for developing, managing, and running OCI Containers on your Linux system in root or rootless mode.

There are other articles on Fedora Magazine you can use to learn more about Podman. Two examples follow:

If you have worked with Docker, chances are you also know about Docker Compose, which is a tool for orchestrating several containers that might be interdependent. To learn more about Docker Compose see its [documentation](https://docs.docker.com/compose/).

## What is Podman Compose?

[Podman Compose](https://github.com/containers/podman-compose) is a project whose goal is to be used as an alternative to Docker Compose without needing any changes to be made in the docker-compose.yaml file. Since Podman Compose works using pods, it’s good to check a refresher definition of a pod.

A

Pod(as in a pod of whales or pea pod) is a group of one or more[containers], with shared storage/network resources, and a specification for how to run the containers.[Pods – Kubernetes Documentation]

The basic idea behind Podman Compose is that it picks the services defined inside the *docker-compose.yaml* file and creates a container for each service. A major difference between Docker Compose and Podman Compose is that Podman Compose adds the containers to a single pod for the whole project, and all the containers share the same network. It even names the containers the same way Docker Compose does, using the *‐‐add-host* flag when creating the containers, as you will see in the example.

## Installation

Complete install instructions for Podman Compose are found on its [project page](https://github.com/containers/podman-compose), and there are several ways to do it. To install the latest development version, use the following command:

pip3 install https://github.com/containers/podman-compose/archive/devel.tar.gz

Make sure you also have [Podman installed](https://podman.io/getting-started/installation) since you’ll need it as well. On Fedora, to install Podman use the following command:

sudo dnf install podman

## Example: launching a WordPress site with Podman Compose

Imagine your *docker-compose.yaml* file is in a folder called *wpsite*. A typical *docker-compose.yaml* (or *docker-compose.yml*) for a WordPress site looks like this:

version: "3.8" services: web: image: wordpress restart: always volumes: - wordpress:/var/www/html ports: - 8080:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: magazine WORDPRESS_DB_NAME: magazine WORDPRESS_DB_PASSWORD: 1maGazine! WORDPRESS_TABLE_PREFIX: cz WORDPRESS_DEBUG: 0 depends_on: - db networks: - wpnet db: image: mariadb:10.5 restart: always ports: - 6603:3306 volumes: - wpdbvol:/var/lib/mysql environment: MYSQL_DATABASE: magazine MYSQL_USER: magazine MYSQL_PASSWORD: 1maGazine! MYSQL_ROOT_PASSWORD: 1maGazine! networks: - wpnet volumes: wordpress: {} wpdbvol: {} networks: wpnet: {}

If you come from a Docker background, you know you can launch these services by running *docker-compose up*. Docker Compose will create two containers named *wpsite_web_1* and *wpsite_db_1*, and attaches them to a network called *wpsite_wpnet*.

Now, see what happens when you run *podman-compose up* in the project directory. First, a pod is created named after the directory in which the command was issued. Next, it looks for any named volumes defined in the YAML file and creates the volumes if they do not exist. Then, one container is created per every service listed in the *services* section of the YAML file and added to the pod.

Naming of the containers is done similar to Docker Compose. For example, for your web service, a container named *wpsite_web_1* is created. Podman Compose also adds localhost aliases to each named container. Then, containers can still resolve each other by name, although they are not on a bridge network as in Docker. To do this, use the option *–add-host*. For example, *–add-host web:localhost*.

Note that *docker-compose.yaml* includes a port forwarding from host port 8080 to container port 80 for the web service. You should now be able to access your fresh WordPress instance from the browser using the address *http://localhost:8080*.

![](https://fedoramagazine.org/wp-content/uploads/2021/01/Screenshot-from-2021-01-08-06-27-29-1024x767.png)

## Controlling the pod and containers

To see your running containers, use *podman ps*, which shows the web and database containers along with the infra container in your pod.

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

a364a8d7cec7 docker.io/library/wordpress:latest apache2-foregroun... 2 hours ago Up 2 hours ago 0.0.0.0:8080->80/tcp, 0.0.0.0:6603->3306/tcp wpsite_web_1

c447024aa104 docker.io/library/mariadb:10.5 mysqld 2 hours ago Up 2 hours ago 0.0.0.0:8080->80/tcp, 0.0.0.0:6603->3306/tcp wpsite_db_1

12b1e3418e3e k8s.gcr.io/pause:3.2

You can also verify that a pod has been created by Podman for this project, named after the folder in which you issued the command.

POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS

8a08a3a7773e wpsite Degraded 2 hours ago 12b1e3418e3e 3

To stop the containers, enter the following command in another command window:

podman-compose down

You can also do that by stopping and removing the pod. This essentially stops and removes all the containers and then the containing pod. So, the same thing can be achieved with these commands:

podman pod stop podname podman pod rm podname

Note that this does not remove the volumes you defined in *docker-compose.yaml*. So, the state of your WordPress site is saved, and you can get it back by running this command:

podman-compose up

In conclusion, if you’re a Podman fan and do your container jobs with Podman, you can use Podman Compose to manage your containers in development and production.

## Oscar

Thanks. Another way to do the more or less the same is https://www.redhat.com/sysadmin/compose-podman-pods

## Mehdi Haghgoo

Yes Oscar, that’s also another useful feature of Podman. However, in order for “podman kube generate” to work, a pod needs to be running with the containers added to it manually. It’s very interesting though, and I might write a future article about it on Fedora Magazine.

## James

Thanks, that’s really useful to me as I am working with podman to create a django site, using a pod. I have used podman build to build the container images, and have added their containers to a pod using the podman run command with the –pod switch.

I recently switch to using Silverblue, but on both Silverblue and Workstation 33 if I forgot to stop the pod when closing down, it would take an absolute age, something like 2 minutes, before the laptop finally shut down.

So, I made a simple systemd service file to shutdown podman on power off of the laptop…

[Unit]

Description=Podman shutdown service

DefaultDependencies=no

Before=poweroff.target halt.target shutdown.target

[Service]

Type=oneshot

User=dev

ExecStart=/usr/bin/podman pod stop --all

RemainAfterExit=yes

TimeoutStartSec=0

TimeoutSec=3600

[Install]

WantedBy=shutdown.target halt.target

I enabled the service using ‘sytemctl enable podman-shutdown.service’ and now my laptop shuts down cleanly and immediately.

I just have one question left. Is there a way to open ports individually to running containers inside a pod?

With the publish option when creating a pod, a port mapping is created, but that port is then open for all the containers, not just one, and without peeking, I seem to recall that only one port can be published.

## Mehdi Haghgoo

James, for your use case, if you don’t want to use podman-compose, you can use “podman generate kube” feature to generate a kubernetes YAML that you will be able to run using “podman play kube” later on to quickly restore your pod and its containers.

Regarding your question to individually map ports of a container within a pod to a specific host port, it is not possible as far as I know. Instead, you configure port mapping in the form of HOST_PX:CON_PX on the pod when creating it. Later, when you run a container inside the pod that exposes port CON_PX, that port from the container will automatically be published to HOST_PX on the host.

## Gwyn Ciesla

podman-compose is also installable in Fedora via dnf.

## Mehdi Haghgoo

Yes Gwyn, but the latest developer version has to be installed from GitHub, as we did.

## Gwyn Ciesla

It’s actually in rawhide and updates-testing for f33.

## Laszlo Jagusztin

Unfortunately podman compose unable to handle anything that newer than Docker compose 1.0

Most of the projects use newer syntax

## Mehdi Haghgoo

Laszlo I have not had problem with it so far working with my podman-compose.yml files. Do you have specific commands that are not supported by Podman Compose?

## Stefano Stagnaro

I often appreciate Fedora Magazine blog posts but this time I must respectfully disagree. Podman Compose is nothing more than an (awesome) experimental project. There are dozen of forgotten issues and unmerged pull requests and moreover, it’s hard to deal with most of the docker-compose.yml found on the net. Since Podman 3.0 is now GA with the new RESTful API, there aren’t any strong reasons for not using the original Docker Compose directly with Podman… except for this three:

1) Compose is bad, DON’T COMPOSE! Docker Compose works well with Docker ecosystem only, therefore it lacks support for modern container features like Pods and other Kubernetes resources. Unlike Docker, Podman can definitely deal with them but unfortunately not through Compose.

2) Compose is a Docker-only provisioning system, while IT guys usually prefers all-around automation technologies like Ansible. Just write an Ansible playbook with Podman modules instead of the docker-compose.yml. Same effort, only benefits.

3) Compose and Docker may works for developers, certainly not when it comes to enterprise application deployment. Even if Kubernetes is the preferred way for container deployments, in specific contexts a stand-alone Podman managed by systemd units and monitored by journald will do the trick.

In conclusion, since I’m a big Fedora fan, I can’t help but suggesting an awesome new article for Fedora Magazine called… DON’T COMPOSE 😀

## Erik Sjölund

The upcoming Podman 3.0 supports the Docker REST API well enough to be used as back-end for docker-compose. It is planned to be released in a few weeks.

Caveats:

Running Podman as root is supported, but not yet running as a normal user, i.e. running “rootless”. (See feature request https://github.com/containers/podman/issues/9169)

Functionality relating to Swarm is not supported

To enable Podman as the back-end for docker-compose, run

sudo systemctl enable –now start podman.socket

Podman will then listen on the UNIX domain socket /var/run/docker.sock

See also: https://www.redhat.com/sysadmin/podman-docker-compose

## Mehdi Haghgoo

Stefano I appreciate your arguments regarding Podman and against Podman-Compose. As far as I know the new Podman 3.0 feature allowing running docker-compose.yaml files only works in root mode. I don’t think many people prefer rootless containers.

Personally, I have found docker-compose super useful for development environments. Then, thanks to Podman Compose, I was able to switch back and forth from macOS to Fedora for development very easily. It is amazing!

## Viktor Ransmayr

@Mehdi : I assume you wanted to say “I

dothink many people prefer rootless containers”. – Correct?## Mehdi Haghgoo

That is right. Unfortunately, I didn’t have the option to revise the comment. Thank you Viktor for correcting.

## Werner

I had some issues running a simple nginx pod using podman-compose on Fedora 33: it was impossible to access the volume mounts for http document root. Adding a

privileged: true

solved the security issues. Probably there is a better solution, though I was not able to find one. Tried even to make it world readable did not help. Just in case somebody has the same problem.

## Mehdi Haghgoo

Yes Werner, it happens with volumes and it is caused by SELinux. I used to solve it using setenforce 0, but “privileged: true” seems a better option.

Thanks for sharing.

## Blake

Hi, @Werner @Mehdi Another way which I believe is more suitable for the volume issue mentioned here is mapping the volume with :z at the end.

E.g: podman -v /my/host/path:/etc/containerpath:z

https://www.redhat.com/sysadmin/user-namespaces-selinux-rootless-containers