Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to use FreeBSD's pkg_add command to install and upgrade binary packages in a build-once-install-on-multiple-machines sort of scenario. It works well when installing a new package, but upgrades are baffling me. For example, if I want to upgrade a package that is depended on by another package, I can't just install it:

# pkg_add /path/to/somepackage-2.0.tbz
pkg_add: package 'somepackage' or its older version already installed

At this point, I can delete the older version of the package if I pass -f to the pkg_delete command:

# pkg_delete -f somepackage-1.0
pkg_delete: package 'somepackage-1.0' is required by these other packages
and may not be deinstalled (but I'll delete it anyway):

But...and this is the the dependency information is gone! I can install the upgrade:

# pkg_add /path/to/somepackage-2.0.tbz

And now attempts to delete it will succeed without any errors:

# pkg_delete somepackage-2.0

How do I handle this gracefully (whereby "gracefully" means "in a fashion that preserves dependency information without requiring me to rebuild/reinstall and entire dependency chain").


share|improve this question
up vote 4 down vote accepted

As you've found, pkg_add can't upgrade ports gracefully. The portupgrade package does this quite nicely however, and is the method I use and recommend (there are others available if you don't like this method).

Once the port is installed you can simply run portupgrade -aPP and it will upgrade all ports installed on the system using packages. If you don't want to update ever port, you can run portupgrade -RPP [category/port] to upgrade a particular port and the ports it depends on. Running the program without arguments will upgrade the port belonging to the current directory (i.e. cd /usr/ports/security/openssl ; portupgrade will upgrade openssl, without the -PP option it will build the port from source); and if you are not in a port directory it will display help (same as the -h option).

By default portupgrade will install packages if they exist in the directory defined by the PKG_PATH environmental variable (defaults to $PACKAGES/All, $PACKAGES defaults to $PORTSDIR/packages; so the default path is /usr/ports/packages/All).

If they don't exist there, it will download the packages (by preference) from $PKG_SITES (takes a URI with subfolders Latest and All; no default value), or $PACKAGEROOT (takes a URI with the normal mirror path under it; default is "").

One easy way to do this, use one machine to build/cache packages that will be installed on other machine.

  • You can build packages from the ports tree with make package in the port's directory (which will also install the port).
  • You can use portupgrade to upgrade one machine and cache the package files for use on other machines, the aforementioned commands will cache the package files in the default directory (see above).
  • You can use portupgrade to fetch the packages only, and not install them, with portupgrade -aPPF or portupgrade -RPPF [category/port].

Once you have the cached package files you can share the directory via NFS, FTP, HTTP, etc; so long as the files are accessible from the other machines. Set the PACKAGES or PKG_SITE with the appropriate values to point to the caching server. Execute the typical portupgrade command, it should pull the packages from the caching server and install them.

Note: The port tree has to be up to date on all the servers for portupgrade to operate correctly (it will attempt to update to whatever version is in the local ports tree). If you're going to have the same ports/packages installed on all the computers, it might be easiest to share one servers /usr/ports directory (say over NFS) and mount it on all the other servers.

share|improve this answer
What I want to is to (a) use locally built packages, if available, or (b) use packages from a remote repository. What I'm trying to avoid is the situation where I need to upgrade a package when the port is more recent than the available binary package on the mirrors...building it on the target system will pull in all the build dependencies, which isn't desirable. Building it a dedicated build host would work great if it's possible to tell portmaster to look into multiple locations for binary packages. – larsks Dec 21 '10 at 14:06

Maybe pkg_replace is what you are looking for.

I'm using it for quit a some time now. One of my FreeBSD machines acts as build server and builds ( using portmaster ) all packages for the other machines. I'am using pkg_replace to install these prebuild packages on all other machines.

share|improve this answer
Thanks, I'll take a look. – larsks Jan 13 '11 at 17:11

Or you could rely on Portsnap or CVSup, described here:

share|improve this answer
I think you've misunderstood the question. Portsnap and CVSup take care of keeping the ports tree up-to-date, but have very little to do with updating installed packages. Tools like portmaster and portupgrade bridge both worlds, but have their own issues. – larsks Dec 21 '10 at 14:04

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.