Debian: Setup z-push with IMAP and nginx

z-push allows you to extend your mail server with ActiveSync capabilities, e. g. support for push notifications on Apple’s iOS. That way, you can get earlier information about new emails on your iPhone and iPad. Since I couldn’t fine any complete guide on how to setup z-push within your already working setup with a mail server and nginx, I decided to create my own.

It will create a working ActiveSync functionality as well as an Autodiscover feature so that you need not more than email address and password to configure the email account on your device.

I’ve tested all of this on an iPhone device.

Installation of z-push

First, you need to install z-push. In order to do so, you just need to run the following command:

apt install z-push-backend-imap
Code language: Bash (bash)

This will install the package z-push-common with all required files as well.

By default data are installed into /usr/share/z-push and configuration files into /etc/z-push.

Optional: change owner to match PHP user

By default, all files and folders inside /usr/share/z-push are owned by www-data, which also is the default user for executing PHP scripts. If your setup runs with a different PHP user, you need to change permissions for this folder, the library folder and the log folder:

chown -R myuser:myuser /usr/share/z-push chown -R myuser:myuser /var/lib/z-push chown -R myuser:myuser /var/log/z-push
Code language: Bash (bash)

Otherwise, required files cannot be written or accessed by PHP.

Adjust log rotation

Also you need to adjust the user in the log rotation configuration under /etc/logrotate.d/z-push-common so that the files will be generated with the correct user.

/var/log/z-push/*.log { weekly missingok rotate 4 compress notifempty create 0644 www-data www-data }
Code language: JavaScript (javascript)

Set your username where currently www-data is set.


Now you need to configure z-push so that it is able to talk to your mail server.

There is more to configure in these configuration files, which is not part of this guide, since it is not necessary to get z-push working. However, edit these additional parameters to your liking. But please, do it after you followed this complete guide.


First, edit the file /etc/z-push/autodiscover.conf.php.
Enter your timezone in the line define('TIMEZONE', ''); and define BackendIMAP as your backend data provider: define('BACKEND_PROVIDER', 'BackendIMAP');


Now edit the file /etc/z-push/imap.conf.php and define your IMAP_SERVER, if it’s a remote one, as well as the IMAP_PORT. By default, these values point to localhost:443, which was fine for me.

The most important thing is now setting IMAP_FOLDER_CONFIGURED to true since it otherwise won’t work (as you can read in the comment above this setting).

Take a look into the settings for the folder names below this configuration. Depending on your mail server configuration you need to adjust these values. Personally, I needed to set IMAP_FOLDER_SENT to Sent Messages as well as IMAP_FOLDER_TRASH to Deleted Messages to properly be able to store sent messages and deleted messages. Otherwise, sent messages are gone forever and deleted messages were not deleted from the server itself and would be still accessible via IMAP.

Set IMAP_SMTP_METHOD to smtp to use your SMTP server to send emails. Below, set your $imap_smtp_params correctly according to your SMTP server. In my case, it’s the following:

$imap_smtp_params = array('host' => 'tcp://', 'port' => 587, 'auth' => true, 'username' => 'imap_username', 'password' => 'imap_password');
Code language: PHP (php)

If you use Port 25 or 587, you need to prefix your host with tcp://. If you’re using Port 465, you need to set the prefix to ssl://.


As last configuration step of this guide edit the file /etc/z-push/z-push.conf.php and adjust it the same way as you did for your Autodiscover settings.

nginx configuration

You need a working SSL/TLS certificate for the sub domain autodiscover.domain.tld to get it working properly.

You already might have a working vHost configuration, especially for this subdomain. If not, here you go:

server { listen 80; listen [::]:80; listen 443 ssl http2; listen [::]:443 ssl http2; ## # General settings ## server_name autodiscover.domain.tld; access_log /var/log/nginx/autodiscover.domain.tld-access.log; error_log /var/log/nginx/autodiscover.domain.tld-error.log; location ~* /AutoDiscover/AutoDiscover.xml { alias /usr/share/z-push/autodiscover/autodiscover.php; include /etc/nginx/fastcgi.conf; fastcgi_read_timeout 3660; fastcgi_pass; } location ~* /Microsoft-Server-ActiveSync { alias /usr/share/z-push/index.php; include /etc/nginx/fastcgi.conf; fastcgi_read_timeout 3660; fastcgi_pass; } ## # SSL ## location /.well-known/acme-challenge { root /var/www/letsencrypt; auth_basic off; types { } default_type text/plain; } ssl_certificate /etc/letsencrypt/live/autodiscover.domain.tld/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/autodiscover.domain.tld/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/autodiscover.domain.tld/fullchain.pem; }
Code language: Nginx (nginx)

You need to change all autodiscover.domain.tld with your correct domain name as well as your value to pass PHP connections to in both fastcgi_pass options.

Additionally, if you haven’t got a TLS certificate via Let’s Encrypt yet, comment out the last three lines if the SSL part (lines 41–43). Then, request a certificate and as soon as you’ve got one, uncomment these lines again.

Make sure, you always reload the configuration after a change (nginx -t && systemctl reload nginx).

Also, make sure that autodiscover.domain.tld points to your server via DNS.


It’s not many steps to to setup z-push with working Autodiscover thanks to the awesome work of the z-push maintainers. I’m curious why there wasn’t a complete guide for it before, especially the nginx part as there are many having problems getting it to work properly. I hope this time is over now. If you still having trouble setting z-push up correctly in this constellation, feel free to use the comment section below.

3 thoughts on “Debian: Setup z-push with IMAP and nginx

  1. Thank you. I’ll use this to motivate my web host to provide this

    Yup, I’m flipping through your blog

    Z-push is on my mind now and again for android as I have degoogled my droids since KitKat. Not simply hacking away with rm but clean roms. Zpush is the elegant solution

  2. Would you be able to add a piece about getting the letsencrypt cert? I use an nginx reverse proxy – can I just use that or does it have to be in local nginx on the z-push box?

    I intend to use this to add push to gmail, but I’m also not sure where to put the credentials.

    1. There already are plenty of tutorials about getting a Let’s Encrypt certificate for nginx. I don’t see any valid point why I should add it. Especially not to this article since it explicitly says that it is based on an already working nginx configuration. Additionally, z-push itself has nothing to do with the certificate. You should be able to retrieve it within your reverse proxy.

Leave a Reply

Your email address will not be published.