How to change the date of a docker container without using libfaketime? [duplicate] - database

I have a container with a running program inside tomcat. I need to change date only in this container and test my program behaviour. I have time sensitive logic, and sometimes need to see what happens in a few days or months later.
Is it possible in docker? I read that if I change date in container, date will get changed on the host system. But it is a bad idea for me. I need to have a few instances of this application on one server and have possibilities of setting up different time for each instance.
But when I try to change date inside the container I get the error:
sudo date 04101812
date: cannot set date: Operation not permitted
Fri Apr 10 18:12:00 UTC 2015

It is very much possible to dynamically change the time in a Docker container, without effecting the host OS.
The solution is to fake it. This lib intercepts all system call programs use to retrieve the current time and date.
The implementation is easy. Add functionality to your Dockerfile as appropriate:
WORKDIR /
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime/src
RUN make install
Remember to set the environment variables LD_PRELOAD before you run the application you want the faked time applied to.
Example:
CMD ["/bin/sh", "-c", "LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME_NO_CACHE=1 python /srv/intercept/manage.py runserver 0.0.0.0:3000]
You can now dynamically change the servers time:
Example:
def set_time(request):
import os
import datetime
print(datetime.datetime.today())
os.environ["FAKETIME"] = "2020-01-01" # string must be "YYYY-MM-DD hh:mm:ss" or "+15d"
print(datetime.today())

That's not possible with Docker. Docker uses the same clock as the outside kernel. What you need is full virtualization which emulates a complete PC.
The sudo fails because it only makes you root of the virtual environment inside of the container. This user is not related to the real root of the host system (except by name and UID) and it can't do what the real root could do.
If you use a high level language like Python or Java, you often have hooks where you can simulate a certain system time for tests or you can write code which wraps "get current time from system" and returns what your test requires.
Specifically for Java, use joda-time. There you can inject your own time source using DateTimeUtils.setCurrentMillis*().

I created a Docker image containing libfaketime for use with Alpine but the process can be done in other distributions.
Here's an example of using it Java using Groovy as an example. But Tomcat can be used as well.
FROM groovy:alpine
COPY --from=trajano/alpine-libfaketime /faketime.so /lib/faketime.so
ENV LD_PRELOAD=/lib/faketime.so \
DONT_FAKE_MONOTONIC=1
Then build and pass the FAKETIME environment variable when doing a docker run for example
docker build -f fakedemo-java.Dockerfile . -t fakedemo
docker run --rm -e FAKETIME=+15d fakedemo groovy -e "print new Date();"
Source is in trajano
/
alpine-libfaketime | Github and the docker image is in trajano/alpine-libfaketime | dockerhub
I also created a variant of it based on Ubuntu: trajano
/
ubuntu-faketime | Github

This worked for me, maybe you could try it:
dpkg-reconfigure tzdata
Edit: Execute it inside the container you are having problems. An interface will appear. There you can edit the timezone and localtime for example, and set it correctly, that fixed my problem, that was the same as yours.
Good luck!

For me, I actually needed to set the actual date for testing. I found the following options work on Mac, but you have to realize you'll be changing the date for all of your containers because you're changing the date of the underlying Alpine VM that Docker uses for all of its containers.
OPTION 1: Change the date of your host machine & restart docker
Use this when:
You can restart docker.
You can change the date of your host machine
Steps:
Stop your containers.
Change the date of your machine via the Date & Time Preferences
Restart docker.
Start your containers.
Run this sequence again to get back to the right date & time.
OPTION 2: Change the date of the Alpine VM
Use this when:
You can't restart docker.
You can't set the date of your host machine
Steps:
screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
The screen starts blank, hit enter a few times.
date -s [hh:mm]
All of your docker containers will now have your new time. You can
also use other formats, look for documentation on “busybox date” as
it’s not quite the same as other date implementations.
To exit hit control-a : and type d
This detaches the screen session, but leaves the tty running.
To reset the time:
screen -r
This resumes your tty.
ntpd -q
This uses the server defined in /etc/ntp.conf (this looks like a magic bridge back to the host clock)
To exit hit control-a : and type quit
This terminates your screen and tty session.

docker exec -it [Container Id] /bin/bash (exec into container)
rm /etc/localtime (see time zone)
ln -s /usr/share/zoneinfo/Asia/Karachi /etc/localtime (set new time zone)

My solution: I run docker on top of a virtualbox vm via vagrant.
This is not as complex as it sounds. The Vagrantfile below resets the datetime of the vm to a specific one, before the machine goes up. The corresponding docker-compose provisioner takes care of automatically running the docker-compose.yml.
Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.define "ubuntuvm" do |ubuntuvm|
config.vm.box = "ubuntu/focal64"
config.vm.provision :docker
ubuntuvm.trigger.before :up do |trigger|
trigger.info = "changing time"
trigger.ruby do |env,machine|
require 'time'
machineTime = "2022/07/02 00:20:00"
offset = DateTime.parse(machineTime).strftime("%Q").to_i - DateTime.now.strftime("%Q").to_i
puts "Updating machine time to: #{machineTime} by shifting biossystemtime #{offset} ms"
puts `VBoxManage setextradata #{machine.id} "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled" 1`
puts `VBoxManage modifyvm #{machine.id} --biossystemtimeoffset #{offset}`
end
end
end
config.vm.hostname = "ubuntuvm"
# config.vm.network "forwarded_port", guest: 80 host: 8080
# config.vm.synched_folter "../data"", "/vagrant_data"
config.vm.provider "virtualbox" do |vb|
# vb.memory = "1024"
end
config.vm.provision :docker_compose, yml: "/vagrant/docker-compose.yml", rebuild: true, run: "always"
end
Then I just need to do a the following:
# start the machine and run the docker-compose
vagrant up
Everytime I start the machine I see the messages:
ubuntuvm: Updating machine time to: 2022/07/02 00:20:00 by shifting biossystemtime -212710744 ms
ubuntuvm: Running docker-compose up...
other commands:
# get inside the machine with ssh to check its time and also check the container's time (docker commands already exist inside there due to the provisioner).
vagrant ssh ubuntuvm
# stop the machine
vagrant halt
# destroy the machine
vagrant destroy
prerequisites
install virtualbox
install vagrant
Install docker-compose provisioner (optional for using docker-compose instead of just docker)
Known issues:
On the first run only, vagrant up will fail to update the time because for some reason the before-up trigger is executed even before the machine is created. On all other executions the machine is already there, so the time is reset as expected.

I was having the same problem with my jenkins docker instance following steps fixed my problem
exec into container
docker exec -it 9d41c699a8f4 /bin/bash
See time zone
cat /etc/timezone : out put Etc/UTC
set new time zone, with nano : Asia/Colombo (your timezone here)
Restart the container

Related

How to deploy SQL Server Express on Docker Desktop Kubernetes

I've been studying "Kubernetes Up and Running" by Hightower et al (first edition) Chapter 13 where they discussed creating a Reliable MySQL Singleton (Since I just discovered that there is a second edition, I guess I'll be buying it soon).
Using their MySQL reliable singleton example as a model, I've been looking for some sample YAML files to make a similar deployment with Microsoft SQL Server (Express) on Docker Desktop for Kubernetes.
Apparently I need YAML files to deploy
Persistent Volume
Volume claim (should this be NFS?)
SQL Server (Express edition) replica set (in spite of the fact that this is just a singleton).
I've tried this example but I'm confused because it does not contain a persistent volume & claim and it does not work. I get the error
Error: unable to recognize "sqlserver.yml": no matches for kind "Deployment" in version "apps/v1beta1"
Can someone please point me to some sample YAML files that are not Azure specific that will work on Docker Desktop Kubernetes for Windows 10? After debugging my application, I'll want to deploy this to Azure (AKS).
Wed Jul 15 2020 Update
I left out the "-n namespace" for the helm install command (possibly because I'm using Helm and you are using helm v2?).
That install command still did not work. Then I did a
helm repo add stable https://kubernetes-charts.storage.googleapis.com/
Now this command works:
helm install todo-app-database stable/mssql-linux
Progress!
When I do a "k get pods" I see that my todo-app-mssql-linux database is in the pending state. So I did a
kubectl get events
and I see
Warning FailedScheduling pod/todo-app-database-mssql-linux-8668d9b88c-lsh5l 0/1 nodes are available: 1 Insufficient memory.
I've been google searching for "Kubernetes insufficient memory" and can find no match.
I suspect this is a problem specific to "Docker Desktop Kubernetes".
When I look at the output for
helm -n ns-todolistdemo template todo-app-database stable/mssql-linux
I see the deployment is asking for 2Gi. (Interesting: when I use the template command, the "-n ns-todolistdemo" does not cause an error like it does with the install command).
So I do
kubectl describe deployment todo-app-database-mssql-linux >todo-app-database-mssql-linux.yaml
I edit the yaml file to change 2Gi to 1Gi.
kubectl apply -f todo-app-database-mssql-linux.yaml
I get this error:
error: error parsing todo-app-database-mssql-linux.yaml: error converting YAML to JSON: yaml: line 9: mapping values are not allowed in this context
Hmm... that did not work. I try delete:
kubectl delete deployment todo-app-database-mssql-linux
kubectl create -f todo-app-database-mssql-linux.yaml
I get this error:
error: error validating "todo-app-database-mssql-linux.yaml": error validating data: invalid object to validate; if you choose to ignore these errors, turn validation off with --validate=false
So I try apply:
kubectl apply -f todo-app-database-mssql-linux.yaml
Same error!
Shucks.... Is there a way to adjust the memory allocation for Docker Desktop?
Thank you
Siegfried
Short answer
https://github.com/helm/charts/blob/master/stable/mssql-linux/templates/pvc-master.yaml
Detailed Answer
Docker For Desktop comes already with a default StorageClass :
This storage class is responsible for auto-provisioning of PV whenever you create a PVC.
If you have a YAML definition of PVC (persistent volume claim), you just need to keep storageClass empty, so it will use the default.
k get storageclass
NAME PROVISIONER AGE
hostpath (default) docker.io/hostpath 11d
This is fair enough as Docker-For-Desktop Cluster is a one node cluster. So if your DB crashes and the cluster opens it again , it will not move to another node, because simply, you have a single node :)
Now should write the YAML of PVC from scratch ?
No , you don't need. Because Helm should be your best friend.
( I explained below Why you have to use Helm even without deep learning curve)
Fortunately, the community provides a chart called stable/mssql-linux..
Let's run it together :
helm -n <your-namespace> install todo-app-database stable/mssql-linux
# helm -n <namespace> install <release-name> <chart-name-from-community>
If you want to check the YAML (namely PVC) that Helm computed, you can run template instead of install
helm -n <your-namespace> template todo-app-database stable/mssql-linux
Why I give you the answer with Helm ?
Writing YAML from scratch lets reinventing the wheel while others do it.
The most efficient way is to reuse what community prepare for you.
However, you may ask: How can i reuse what others doing ?
That's why Helm comes.
Helm comes to be your installer of any application on top of kubernetes regardless how much YAML does your app require.
Install it now and hit the ground choco install kubernetes-helm

Volttron init daemon

Apparently my initial question was to vague or was interpreted as a bad question.
I'll try again.
There is a file called volttron located at volttron/scripts/admin/ the contents indicate it is / was for a Volttron daemon to start from init. I notice that it refers to paths outside of the venv (/var/lib/volttron) Why is this file there? Are there plans to revise it? Have people modified this file to achieve start from init? Is there documentation in regards to this subject?
Auto initialization is an extremely important feature for any program that provides a service on a computer system.
I have provided a snippet of the code.
#! /bin/sh
### BEGIN INIT INFO
# Provides: volttron
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: $network $named
# Should-Start: $network $named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: VOLTTRON (TM) Daemon
# Description: VOLTTRON (TM) agent execution platform.
### END INIT INFO
# Author: Brandon Carpenter <brandon.carpenter#pnnl.gov>
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="VOLTTRON (TM) agent execution platform"
NAME=volttron
USER=volttron
VLHOME=/var/lib/volttron
DAEMON_ARGS="-v -l $VLHOME/volttron.log"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
This script (scripts/admin/volttron) was setup assuming you had installed VOLTTRON in var/lib. To use it for your environment, edit VLHOME to where you installed it. For example: /home/volttronuser/git/volttron
Make the script executable: chmod +x scripts/admin/volttron, then copy it over to /etc/init.d/
To make it autostart with the OS:
sudo update-rc.d volttron defaults
To start and stop it manually:
sudo service volttron start
sudo service volttron stop
See the status with:
sudo service volttron status
If this is going to be used in a deployed situation, it's recommended that you edit the script to use a rotating log configuration (or using http://www.linuxcommand.org/man_pages/logrotate8.html). Edit the arguments in the script to use the -L option when starting VOLTTRON. This will use the rotatinglog configuration.
DAEMON_ARGS="-v -L $VLHOME/examples/rotatinglog.py"
You will also need to edit examples/rotatinglog.py to change the location of the log file. Edit "filename" to point to a location your user has permission to write to.
'handlers': {
'rotating': {
'class': 'logging.handlers.TimedRotatingFileHandler',
'level': 'DEBUG',
'formatter': 'agent',
'filename': '/home/myuser/git/volttron/volttron.log',
Note:
The cgroups portion of the script supports a VOLTTRON plugin for resource management and isn't needed without that. This is why it's commented out in the start method of the script.

Mesosphere installation PermissionError:/genconf/config.yaml

I got a Mesosphere-EE, and install on fedora 23 server (kernel 4.4)with:
$bash dcos_generate_config.ee.sh --web –v
then output:
Running mesosphere/dcos-genconf docker with BUILD_DIR set to/home/mesos-ee/genconf
Usage of loopback devices is strongly discouraged for production use.Either use `--storage-opt dm.thinpooldev` or use `--storage-opt
dm.no_warn_on_loop_devices=true` to suppress this warning.
07:53:46:: Logger set to DEBUG
07:53:46:: ====> Starting DCOS installer in web mode
07:53:46:: DCOS Installer v1
07:53:46:: Starting server ('0.0.0.0', 9000)
Then I start firefox though vnc, the vnc is on root. then:
07:53:57:: Root page requested. 07:53:57:: Serving/usr/local/lib/python3.4/site-packages/dcos_installer/templates/index.html
07:53:58:: Request for configuration type made.
07:53:58::Configuration file not found, /genconf/config.yaml. Writing new onewith all defaults.
07:53:58:: Error handling request
PermissionError: [Errno 13] Permission denied: '/genconf/config.yaml'
But I already have a genconf/config.yaml, it look like:
bootstrap_url: http://<bootstrap_public_ip>:<your_port>
cluster_name: '<cluster-name>'
exhibitor_storage_backend: zookeeper
exhibitor_zk_hosts: <host1>:2181,<host2>:2181,<host3>:2181
exhibitor_zk_path: /dcos
master_discovery: static
master_list:
- <master-private-ip-1>
- <master-private-ip-2>
- <master-private-ip-3>
superuser_username: <username>
superuser_password_hash: <hashed-password>
resolvers:
- 8.8.8.8
- 8.8.4.4
I do not know what’s going on. If you have any idear, please let me know, thank you very much!
Disable Selinux!
Configure SELINUX=disabled in the /etc/selinux/config file and then reboot!
Be ensure the selinux is disabled by the command getenforce.
$ getenforce
Disabled
zhe.
Correctly installing the enterprise edition depends on the correct system prerequisites. Anyway I suppose you're still on the bootstrap node so I will give you some path to succed in your current task.
Run the script as root or as a user issuing sudo dcos_generate_config.ee.sh
The script will also generate the config file automatically; if you want to use your own configuration file then create a folder named genconf and put it inside before running the script. You should changes the values inside <> with your specific configuration. If you need more help for your specific case send me an email to infofs2 at gmail.com

Starting and stopping App Engine instances with Docker

I've set up an App Engine project locally using Docker (on OSX), and have been running a server using the usual "gcloud preview app run app.yaml" command. From what I can tell, this keeps creating new images over and over again. After an hour or so of work I end up with something like 30 docker images, each taking 130MB.
Eventually I'm told I can no longer bind to localhost:8080. I tried killing all containers and images, but still cannot use localhost:8080 until I reboot.
Seems like I'm not using Docker/gcloud correctly. Anyone have an idea what I might be doing wrong? Is there another way I should be restarting App Engine instances other than hitting command C and running the "run" command again?
UPDATE: After looking closer, I noticed I'm getting this message when I run an app locally and a container is created: "http: Hijack is incompatible with use of CloseNotifier". I'm not familiar enough with Docker to understand what's going on here. All searches seem to point to Go, which I am not using.
UPDATE 2: Here is the trace:
Creating container...
INFO 2015-05-05 02:23:28,293 containers.py:560] Container 1564ce4344957114312d6d1dc696ffbb4176b40ace6dcff5e4239e13ee04a8f6 created.
Exception in thread Thread-2:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "/Users/judeosborn/google-cloud-sdk/platform/google_appengine/google/appengine/tools/docker/containers.py", line 643, in _ListenToLogs
for line in log_lines:
File "/Users/judeosborn/google-cloud-sdk/./lib/docker/docker/client.py", line 225, in _multiplexed_response_stream_helper
socket = self._get_raw_response_socket(response)
File "/Users/judeosborn/google-cloud-sdk/./lib/docker/docker/client.py", line 167, in _get_raw_response_socket
self._raise_for_status(response)
File "/Users/judeosborn/google-cloud-sdk/./lib/docker/docker/client.py", line 119, in _raise_for_status
raise errors.APIError(e, response, explanation=explanation)
APIError: 500 Server Error: Internal Server Error ("http: Hijack is incompatible with use of CloseNotifier")
INFO 2015-05-05 02:23:28,606 module.py:1745] New instance for module "default" serving on:
http://localhost:8080
There's an ongoing issue with Docker 1.6.x [reference] that prevents gcloud to work well with Managed VMs (as you seem to be using). Easiest workaround until it gets fixed is to downgrade Docker in your development machine to version 1.5.0, which is the latest version known to work.
For Ubuntu, you can do something like:
$ curl -sSL https://get.docker.com/ubuntu | sed 's/lxc-docker/lxc-docker-1.5.0/' | sudo sh
For other Linux distros, you might have to modify that sed pattern, though.
On the other hand, if you're using Boot2Docker under Mac OS X, follow these steps:
Fully uninstall your previous Boot2Docker/Docker setup; there is a nice guide here
Reinstall Boot2Docker/Docker following instructions here. IMPORTANT: You MUST stop right after completing "Install Boot2Docker" step and before "Start the Boot2Docker Application". Once you get there, open up a terminal and execute the following commands:
$ mkdir ~/.boot2docker
$ echo 'ISOURL="https://github.com/boot2docker/boot2docker/releases/download/v1.5.0/boot2docker.iso"' > ~/.boot2docker/profile
At this point, you can continue with "Start the Boot2Docker Application" section and finish the installation. You should now have a valid Docker launchpad with which to start Managed VMs. It'd be nice to double check that you have the right versions installed by issuing:
$ boot2docker ssh docker version | egrep "(Client|Server) version"
The output should look like:
Client version: 1.5.0
Server version: 1.5.0
Now you can try again your original command:
$ gcloud preview app run app.yaml
Try running:
$ ps uax | egrep "gcloud|appserver"
If you see anything running, kill it... you may even need to kill -9 it.

MacPorts Apache2 Stopped Launching on Boot

Something that I've noticed recently on two different machines is that Apache2 installed via MacPorts seems to have stopped launching when I boot up. The honest truth is that I can't swear it did so before, but it's something I think I'd notice because installing the LaunchDaemon is part of my install process. In fact, if I try to reload the LaunchDaemon, it fails:
$ sudo launchctl load -w /Library/LaunchDaemons/org.macports.apache2.plist
org.macports.apache2: Already loaded
Unless I start Apache manually (using sudo apachectl restart), grep'ing for either "apache2" or "httpd" in my process list only produces this:
$ sudo ps -ef | egrep "apache2|httpd"
0 52 1 0 0:00.06 ?? 0:00.08 /opt/local/bin/daemondo --label=apache2 --start-cmd /opt/local/etc/LaunchDaemons/org.macports.apache2/apache2.wrapper start ; --stop-cmd /opt/local/etc/LaunchDaemons/org.macports.apache2/apache2.wrapper stop ; --restart-cmd /opt/local/etc/LaunchDaemons/org.macports.apache2/apache2.wrapper restart ; --pid=none
1410639199 6960 6792 0 0:00.00 ttys001 0:00.00 egrep apache2|httpd
Looks like the daemon itself is in place, but no executable. As far as I know/can tell, the relevant executables (httpd and apachectl) are executable by everyone.
Has anyone else noticed this? Any ideas?
UPDATE
As requested below, I did execute launchctl list. The list is long and I'm not sure how to snip it, but suffice to say that no org.macports.* items are listed. That in itself is interesting because my MySQL daemon is loaded the same way. It works, but also doesn't appear in the list. Let me know if the entire output is really needed.
UPDATE
I assumed that I had executed launchctl list under sudo, but prompted by mipadi's comment below, I tried again ensuring that I did so and I assumed incorrectly. When executed under sudo, the MacPorts items appear:
51 - org.macports.mysql5
52 - org.macports.apache2
I'm not sure whether that will help, but it's a little more info nonetheless.
UPDATE
I've asked a different, but related, question at LaunchDaemons and Environment Variables. I'll update both questions as I learn more.
UPDATE
Today, based on mailing list input, I tried using a wildcard home directory. Academically, it's a little more inclusive than I'd like, but the practical reality is that I'm the only one using this computer; certainly the only one who'd have Apache config files laying around.
Include "/Users/*/Dropbox/Application Support/apache/conf.d.osx/*.conf"
Include "/Users/*/Library/Application Support/MacPorts/apache/conf.d/*.conf"
Unfortunately...
httpd: Syntax error on line 512 of /opt/local/apache2/conf/httpd.conf: Wildcard patterns not allowed in Include /Users/*/Dropbox/Application Support/apache/conf.d.osx/*.conf
I found my answer to this problem here:
https://trac.macports.org/ticket/36101
"I apparently fixed this when changing my local dnsmasq config. In /etc/hosts I added my servername (gala) to the loopback entry:
127.0.0.1 localhost gala
and then I changed ServerName in /opt/local/apache2/conf/httpd.conf to match:
ServerName gala
Apache now starts at boot for me."
Since I now know why Apache has stopped loading on startup, I'm going to articulate that answer and mark this question as answered. The reason Apache has stopped launching on boot is that I'm trying to share an httpd.conf file across systems. The config file needs to Include files from directories that exist within my home directory. Since the home directory is different on each machine, I was trying to reference the ${HOME} environment variable.
This works fine when manually starting after the machine is booted, but fails on startup because the environment variable isn't yet set. As mentioned above, see this question for more information.
Rob:
Had the same problem: "sudo launchctl load -w ..." started Apache2 while I was logged in, but did not work during startup (the "-w" should have taken care of that). Also, as you noticed, the daemon seems to be registered with launchctl. It will show up with "sudo launchctl list" and another "sudo launchctl load ..." will result in the error message.
I played with "sudo port load apache2" and "sudo port unload apache2", but could not get httpd running on reboot.
In the end, I got rid of the MacPorts startup item: "sudo port unload apache2", checked with "sudo launchctl list" that org.macports.apache2 is no longer registered for startup.
Afterwards, I followed the steps on http://diymacserver.com > Docs > Tiger > Starting Apache. I only had to adapt the path from /usr/local/... to /opt/local/...
Now the MacPorts Apache2 is starting fine with every reboot.
Good luck, Klaus
I found that my MacPorts apache2 was not starting on boot because of an “error” in my httpd.conf.
I was using
Listen 127.0.0.1:80
Listen 192.168.2.1:80
Listen 123.123.123.123:80 # Example IP, not the one I was really using
And in Console.app I was seeing
4/8/12 4:59:06.208 PM org.macports.apache2: (49)Can't assign requested address: make_sock: could not bind to address 192.168.2.1:80
4/8/12 4:59:06.208 PM org.macports.apache2: no listening sockets available, shutting down
4/8/12 4:59:06.208 PM org.macports.apache2: Unable to open logs
I tried adjusting permissions on all the log folders (despite the fact that logs were being written just fine when I manually started apache2) and that didn't help.
Even though the Apache Documentation for Listen clearly states
Multiple Listen directives may be used to specify a number of addresses and ports to listen to. The server will respond to requests from any of the listed addresses and ports.
I decided to try switching back to just using
Listen 80
And after doing so apache2 is starting on boot with no errors or warnings.
If you're using Subversion with Apache, you may find that Apache is not starting because the mod_dav_svn.so file has moved to /opt/local/libexec. You'll need to adjust your Apache startup files to account for the new location of this file.
In newer versions of MacPorts you can run sudo port load apache2 to instruct MacPorts to take care of the launchctl setup and automatically start the process. To stop the process run port unload.
After loading check /opt/local/apache2/logs/error_log for errors, including configuration issues.
In addition to my previous answer I have also found that sometimes Apache fails to start because something else with the system is not yet ready.
On one OS X Server machine I also use the DNS to create a “internal only” DNS name for the machine and that name is used in my Apache configuration. Sometimes when Apache tries to start the DNS server is not yet ready and Apache fails to load because the hostname isn’t valid.
I have also seen this on other non-Server systems without local DNS as well where something else required by Apache must not be ready yet.
One thing that has worked is to edit the apache2.wrapper located at /opt/local/etc/LaunchDaemons/org.macports.apache2/apache2.wrapper that MacPorts’ daemondo uses to start up Apache.
Edit the Start() function to add a sleep command to wait a bit before launching Apache.
Original (Lines 14-17 on my machine)
Start()
{
[ -x /opt/local/apache2/bin/apachectl ] && /opt/local/apache2/bin/apachectl start > /dev/null
}
With wait time added
Start()
{
[ -x /opt/local/apache2/bin/apachectl ] && sleep 10 && /opt/local/apache2/bin/apachectl start > /dev/null
}

Resources