Tiny Deathstars of Foulness

Web Services in Mac OS X, Mac OS X Server, Linux and most versions of Unix are provided by Apache, an Open Source project that much of the Internet owes its origins to. Apache owes its name to the fact that it’s “a patchy” service. These patches are often mods, or modules. Configuring web services is as easy in OS X Mavericks Server (10.9) as it has ever been. To set up the default web portal, simply open the Server app, click on the Websites service and click on the ON button.

Screen Shot 2013-10-07 at 7.06.28 PMAfter a time, the service will start. Once running, click on the View Server Website link at the bottom of the pane.

Screen Shot 2013-10-07 at 7.07.01 PM

Provided the stock OS X Server page loads, you are ready to use OS X Server as a web server.

Screen Shot 2013-10-07 at 7.07.43 PMBefore we setup custom sites, there are a few things you should know. The first is, the server is no longer really designed to remove the default website. So if you remove the site, your server will exhibit inconsistent behavior. Also, don’t remove the files that comprise the default site. Instead just add sites, which is covered next. Webmail is gone. You don’t have to spend a ton of time looking for it as it isn’t there. Also, Mountain Lion Server added web apps, which we’ll briefly review later in this article as well, as those continue in Mavericks Server.  Finally, enabling PHP and Python on sites is done globally, so this setting applies to all sites hosted on the server.

Screen Shot 2013-10-07 at 8.04.38 PMNow that we’ve got that out of the way, let’s add our first custom site. Do so by clicking on the plus sign. At the New Web Site pane, you’ll be prompted for a number of options. The most important is the name of the site, with other options including the following:

  • Domain Name: The name the site is accessible from. The default sites do not have this option as they are accessible from all names that resolve to the server.
  • IP Address: The IP address the site listens on. Any means the site is available from every IP address the server is configured to use. The default websites do not have this option as they are accessible from all addresses automatically
  • Port: By default, sites without SSL run on port 80 on all network interfaces, and sites with SSL run on port 443 on all network interfaces. Use the Port field to use custom ports (e.g., 8080). The default sites do not have this option as they are configured to use 80 and 443 for default and SSL-based communications respectively.
  • SSL Certificate: Loads a list of SSL certificates installed using Keychain or the SSL Certificate option in the Settings pane of the Server application
  • Store Site Files In: The directory that the files that comprise the website are stored in. These can be placed into the correct directory using file shares or copying using the Finder. Click on the drop-down menu and then select Other to browse to the directory files are stored in.
  • Who Can Access: By default Anyone (all users, including unauthenticated guests) can access the contents of sites. Clicking on Anyone and then Customize… brings up the “Restrict access to the following folders to a chosen group” screen, where you can choose web directories and then define groups of users who can access the contents.
  • Additional Domains: Click on the Edit… button to bring up a simple list of domain names the the site also responds for (e.g. in addition to, add
  • Redirects: Click on the Edit… button to bring up a list of redirects within the site. This allows configuring redirects to other sites. For example, use /en to load or /cn to load
  • Aliases: Click on the Edit… button to load a list of aliases. This allows configuring redirects to folders within the same server. For example, /en loads /Library/Server/Web/Data/Sites/Default
  • Index Files: Click on the Edit… button to bring up a list of pages that are loaded when a page isn’t directly indicated. For example, when visiting, load the wp.php page by default.
  • Advanced Options: The remaining options are available by clicking on the “Edit Advanced Settings…” button.
  • Enable Server Side Includes: Allows administrators to configure leveraging includes in web files, so that pieces of code can be used across multiple pages in sites.
  • Allow overrides using .htaccess files: Using a .htaccess file allows administrators to define who is able to access a given directory, defining custom user names and passwords in the hidden .htaccess file. These aren’t usually required in an OS X Server web environment as local and directory-based accounts can be used for such operations. This setting enables using custom .htaccess files instead of relying on Apple’s stock web permissions.
  • Allow folder listing: Enables folder listings on directories of a site that don’t have an Index File (described in the non-Advanced settings earlier).
  • Allow CGI execution: Enables CGI scripts for the domain being configured.
  • Use custom error page: Allows administrators to define custom error pages, such as those annoying 404 error pages that load when a page can’t be found
  • Make these web apps available on this website: A somewhat advanced setting, loads items into the webapps array, which can be viewed using the following command:  sudo serveradmin settings web:definedWebApps

Once you’ve configured all the appropriate options, click on Done to save your changes. The site should then load. Sites are then listed in the list of Websites.

The Apache service is most easily managed from the Server app, but there are too many options in Apache to really be able to put into a holistic graphical interface. The easiest way to manage the Websites service in OS X Mavericks server is using the serveradmin command. Apache administrators from other platforms will be tempted to use the apachectl command to restart the Websites service. Instead, use the serveradmin command to do so. To start the service:

sudo serveradmin start web

To stop the service(s):

sudo serveradmin stop web

And to see the status:

sudo serveradmin fullstatus web

Fullstatus returns the following information:

web:health = _empty_dictionary
web:readWriteSettingsVersion = 1
web:apacheVersion = "2.2"
web:servicePortsRestrictionInfo = _empty_array
web:startedTime = "2013-10-08 01:05:32 +0000"
web:apacheState = "RUNNING"
web:statusMessage = ""
web:ApacheMode = 2
web:servicePortsAreRestricted = "NO"
web:state = "RUNNING"
web:setStateVersion = 1

While the health option typically resembles kiosk computers in the Computer Science departments of most major universities, much of the rest of the output can be pretty helpful including the Apache version, whether the service is running, any restrictions on ports and the date/time stamp that the service was started.

To see all of the settings available to the serveradmin command, run it, followed by settings and then web, to indicate the Websites service:

sudo serveradmin settings web

The output is pretty verbose and can be considered in two sections, the first includes global settings across sites as well as the information for the default sites that should not be deleted:

web:defaultSite:documentRoot = "/Library/Server/Web/Data/Sites/Default"
web:defaultSite:serverName = ""
web:defaultSite:realms = _empty_dictionary
web:defaultSite:redirects = _empty_array
web:defaultSite:enableServerSideIncludes = no
web:defaultSite:customLogPath = ""/var/log/apache2/access_log""
web:defaultSite:webApps = _empty_array
web:defaultSite:sslCertificateIdentifier = ""
web:defaultSite:fullSiteRedirectToOtherSite = ""
web:defaultSite:allowFolderListing = no
web:defaultSite:serverAliases = _empty_array
web:defaultSite:errorLogPath = ""/var/log/apache2/error_log""
web:defaultSite:fileName = "/Library/Server/Web/Config/apache2/sites/0000_any_80_.conf"
web:defaultSite:aliases = _empty_array
web:defaultSite:directoryIndexes:_array_index:0 = "index.html"
web:defaultSite:directoryIndexes:_array_index:1 = "index.php"
web:defaultSite:directoryIndexes:_array_index:2 = "/wiki/"
web:defaultSite:directoryIndexes:_array_index:3 = "default.html"
web:defaultSite:allowAllOverrides = no
web:defaultSite:identifier = "37502141"
web:defaultSite:port = 80
web:defaultSite:allowCGIExecution = no
web:defaultSite:serverAddress = "*"
web:defaultSite:requiresSSL = no
web:defaultSite:proxies = _empty_dictionary
web:defaultSite:errorDocuments = _empty_dictionary
web:defaultSecureSite:documentRoot = "/Library/Server/Web/Data/Sites/Default"
web:defaultSecureSite:serverName = ""
web:defaultSecureSite:realms = _empty_dictionary
web:defaultSecureSite:redirects = _empty_array
web:defaultSecureSite:enableServerSideIncludes = no
web:defaultSecureSite:customLogPath = ""/var/log/apache2/access_log""
web:defaultSecureSite:webApps = _empty_array
web:defaultSecureSite:sslCertificateIdentifier = ""
web:defaultSecureSite:fullSiteRedirectToOtherSite = ""
web:defaultSecureSite:allowFolderListing = no
web:defaultSecureSite:serverAliases = _empty_array
web:defaultSecureSite:errorLogPath = ""/var/log/apache2/error_log""
web:defaultSecureSite:fileName = "/Library/Server/Web/Config/apache2/sites/0000_any_443_.conf"
web:defaultSecureSite:aliases = _empty_array
web:defaultSecureSite:directoryIndexes:_array_index:0 = "index.html"
web:defaultSecureSite:directoryIndexes:_array_index:1 = "index.php"
web:defaultSecureSite:directoryIndexes:_array_index:2 = "/wiki/"
web:defaultSecureSite:directoryIndexes:_array_index:3 = "default.html"
web:defaultSecureSite:allowAllOverrides = no
web:defaultSecureSite:identifier = "37502140"
web:defaultSecureSite:port = 443
web:defaultSecureSite:allowCGIExecution = no
web:defaultSecureSite:serverAddress = "*"
web:defaultSecureSite:requiresSSL = yes
web:defaultSecureSite:proxies = _empty_dictionary
web:defaultSecureSite:errorDocuments = _empty_dictionary
web:dataLocation = "/Library/Server/Web/Data"
web:mainHost:keepAliveTimeout = 15.000000
web:mainHost:maxClients = "50%"

The second section is per-site settings, with an array entry for each site:

web:customSites:_array_index:0:documentRoot = "/Library/Server/Web/Data/Sites/"
web:customSites:_array_index:0:serverName = ""
web:customSites:_array_index:0:realms = _empty_dictionary
web:customSites:_array_index:0:redirects = _empty_array
web:customSites:_array_index:0:enableServerSideIncludes = no
web:customSites:_array_index:0:customLogPath = "/var/log/apache2/access_log"
web:customSites:_array_index:0:webApps = _empty_array
web:customSites:_array_index:0:sslCertificateIdentifier = ""
web:customSites:_array_index:0:fullSiteRedirectToOtherSite = ""
web:customSites:_array_index:0:allowFolderListing = no
web:customSites:_array_index:0:serverAliases = _empty_array
web:customSites:_array_index:0:errorLogPath = "/var/log/apache2/error_log"
web:customSites:_array_index:0:fileName = "/Library/Server/Web/Config/apache2/sites/"
web:customSites:_array_index:0:aliases = _empty_array
web:customSites:_array_index:0:directoryIndexes:_array_index:0 = "index.html"
web:customSites:_array_index:0:directoryIndexes:_array_index:1 = "index.php"
web:customSites:_array_index:0:directoryIndexes:_array_index:2 = "/wiki/"
web:customSites:_array_index:0:directoryIndexes:_array_index:3 = "default.html"
web:customSites:_array_index:0:allowAllOverrides = no
web:customSites:_array_index:0:identifier = "41179886"
web:customSites:_array_index:0:port = 80
web:customSites:_array_index:0:allowCGIExecution = no
web:customSites:_array_index:0:serverAddress = "*"
web:customSites:_array_index:0:requiresSSL = no
web:customSites:_array_index:0:proxies = _empty_dictionary
web:customSites:_array_index:0:errorDocuments = _empty_dictionary

The final section (the largest by far) includes array entries for each defined web app. The following shows the entry for a Hello World Python app:

web:definedWebApps:_array_index:20:requiredWebAppNames = _empty_array
web:definedWebApps:_array_index:20:includeFiles = _empty_array
web:definedWebApps:_array_index:20:requiredModuleNames = _empty_array
web:definedWebApps:_array_index:20:startCommand = ""
web:definedWebApps:_array_index:20:sslPolicy = 0
web:definedWebApps:_array_index:20:requiresSSL = no
web:definedWebApps:_array_index:20:requiredByWebAppNames = _empty_array
web:definedWebApps:_array_index:20:launchKeys:_array_index:0 = "org.postgresql.postgres"
web:definedWebApps:_array_index:20:proxies = _empty_dictionary
web:definedWebApps:_array_index:20:preflightCommand = ""
web:definedWebApps:_array_index:20:stopCommand = ""
web:definedWebApps:_array_index:20:name = "org.postgresql.postgres"
web:definedWebApps:_array_index:20:displayName = ""

Each site has its own configuration file defined in the array for each section. By default these are stored in the /Library/Server/Web/Config/apache2/sites directory, with /Library/Server/Web/Config/apache2/sites/ being the file for the custom site we created previously. As you can see, many of the options available in the Server app are also available in these files:

<VirtualHost *:80>
DocumentRoot "/Library/Server/Web/Data/Sites/"
DirectoryIndex index.html index.php /wiki/ default.html
CustomLog /var/log/apache2/access_log combinedvhost
ErrorLog /var/log/apache2/error_log

<IfModule mod_ssl.c>
SSLEngine Off
SSLProtocol -ALL +SSLv3 +TLSv1
SSLProxyEngine On
SSLProxyProtocol -ALL +SSLv3 +TLSv1

<Directory “/Library/Server/Web/Data/Sites/”>
Options All -Indexes -ExecCGI -Includes +MultiViews
AllowOverride None
<IfModule mod_dav.c>
Deny from all
ErrorDocument 403 /customerror/websitesoff403.html


The serveradmin command can also be used to run commands. For example, to reset the service to factory defaults, delete the configuration files for each site and then run the following command:

sudo serveradmin command web:command=restoreFactorySettings

The final tip I’m going to give in this article is when to make changes with each app. I strongly recommend making all of your changes in the Server app when possible. When it isn’t, use serveradmin and when you can’t make changes in serveradmin, only then alter the configuration files that come with the operating system by default. I also recommend keeping backups of all configuration files that are altered and a log of what was altered in each, in order to help piece the server back together should it become unconfigured miraculously when a softwareupdate -all is run next.

October 22nd, 2013

Posted In: Mac OS X Server

Tags: , , , , , , , , , , , , , , , , , ,

A common task when scaling databases is to reindex tables within the database. This process makes lookups faster and databases run butter. Reindexing becomes a pretty easy step before or after backing up the database as a general housekeeping step. To backup the database, you’ll use the pg_dump command, defining the user with -U and then the database with -d. In the case of Profile Manager, the database is device_management. Given that data is distributed across a lot of tables in the device_management database, the below script will backup the device_management database and then reindex each of the tables.

If you follow previous articles to enable the Postgres user, you would use the enabled user to access the database, editing the pguser variable to set that user. The paths to the binaries have also been made variables. This same concept could also be used with the collab, caldav, postgres and potentially roundcubemail databases, according to which databases and more specifically tables are causing systems to run slower as they grow.

$pg_dump -U $pguser device_management -c -f $backuplocation
$psql -U $pguser -d device_management -c "REINDEX table public.apn_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.auto_join_profiles;"
$psql -U $pguser -d device_management -c "REINDEX table public.cal_dav_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.cal_sub_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.card_dav_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.certificate_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.cfprefs_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.data_files;"
$psql -U $pguser -d device_management -c "REINDEX table public.device_groups;"
$psql -U $pguser -d device_management -c "REINDEX table public.device_groups_devices;"
$psql -U $pguser -d device_management -c "REINDEX table public.devices;"
$psql -U $pguser -d device_management -c "REINDEX table public.devices_provisioning_profiles;"
$psql -U $pguser -d device_management -c "REINDEX table public.directory_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.dock_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.dock_knob_sets_system_applications;"
$psql -U $pguser -d device_management -c "REINDEX table public.email_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.energy_saver_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.enet_addresses;"
$psql -U $pguser -d device_management -c "REINDEX table public.exchange_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.general_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.group_mappings;"
$psql -U $pguser -d device_management -c "REINDEX table public.ichat_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.interface_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.ios_application_library_item_relations;"
$psql -U $pguser -d device_management -c "REINDEX table public.ios_applications;"
$psql -U $pguser -d device_management -c "REINDEX table public.knob_sets_profiles;"
$psql -U $pguser -d device_management -c "REINDEX table public.lab_sessions;"
$psql -U $pguser -d device_management -c "REINDEX table public.ldap_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.login_item_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.login_item_knob_sets_system_applications;"
$psql -U $pguser -d device_management -c "REINDEX table public.login_window_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.mac_restrictions_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.mac_restrictions_knob_sets_system_applications;"
$psql -U $pguser -d device_management -c "REINDEX table public.mac_restrictions_knob_sets_widgets;"
$psql -U $pguser -d device_management -c "REINDEX table public.mcx_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.members_profiles;"
$psql -U $pguser -d device_management -c "REINDEX table public.mobility_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.parental_controls_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.printers;"
$psql -U $pguser -d device_management -c "REINDEX table public.printers_printing_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.printing_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.privacy_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.profiles;"
$psql -U $pguser -d device_management -c "REINDEX table public.provisioning_profiles;"
$psql -U $pguser -d device_management -c "REINDEX table public.restrictions_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.scep_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.schema_migrations;"
$psql -U $pguser -d device_management -c "REINDEX table public.sessions;"
$psql -U $pguser -d device_management -c "REINDEX table public.settings;"
$psql -U $pguser -d device_management -c "REINDEX table public.software_update_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.system_applications;"
$psql -U $pguser -d device_management -c "REINDEX table public.tasks;"
$psql -U $pguser -d device_management -c "REINDEX table public.user_groups;"
$psql -U $pguser -d device_management -c "REINDEX table public.users;"
$psql -U $pguser -d device_management -c "REINDEX table public.vpn_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.web_clip_knob_sets;"
$psql -U $pguser -d device_management -c "REINDEX table public.widgets;"
$psql -U $pguser -d device_management -c "REINDEX table public.wifi_knob_sets;"

February 2nd, 2012

Posted In: iPhone, Mac OS X, Mac OS X Server, Mass Deployment

Tags: , , , , , , , , , , ,

Mac OS X Server 10.7, Lion Server, comes with a few substantial back-end changes. One of these is the move from SQLite3 to PostgreSQL for many of the back-end databases, including Wiki and Podcast Producer (collab), Webmail (roundcubemail), iCal Server and Address Book Server (caldav) and as the back-end to the newest service in Lion Server, Profile Manager (device_management). As such, it’s now important to be able to use PostgreSQL the way we once used SQLite3, when trying to augment the data that these databases contains, as there currently aren’t a lot of options for editing this data (aside from manually of course).

Postgres has a number of commands that can be used to interact with databases. The most important is probably psql. Many of the other commands simply provide automated options to psql, and over time I’ve started using psql for most everything. For example, PostgreSQL comes with a command /user/bin/createuser. However, as it’s usually more verbose with errors, I like to use psql to do this. In Lion Server, the only user that can access the Postgres databases is _postgres, installed by default with Lion Server. Because a lot of commands require passwords and we might not always want to provide write access to the databases, we’re going to create a new SuperUser, called krypted with a password of daneel.

To do so, we will have to use the _postgres user to invoke psql. Any time you want to invoke psql with a different user than the user you are currently logged in as, use the -U option. To define a database, use the -d option (device_management providing access to Profile Manager data, caldav to iCal Server data roundcubemail to WebMail data and collar to Wiki data). To string this together, for accessing the device_management database as _postgres:

psql -U _postgres -d device_management

To then create a new user called krypted with a password of daneel we’ll use the create option, defining a user as the type of object to create, followed by the user name and then with password followed by the password (single quoted) and then createuser; as follows:

device_management=# create user krypted with password 'daneel' create user;

Now that there’s a valid user, let’s see what else we can do. To see all of the tables, use d:

device_management=# d

As you can tell, there are a bunch of them. Run the help command to see a list of SQL commands that can be run and ? for a list of psql options. To put some SQL commands into action, we’re going to look at the tasks that have been performed by Profile Manager. These are stored in the tasks table (aptly named), so we’re going to run the following SQL query (note a space followed by a semi-colon is required at the end of this thing):

device_management=# select * from "public"."tasks" limit 1000 offset 0 ;

Or to make it a bit simpler if you don’t have a lot of data in there yet:

device_management=# select * from "public"."tasks" ;

After seeing the output, you’ll probably be a little appreciative of Apple’s formatting. Next, let’s look at dumping the databases. We’re going to create a folder on the root of the volume called db_backups first:

sudo mkdir /db_backups

This is where these backups will end up getting stored. We’ll continue using the _postgres user for now. To do our database dumps, we’re going to use pg_dump, located at /usr/bin. First, we’ll dump the device_management database (but first we’ll stop the service and after we’ll start it – all commands from here on out also assume you’re sudo’d):

serveradmin stop devicemgr
pg_dump -U _postgres device_management -c -f /db_backups/device_management.sql
serveradmin start devicemgr

And the other 3 (stopping and starting each in the process):

serveradmin stop web
pg_dump -U _postgres roundcubemail -c -f /db_backups/roundcubemail.sql
serveradmin start web
serveradmin stop wiki
pg_dump -U _postgres collab -c -f /db_backups/collab.sql
serveradmin start wiki
serveradmin stop addressbook
serveradmin stop calendar
pg_dump -U _postgres caldav -c -f /db_backups/caldav.sql
serveradmin start addressbook
serveradmin start calendar

I haven’t had any problems running the dumps with the services running, but it’s better safe than sorry I guess. I’d probably also add some logging and maybe dump the output of full status for each service to try and track if all is well with each. Any time a service didn’t fire back up I’d then build in a sanity check for that event. There’s also a database for postgres itself, so let’s back that up as well since we’re here:

pg_dump -U _postgres postgres -c -f /db_backups/postgres.sql

These can then be restored using psql with the -d option to define the database being restored into and the -f option to define the file being restored from. For example, to restore collab:

psql -U _postgres -d collab -f /db_backups/collab

The databases are all dumped daily using pg_dumpall. These are stored in /var/pgsql but can be changed using serveradmin settings (for example, to move them to /var/pgsql1):

serveradmin settings postgres:dataDir = "/var/pgsql1"

If you mess up the Profile Manager database (before you put any real data into it) you can always use the /usr/share/devicemgr/backend/ script to trash the database and start anew (although I’d just use a snapshot of a VM for all this and restore from that).

You can also connect to Postgres remotely, or locally through a network socket (common in Apache uses) by adding a listener. To do so, we’ll need to restart the Postgres LaunchDaemon. First, back up the file, just in case:

cp org.postgresql.postgres.plist org.postgresql.postgres.plist.OLD_CSE

Then stop postgres:

serveradmin stop postgres

Then edit the org.postgresql.postgres.plist file to change the following line:


To read:


Then fire up postgres again:

serveradmin start postgres

And now let’s scan port 5432 (the default TCP and UDP port used for postgres) for localhost:

/Applications/Utilities/Network 5432 5432

We could have used another IP address for the listen_addresses as well, but with that _postgres user not requiring a password it didn’t really seem prudent to do so. Once you’ve enabled a socket, you’ll then be able to use one of the many GUI tools to manage postgres. Navicat is available on the Mac App Store for $5 and PGnJ is a nice, easy to use, free one. There are tons of others, but I don’t spend a lot of time in a SQL GUI and so don’t need more than a cheap app will get me. One nice thing about most of these is that they help you to form SQL queries (or they help me). This can get really nice if you are, for example, trying to get some good reporting on Profile Manager (a feature it’s a bit light on right now).

Finally, don’t do any of this stuff on a production box, except maybe if you want more than nightly backups unless you think pretty hard about what you’re doing and know the exact impact of doing something. If you were to edit the databases on a live boxen, then you can safely assume that with how all of the objects in those databases use GUIDs that you’re probably going to break something, if not bring the whole house of cards tumbling down.

January 4th, 2012

Posted In: iPhone, Mac OS X Server, Mac Security, Mass Deployment, SQL

Tags: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Daylite 3.9 is actually a fairly substantial update from 3.8. This mainly stems from the fact that 3.9 uses PostgreSQL rather than OpenBase, and it runs Postgres on a dedicated server (not that this increases complexity too much as it’s going to discover those databases using Bonjour). This gives the application speed and the developers a number of new options they hadn’t had before. The MarketCircle developers will likely be able to come to market with new changes faster, thus being able to make you more productive with your productivity app. Also expect more 3rd party developers. Why? Because PostgreSQL is way more popular than OpenBase, is flexible for exchanging data and allows for a number of existing developers to integrate with Daylite. But more importantly, the short term gain is raw, unfettered speed.

Before you look to install Daylite 3.9, make sure all your boxen have at minimum 10.4.11 or 10.5.6. Also make sure they have a Gig of RAM and that they’re a 1GHz G4 or better. Finally, like with Workgroup Manager, 640×480 just isn’t enough (I don’t think it’s enough to even load my web site without scrolling, but that’s aside from the point). So make sure you have 1024×768 or better.

Because of the migration from OpenBase to PostgreSQL there’s a little work in migrating the database to be done. To get started, perform a final sync on your 3.8 users. Then disconnected them and disable synchronization, backing up your database when you are done. Those 3.8 users should not sync again. You can go ahead and upgrade them to 3.9 while the server is offline. Now install the 3.9 package and install your licenses, just as you would in Daylite 3.8 and below). Then go to the File menu (from within Daylite) and select Database and then Migrate Database. Then enter some admin credentials and click on Migrate. The database will then be migrated and the admin password reset.

The application is snappier, both on a LAN and over the WAN. If you’re using Daylite 3.9 over a WAN (and you don’t have a VPN) then one of the first things you’ll look for is the TCP ports to open up. 6113 through 6116 for the server-side app. The new Daylite Touch will also need 6117.

Daylight 3.9 also brings Daylite Touch into focus. Daylite Touch is the answer to the fact that people don’t just want CRM or what have you on their desktops. They want it on the handheld as well. Daylite Touch allows you to access that. More on Daylite Touch in later posts.

There are a few other features to note as well (other than speed and handheld synchronization). Most of the new features revolve around being able to associate data, be it contacts, calendars or notes, with other data – thus providing a more robust object oriented model for data management within the app. There are also some GUI enhancements to make it easier to find objects on the screen (mostly trying to unify the Daylite Touch interface with that of the fat client). For users sync’ing data, this update should improve the experience, although I haven’t managed to verify that just yet. There are a number of minor bug fixes as well.

All in all, 3.9 is a substantial upgrade. I would think that an upgrade where the backend database is migrated to another solution, the server is split into its own component and handheld over-the-air sync is introduced would alone be worthy of a full version number. This really makes me take more and more notice of Daylite; they are just on the ball these days at MarketCircle and I can say I am truly looking forward to seeing what 4.0 has in store for us. Hold-out users of Now who need a server based solution finally have a good upgrade path, albeit one with a slightly different (and more robust) workflow.

March 31st, 2009

Posted In: Mac OS X

Tags: , , , , , , , , ,