Skip to content

Commit

Permalink
Docker setup (#54)
Browse files Browse the repository at this point in the history
* Added Dockerfile and updated README.md accordingly

The Dockerfile is a minimal setup to construct a  layered docker image, which automatically
launches into the nix-shell when executed interactively.

The README.md now contains basic instructions about how to build and run the image, although
it does not yet specify how to e.g. sync the database files to be persistent or other niceties.
  • Loading branch information
tchoutri authored Dec 30, 2021
1 parent 9d08075 commit e033cc7
Show file tree
Hide file tree
Showing 14 changed files with 153 additions and 17 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

assets/node_modules
13 changes: 9 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,22 @@ jobs:
tests:
runs-on: ubuntu-latest
steps:

- uses: actions/[email protected]
- name: Local cache
uses: actions/cache@v2

- name: Cache install Nix packages
uses: rikhuijzer/[email protected]
with:
path: /nix/store
key: "${{ runner.os }}-nix-cache"
key: nix-${{ hashFiles('default.nix') }}

- uses: cachix/install-nix-action@v12
with:
nix_path: nixpkgs=channel:nixos-unstable

- uses: cachix/cachix-action@v10
with:
name: flora-pm

- run: nix-build nix/ci.nix
- run: nix-shell --run "echo OK"

Expand Down
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# syntax=docker/dockerfile:1
FROM nixos/nix

RUN nix-channel --update
RUN nix-env -iA nixpkgs.gnumake

# generate a working directory
WORKDIR /flora-server

# copy the files relevant to build core dependencies
COPY default.nix flora.cabal shell.nix environment.sh environment.docker.sh Makefile scripts/start-tmux.sh ./
COPY nix/ ./nix/

# let nix build the dependencies. This uses nix-shell to cache the setup phase.
RUN nix-shell

# copy asset-relevant dependency files
COPY assets/package.json assets/yarn.lock assets/
RUN nix-shell --run "make assets-deps"

CMD [ "/bin/sh", "-c", "sleep 1d"]
32 changes: 23 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ assets-watch: ## Continuously rebuild the web assets
assets-clean: ## Remove JS artifacts
@cd assets/ && rm -R node_modules

db-init: ## Initialize the dev database
@initdb -D _database

db-start: ## Start the dev database
@postgres -D _database

db-create: ## Create the database
@createdb -h $(FLORA_DB_HOST) -p $(FLORA_DB_PORT) -U $(FLORA_DB_USER) $(FLORA_DB_DATABASE)

Expand All @@ -35,7 +29,9 @@ db-setup: db-create ## Setup the dev database
@migrate init "$(FLORA_PG_CONNSTRING)"
@migrate migrate "$(FLORA_PG_CONNSTRING)" migrations

db-reset: db-drop db-setup ## Reset the dev database
db-reset: db-drop db-setup db-provision ## Reset the dev database (uses Cabal)

db-provision: ## Load the development data in the database
@cabal run -- flora-cli provision-fixtures

repl: ## Start a REPL
Expand All @@ -60,15 +56,33 @@ style: ## Run the code formatters (stylish-haskell, cabal-fmt, nixfmt)
@cabal-fmt -i flora.cabal
@nixfmt *.nix nix/*.nix

nix-build: ## Build the backend with Nix
@nix-build

nix-start: ## Start the server build with Nix. Does not source the environment.
./result/bin/flora-server

nix-shell: ## Enter the Nix shell
@nix-shell

nix-provision: ##
./result/bin/flora-cli provision-fixtures

nix-clean: ## Clean the Nix build artifacts
@nix-store --delete --ignore-liveness result
@rm result

nix-build: ## Build the backend with Nix
@nix-build
nix-tmux: nix-build ## Start a tmux session with the nix build system
@./scripts/start-tmux.sh

docker-build: ## Build the docker image
@docker-compose build

docker-start: ## Start the container cluster
@docker-compose up -d

docker-enter: ## Enter the docker environment
docker-compose exec flora-server "nix-shell"

tags:
@ghc-tags -c
Expand Down
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ For ease of development, a `shell.nix` file is provided. It brings with it syste
To jump into the development environment, use `make nix-shell`. It is impure by default, so your editor and development
tools will still be accessible.

## Installing using Docker instead

If you are using an environment that is not friendly to nix, like MacOS, you may want to use Docker instead.

To build the image, run `docker build -t flora-server .`. The build will take a while to download and set up dependencies the first time it is run, but subsequent builds should be significantly faster.

The image is set up to run the nix-shell on boot, so once the build is complete simply run `docker run -it -p 8083:8083 --rm flora-server`. Then you should be able to build the server itself by `nix-build`, or use any of the `make` commands as described below.

### Flora server

Configuration is handled through environment variables. They are all prefixed by `FLORA_` to avoid conflict, and the
Expand Down Expand Up @@ -55,6 +63,29 @@ $ make db-setup # Implies db-create

you can also use `db-create` and `db-drop` to create and delete the database in the PostgreSQL instance.

### Docker Workflow

A docker-based workflow is provided:

```bash
# It's gonna take around 13 minutes the first time you build,
# run "make docker-start" the next times.
$ docker-compose up -d --build
$ make docker-enter
# You'll be in the docker container
(docker)$ source environment.docker.sh
(docker)$ make nix-tmux
# You'll be in a tmux session, everything should be launched
# Visit localhost:8084 from your web browser to see if it all works.

# To provision the development database, type:
$ make docker-enter
(docker)$ source environment.docker.sh
(docker)$ make db-drop
(docker)$ db-setup # password is 'postgres' by default
(docker)$ make nix-provision
# And you should be good!
```
---

You can explore the Makefile rules by typing `make` in your shell.
3 changes: 3 additions & 0 deletions database.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
POSTGRES_USER="postgres"
POSTGRES_PASSWORD="postgres"
POSTGRES_DB="flora_dev"
6 changes: 6 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,11 @@ let

in pkgs.haskell.lib.overrideCabal cabal2nix (drv: {
inherit src;
doBenchmark = false;
doCheck = true; # Run the flora tests
doHaddock = false;
doHoogle = false;
enableExecutableProfiling = false;
enableLibraryProfiling = false;
isExecutable = true;
})
25 changes: 25 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
version: "3"
services:
flora-server:
build: .
container_name: flora-server
ports:
- "8084:8084"
volumes:
- database-data:/flora-server/pgdata/
- .:/flora-server:Z
links:
- database

database:
image: "postgres"
container_name: database
expose:
- "5432"
env_file:
- database.env
volumes:
- database-data:/flora-server/pgdata/

volumes:
database-data:
9 changes: 9 additions & 0 deletions environment.docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
source environment.sh

export FLORA_DB_HOST="database"

export FLORA_PG_URI="postgresql://${FLORA_DB_USER}:${FLORA_DB_PASSWORD}@${FLORA_DB_HOST}:${FLORA_DB_PORT}/${FLORA_DB_DATABASE}"
export FLORA_PG_CONNSTRING="host=${FLORA_DB_HOST} dbname=${FLORA_DB_DATABASE} user=${FLORA_DB_USER} password=${FLORA_DB_PASSWORD}"


export FLORA_HTTP_PORT=8084
2 changes: 1 addition & 1 deletion environment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export FLORA_PG_URI="postgresql://${FLORA_DB_USER}:${FLORA_DB_PASSWORD}@${FLORA_
export FLORA_PG_CONNSTRING="host=${FLORA_DB_HOST} dbname=${FLORA_DB_DATABASE} user=${FLORA_DB_USER} password=${FLORA_DB_PASSWORD}"

export FLORA_HTTP_PORT=8083
export FLORA_ENVIRONMENT="local"
export FLORA_ENVIRONMENT="development"

export FLORA_DOMAIN="localhost"

Expand Down
2 changes: 1 addition & 1 deletion nix/pin.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import (builtins.fetchTarball {
url =
"https://github.com/NixOS/nixpkgs/archive/2c2a09678ce2ce4125591ac4fe2f7dfaec7a609c.tar.gz";
"https://github.com/NixOS/nixpkgs/archive/589ce6d8899f9800cb90d85618cf46026a8d784d.tar.gz";
})
3 changes: 1 addition & 2 deletions nix/pkgs.nix
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,10 @@ import ./pin.nix {
prometheus-client =
hpNew.callHackage "prometheus-client" "1.1.0" { };

PyF = hpOld.callHackage "PyF" "0.10.1.0" { };
PyF = hpOld.callHackage "PyF" "0.10.2.0" { };
data-sketches = hpOld.callHackage "data-sketches" "0.3.1.0" { };
pcre2 = hpOld.callHackage "pcre2" "2.0.3" { };
optics-core = hpOld.callHackage "optics-core" "0.4" { };
# PyF = hpOld.callHackage "PyF" "0.10.2.0" { };
lucid = hpOld.callHackage "lucid" "2.11.0" { };
servant-lucid = hpNew.callCabal2nix "servant-lucid" (fetchTarball {
url =
Expand Down
14 changes: 14 additions & 0 deletions scripts/start-tmux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash

set -euxo pipefail

tmux kill-session -t 'flora' || true
tmux new-session -d -s 'flora'
tmux rename-window 'flora'
sleep 1
tmux send-keys -t "flora" 'make nix-start' 'C-m'
tmux select-window -t flora:0
sleep 1
tmux split-window -h 'make assets-watch'
tmux send-keys -t "flora" 'C-b'
tmux attach-session -t flora
7 changes: 7 additions & 0 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,19 @@ pkgs.haskellPackages.shellFor {
pkgs.concurrently
pkgs.esbuild
pkgs.nodePackages.postcss-cli
pkgs.iputils
pkgs.tmux
pkgs.bash
pkgs.nixfmt
];
exactDeps = true;
NIX_PATH = "nixpkgs=${pkgs.path}:.";
shellHook = ''
source environment.sh
export LOCALE_ARCHIVE="/nix/store/m53mq2077pfxhqf37gdbj7fkkdc1c8hc-glibc-locales-2.27/lib/locale/locale-archive"
export LC_ALL=C.UTF-8
printf "To start the server: \'make nix-build && make nix-start\'\n"
printf "To start the assets pipeline: \'make assets-watch\'\n"
printf "Happy hacking!\n"
'';
}

0 comments on commit e033cc7

Please sign in to comment.