# Docker # To install PostgreSQL, Postgres Admin console, Redis and the test Web app, you would use docker-compose. ### Install Docker ### Download and install Docker for Mac : [Docker Community Edition for Mac](https://store.docker.com/editions/community/docker-ce-desktop-mac) Docker for Mac already includes Compose along with other Docker apps, so Mac users do not need to install Compose separately. ### Run Docker compose ### docker-compose up -d ### Configure components ### Looking at the docker-compose.yml file section by section: #### PostgreSQL #### ``` PostgreSQL: image: postgres:alpine ports: - 5432:5432 restart: always env_file: .env volumes: - "$ROOT/postgresql:/var/lib/postgresql/data" - ./setup/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql ``` This sets PostgreSQL to use the Postgres:Alpine image. This is a version of the Postgres image built upon the Alpine Linux disk image, it is 5MB so makes for a slimmer image. A 'friendly' name is set for the image, otherwise it will create the running image with a slightly cryptic name which appears to be based upon the current directory, the name of the container and an integer. Here, the container name is set to PostgreSQL It then exposes the Postgres communication port to 5432. This is the standard port for Postgres. The restart option is set to `always` to ensure the image is started again if the host is rebooted. There are other options available, these options can be found here: [Docker-compose:Restart](https://docs.docker.com/compose/compose-file/#restart) Then the environment file is set by pointing `env_file` to `.env`. This allows the use of predefined variables instead of editing the docker-compose file to set things such as volumes. The Postgres image utilises a number of environment variables to set user, password and server details. these values are contained within the `.env` file as `POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB`. They can be changed within the `.env` file. Finally, the volumes are set. The first one: ``` "$ROOT/postgresql:/var/lib/postgresql/data" ``` This makes the Postgres image persist data in a local folder `./postgressql`. Doing this prevents data from being lost if the image is stopped. However, if `docker-compose down -v` is run then the persistant data will be removed. The `$ROOT` value is stored in the environment file, and can be configured there. The second volume: ``` ./setup/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql ``` This is used to recreate the Postgres database from scratch in the case of starting everything with `./docker-compose up`. The official Postgres docker image will run .sql scripts found in the /docker-entrypoint-initdb.d/ folder. So that is used by pointing `/docker-entrypoint-initdb.d/init.sql` to a local file. The Postgres image can be stopped and restarted again individually. Since the container name was set in the configuration, the following can be applied: ``` docker stop PostgreSQL docker restart PostgreSQL ``` #### Adminer #### Adminer is a database management console. ``` adminer: image: adminer container_name: adminer restart: always depends_on: - PostgreSQL ports: - 8080:8080 ``` The image is set to use the adminer image, and the container name is set to be `adminer` instead of the automatically generated container name. Again, the restart option is set to `always` so that adminer will restart on power loss. `Depends_on` is set to `PostgreSQL` since this is the management console for it. The port `8080` is then exposed allowing users to access it. It is typically accessed via [`http://localhost:8080`](http://localhost:8080) Since everything is being launched by docker-compose, there is a background network created that allows the services to communicated with each other. Each service takes the interface name from the configuration file. So the Postgres server will be called PostgreSQL. When logging in via the Adminer console, the System should be set to Postgres and the Server should be set to PostgresSQL The username, password and database to connect to can be found within the `.env` file as `POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB`. #### Redis #### Redis is an open source key-value store that functions as a data structure server. ``` redis: image: redis:alpine container_name: redis restart: always volumes: - "$ROOT/redis:/data" ``` The image is set to use the lightweight redis:alpine image, and the container name is set to be `redis` instead of the automatically generated container name. Again, the restart option is set to `always` so that adminer will restart on power loss. The persistent data volume is set to be `./redis` based by using the ROOT value from the `.env` file. A blank configuration file is included in the `./setup/redist` folder. If this is required to configure redis, then an additional volume should be added to the image. Such as: ``` redis: image: redis:alpine container_name: redis restart: always volumes: - "$ROOT/redis:/data" - "./setup/redis/redis.conf:/usr/local/etc/redis/redis.conf" ``` #### Web #### This is a small NodeJS based server, every 15 seconds it insert data into the database. It also serves a small single page app which retrieves the data from the server and displays a list of entries. It is an example of how to use Docker Compose to build an app from the source code then serve it. ``` web: build: ./setup/web/. container_name: web command: npm run start volumes: - /usr/app/node_modules ports: - 9000:9000 depends_on: - PostgreSQL - redis environment: - HOST=${HOST} - DATABASE=${POSTGRES_DB} - USER=${POSTGRES_USER} - PASSWORD=${POSTGRES_PASSWORD} - DATABASE_URL=${DATABASE_URL} ``` There is no offical image for this, as it builds a new 'image' using the Dockerfile in ./setup/web. This Dockerfile creates a new Node container, copies all the files in ./setup/web into it then runs npm install. This creates the base image for the container. The container name is set to be `web` instead of the automatically generated container name. The command to run once the image has been built is `npm run start`. This launches a NPM script inside the package.json file copied to the container. A persistent volume is created for the node app on `/user/app`. `Depends_on` is set to `PostgreSQL` and `redis` as these are required to be installed before this app can be run. The database connection information is sourced from the .env file and passed to the Node app via environment variables. When the web app is finally running it can be available from [`http://localhost:9000`](http://localhost:9000)