A new daughter and a new job conspired to make the gap between part one and part two of this blog over a year longer than I ever intended. Sorry for the delay. But major changes in both the Haskell and Docker ecosystems make refreshing some of what we did in part one appropriate in any case. In this post we'll:
- recap on setting up our development environment; and
- start building a simple Yesod web application with authentication.
About a week after I originally published part one, the Haskell stack tool was released. As far as I'm concerned you no longer need to build a Docker container simply to develop in. My original purpose in doing so was to make all the pain and suffering of getting Haskell up-and-running a one time cost. Stack goes one better by taking the pain and suffering away entirely.
There have also been changes to Docker Compose, which is a crucial part of our site. We'll use the improvements here to effectively eliminate code changes from our deployment steps later on.
Before you continue
Building a blog site is a tutorial cliché. I'm doing it anyway because this is aimed at people, like me, with no prior Yesod experience and very little Haskell experience. My goal here is to introduce the early steps in a non-intimidating way to get you started with this framework. The site you're reading is the first and only one I've built with Yesod so please don't consider any of what follows as best practice. If you still think you're in the right place read on. You will need around 1-2 hours to follow along.
Getting set up
Part one is still worth reading but not coding along with. Skim over it just now if you haven't already. We're going to go through the setup work part one covers quickly here to avoid repetition. I'll only point out the big changes.
The quickstart instructions for Yesod will tell you everything you need to know about getting stack and Yesod working on your machine. It's absurdly painless now. Create a parent directory to hold the whole docker setup before running the
stack new command. Use
yesod-postgres instead of
yesod-sqlite when following step 2 to get a site that will work with our Docker setup. Stop after step 4. Step 5 won't work until we've got our database set up.
Setting up Docker and Compose
curl -L https://github.com/docker/compose/releases/download/1.7.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
But that will give you a
permission denied error that
sudo won't help. This is easy to fix by breaking what that command is doing into separate steps. First run a slightly changed version of the command like this:
curl -L https://github.com/docker/compose/releases/download/1.7.1/docker-compose-`uname -s`-`uname -m` > ./compose
Then move it into place with:
sudo mv ./compose /usr/local/bin/docker-compose
You don't want to run Compose with
sudo so remember to follow the instructions for creating a
docker group. This will leave you with a working Compose installation.
Connecting your site to our Docker containers
We're just a couple of steps away from having the development site running and starting the fun work. First set up a directory structure like the following, where
site is the directory
stack created for you when you were following the Yesod setup instructions.
parent_directory/ site/ ... database/ dev_env webserver/ binary/ dev.yml
binary/ are just empty directories and
dev_env are empty files.
Note: We'll be using a number of environment files (ending in
envor simply called
env). Don't commit any of them to source control. If you ever commit a production
envfile by accident, note the settings in the file and never use them for any purpose again.
dev_env first and enter the following:
POSTGRES_USER=your_site_name POSTGRES_DB=your_site_name POSTGRES_PASSWORD=supersecretpassword
Now open the file at
./site/config/settings.yml and look for the following values
database: user: "_env:PGUSER:your_site_name_LOWER" password: "_env:PGPASS:your_site_name_LOWER" host: "_env:PGHOST:localhost" port: "_env:PGPORT:5432" # See config/test-settings.yml for an override during tests database: "_env:PGDATABASE:your_site_name_LOWER" poolsize: "_env:PGPOOLSIZE:10"
Change the values that look like
your_site_name_LOWER to match those in the
dev_env file. Now open
dev.yml and enter the following:
version: "2.0" services: database: image: postgres env_file: ./database/dev_env ports: - "5432:5432"
docker-compose --file=dev.yml up from your
parent_directory to set up the database. Once it's started, stop it then enter the command
docker-compose --file=dev.yml up -d to restart it in the background. Now
cd into your site directory and run
stack exec -- yesod devel. If you see an error like
yesod: cabal: createProcess: runInteractiveProcess: exec: does not exist (No such file or directory) then run
stack install yesod-bin cabal-install then try again. Your site should build then start, and you can visit it. If you're using git then create a
.gitignore file similar to that below then commit your work.
/your_site_name/.ghci/ /your_site_name/.stack-work/ /your_site_name/dist/ /database/ /your_site_name/yesod-devel/ /your_site_name/config/client_session_key.aes /your_site_name/.ghci /your_site_name/.dir-locals.el
We're ready to start building a site so please head to part three.