Let me share some thoughts on how one can use Docker and Fig to run custom webapps in Tomcat and Postgres.
Tools that we are using
- Docker - Gives ability to run any App in a container
- Fig - helps run a combined setup of few Docker containers
- boot2docker - sets up special Virtual Machine and gives ability to run Docker on Mac OS X
- Tomcat - Java app server
- PostgreSQL - SQL Database
What do we want
We want: - run a custom set of Java webapps - custom Tomcat configuration - simulate development environment - Webapps are pre-configured to talk with DB on localhost - in Docker
- On Mac OS X, download the latest boot2docker distribution and install it.
- install Fig with
pip install -U fig
We will use a custom Tomcat docker, that will pre-install
socat is used for forwarding a local port 5432 to the remote address. Her’s our
FROM tomcat:7 RUN apt-get update && apt-get install -y curl postgresql-client socat
Next, create the
web: build: . volumes: - tomcat:/usr/local/tomcat - startTomcatAll.sh:/start.sh command: "sh /start.sh" links: - db ports: - "8080:8080" db: image: "postgres:9.4" ports: - "5432:5432" volumes: - postgres:/data
build tells Fig to build a custom Docker container, and specifies where the
volumes FROM:TO maps folder from the host OS, into the guest container. In our case, we have a
tomcat folder which contains the config and the webapps, and a custom start script.
command executes the custom script upon start. NOTE: The last command should output something, or Fig will stop the container.
tail -f catalina.out will do the job.
links tells what other containers shoul be linked. You will also get the environment variables like
DB_PORT_5432_TCP, which we will use in our script.
ports tells what ports to map from container into host OS.
image tells what public image from Docker Hub to use.
start.sh script will look like this:
#!/bin/sh # Port forwarding: localhost:5432 -> $DB_PORT_5432_TCP:5432 env | grep DB_PORT_5432_TCP= | sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/' | sh # Check the DB connection by listing tables psql -h localhost -U postgres -l # Some scripts rely on the operating system... echo "Ubuntu" > /etc/issue # Start the custom Tomcat startTomcat.sh # Output the log, so Fig can catch this tail -f /usr/local/tomcat/bin/catalina.out
A side note about Postgres container
A PostgreSQL official Docker container is set to be run from a user
postgres. In Mac OS X the
volumes are mounted with a current Mac user.
If we will mount a volume that contains the binary database files, when a container starts, Postgres will crash, because the username that is used to run a postgres does not match the username that the database files are.
The possible way to overcome is to
tar the files and “untar” them on start of a container.
The other way is to import the SQL dump -
psql -f /data/all_dbs.sql -h localhost -U postgre.
If you are on the Mac, you might want to tell
boot2docker VM to forward the
5432 port to your Mac. to do so, run
VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port5432,tcp,,5432,,5432";
If you’r on a Mac, make sure the boot2docker VM is started -
boot2docker start. Next, make sure that the environment is properly set by running
fig up and watch the Fig will start the
web containers and outputs the log into the console. You could run
docker build . to build your
Dockerfile, but fig will do it for you.
Now you can open your browser on
localhost:8080 and see your Tomcat app.
You can connect to any container from other shell by running
docker exec -i -t test_web_1 bash (or
docker imageswill list all images (
-awill list all)
docker pswill list running containers (
fig rmwill remove all stopped containers
docker images -f dangling=true -q |xargs docker rmi -f- will remove all dangling (not-named) Docker images