DEV Community

Jeremy Woertink
Jeremy Woertink

Posted on

Deploying Lucky apps to Elastic Beanstalk

This isn't the prettiest solution, but it's what worked for us. If you have ideas on how to clean this up, I'm all for suggestions.

The setup

  • Developing locally on macOS
  • Production using Elastic Beanstalk container
  • EB container uses Docker

The concept

We had issues getting Crystal's cross compile to work properly, so we had to use a couple extra steps.

  • Boot Docker locally to compile release build of app
  • Move release binary, and required files to temp directory
  • Zip up temp directory to as per EB deployment instructions
  • Use eb command locally to push to EB container

If we happen to get cross-compilation working, we could remove the first two steps in this process.

The code

There's a few files we need to create. I'll define those first, then show the code.

  • ./script/deploy. Be sure to chmod +x ./script/deploy
  • ./docker/BuildDockerfile
  • ./docker/
  • ./docker/Dockerfile
  • ./docker/

Deploy script

Used to actually push the code to production.


set -e

# don't execute next commands on error
trap 'exit' ERR

# let echo interpret escape chars (\n)
shopt -s xpg_echo

START=`date +%s`
DATE=`date '+%Y%m%d@%H%M%S'`
SHA1=`git rev-parse HEAD`
RANDOM=`awk -v min=5 -v max=1000000 'BEGIN{srand(); print int(min+rand()*(max-min+1))}'`

# deploy to production when on master branch
# deploy to staging when on other branches
branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
if [ "$branch" == "master" ]

# Remove the old build
rm -rf build/app

# Build assets
echo "Building Assets"
rm -rf public/assets/* public/mix-manifest.json
yarn prod

# Build the application
echo "Starting Docker"
docker build -t lucky-app-build -f docker/BuildDockerfile .
docker run -v $(pwd)/build:/app/build lucky-app-build

# Create a temporary directory to stage the files
mkdir ${BUILD_DIR}

# Stage the files
cp .env.${STAGE} ${BUILD_DIR}/.env
cp build/app ${BUILD_DIR}
cp -r public ${BUILD_DIR}
cp docker/Dockerfile ${BUILD_DIR}
cp docker/ ${BUILD_DIR}
cp -r .ebextensions ${BUILD_DIR}

# Getting them zipped up
cd ${BUILD_DIR}; zip -Xr * .env .ebextensions; mv ../; cd ..

# Deploy the application
eb deploy --label $LABEL

# Cleanup
rm -rf ${BUILD_DIR}

END=`date +%s`

echo Deploy ended with success! Time elapsed: $((END-START)) seconds
Enter fullscreen mode Exit fullscreen mode


Used for building the release binary

FROM crystallang/crystal:0.29.0

ADD . /app
ADD ./docker/ /app/


RUN shards update && \
    rm -rf /app/build/app && \
    crystal build src/ --release -o app

RUN chmod +x

CMD ["./"]
Enter fullscreen mode Exit fullscreen mode


I honestly don't know why we have this, but it's here, so here it is.


cp app /app/build/
Enter fullscreen mode Exit fullscreen mode


The actual Dockerfile used in production on EB

FROM phusion/baseimage

ENV APP_DOMAIN=localhost
ENV SECRET_KEY_BASE=abc123abc123
ENV LUCKY_ENV=production
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get -q update && \
    apt-get -qy install build-essential libgc-dev libssl-dev libxml2-dev libyaml-dev libevent-dev && \
    apt-get -y install tzdata && \
    apt-get -y autoremove && \
    apt-get -y clean && \
    rm -rf /var/lib/apt/lists/* && \
    rm -rf /tmp/*

RUN mkdir /app

ADD ./app /app
ADD ./.env /app/.env
ADD ./public /app/public



CMD trap exit TERM; ./app & wait
Enter fullscreen mode Exit fullscreen mode


This file is used by EB. Learn more on Single Container Docker for AWS EB.

  "AWSEBDockerrunVersion": "1",
  "Logging": "/var/log/app.log",
  "Ports": [
      "ContainerPort": "8000"
Enter fullscreen mode Exit fullscreen mode

Final Notes

You'll want to make sure you update your .gitignore file with things like:

Enter fullscreen mode Exit fullscreen mode

And lastly, this all assumes you have your elastic beanstalk setup. That would require getting the eb binary installed locally, getting your container setup, and adding in all your config stuff.

Top comments (0)