Skip to content

Instantly share code, notes, and snippets.

@dsandstrom
Created August 16, 2017 22:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsandstrom/d1ecdd3f048a5781f842934dea95a1ba to your computer and use it in GitHub Desktop.
Save dsandstrom/d1ecdd3f048a5781f842934dea95a1ba to your computer and use it in GitHub Desktop.
Phoenix deployer using a Docker container to compile
FROM staticfloat/centos-i386:centos6
MAINTAINER Darrell Sandstrom
RUN yum update -y && yum clean all
RUN yum install -y wget && yum clean all
# Install dependencies
RUN yum install -y gcc gcc-c++ glibc-devel make ncurses-devel openssl-devel autoconf java-1.8.0-openjdk-devel git tar && yum clean all
# Install Erlang
ENV ERLANG_VERSION 20.0
RUN wget http://erlang.org/download/otp_src_${ERLANG_VERSION}.tar.gz
RUN tar zxvf otp_src_${ERLANG_VERSION}.tar.gz
RUN cd otp_src_${ERLANG_VERSION} && ./otp_build autoconf && ./configure && make && make install
# Set the locale (en_US.UTF-8)
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
# Build Elixir
ENV ELIXIR_VERSION 1.5.1
WORKDIR /home
RUN git clone https://github.com/elixir-lang/elixir.git
WORKDIR /home/elixir
RUN git checkout refs/tags/v${ELIXIR_VERSION}
RUN make clean install
RUN export PATH="$PATH:/home/elixir/bin"
# Install Hex & Rebar
RUN mix local.hex --force
RUN mix local.rebar --force
# Install Node.js
ENV NODE_VERSION=7.10.1
WORKDIR /home/node
RUN wget https://nodejs.org/download/release/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x86.tar.gz
RUN tar --strip-components 1 -xzvf node-v* -C /usr/local
# Build Phoenix app
# TODO: compile app in separate step, not part of container
RUN mkdir /home/src
WORKDIR /home/src
COPY . /home/src
RUN rm -rf /home/src/_build
RUN rm -rf /home/src/deps
RUN rm -rf /home/src/node_modules
ENV MIX_ENV prod
ENV DEPLOY_ENV prod
RUN mix deps.get --only ${MIX_ENV}
RUN npm install
RUN npm run deploy
RUN MIX_ENV=${MIX_ENV} mix phoenix.digest
RUN MIX_ENV=${MIX_ENV} mix release --env=${DEPLOY_ENV}
WORKDIR /home
#!/bin/bash
APP="tater"
REMOTE_USER="user"
SERVER="server"
RELEASES_DIR="/path/to/releases"
CURRENT_DIR="/path/to/current"
LOG_FILE="tmp/log/deploy.log"
############
VERSION=`awk '/version: \"(.*)\"/{ print $2 }' ./mix.exs | cut -d '"' -f2`
deploy() {
echo -e "Deploying ${APP} v${VERSION} to ${SERVER}"
echo -e "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
touch $LOG_FILE
TMP_DIR="tmp/releases/${VERSION}"
TMP_FILE="${TMP_DIR}/${APP}.tar.gz"
if [ -f $TMP_FILE ]; then
echo -e "~~~> Warning: Compiled app already exists"
else
echo -e "~~~> Compiling in container"
if [[ $(docker ps -q --filter "name=tater") ]]; then
docker rm -f ${APP} > /dev/null
fi
docker build -t ${APP} . >> $LOG_FILE
docker run -it -d --name ${APP} ${APP} >> $LOG_FILE
mkdir -p $TMP_DIR
docker cp $APP:/home/src/_build/prod/rel/$APP/releases/$VERSION/$APP.tar.gz $TMP_FILE
fi
RELEASE_DIR=$RELEASES_DIR/$VERSION
RELEASE_FILE=$RELEASE_DIR/$APP.tar.gz
echo -e "~~~> Deploying to ${SERVER}"
if ssh ${REMOTE_USER}@${SERVER} -- "stat $RELEASE_FILE > /dev/null 2>&1" > /dev/null 2>&1; then
echo -e "~~~> Warning: Current version already deployed"
else
ssh ${REMOTE_USER}@${SERVER} -- "mkdir ${RELEASES_DIR}/${VERSION}" >> $LOG_FILE 2>&1
rsync -r ${TMP_FILE} ${REMOTE_USER}@${SERVER}:${RELEASE_FILE} >> $LOG_FILE 2>&1
fi
if ! ssh ${REMOTE_USER}@${SERVER} -- "stat ${RELEASE_DIR}/bin > /dev/null 2>&1" > /dev/null 2>&1; then
ssh ${REMOTE_USER}@${SERVER} -- "cd ${RELEASE_DIR} && tar xzf ${RELEASE_FILE}" >> $LOG_FILE 2>&1
fi
echo -e "~~~> Restarting app"
stop
ssh ${REMOTE_USER}@${SERVER} -- "rm ${CURRENT_DIR} > /dev/null 2>&1 && ln -s ${RELEASE_DIR} ${CURRENT_DIR}" >> $LOG_FILE 2>&1
start
}
migrate() {
echo -e "--> Running migrations"
ssh ${REMOTE_USER}@${SERVER} -- "${CURRENT_DIR}/bin/${APP} migrate" > /dev/null 2>&1
}
upgrade() {
# echo -e "Upgrading to version ${VERSION}\n"
# ssh ${REMOTE_USER}@${SERVER} -- "cd ${DEPLOY_DIR} && bin/${APP} upgrade ${VERSION}"
echo -e "Not yet implemented"
}
downgrade() {
echo -e "Not yet implemented"
}
start() {
ssh ${REMOTE_USER}@${SERVER} -- "${CURRENT_DIR}/bin/${APP} start" > /dev/null 2>&1
}
stop() {
ssh ${REMOTE_USER}@${SERVER} -- "${CURRENT_DIR}/bin/${APP} stop" > /dev/null 2>&1
}
restart() {
ssh ${REMOTE_USER}@${SERVER} -- "${CURRENT_DIR}/bin/${APP} restart" > /dev/null 2>&1
}
console() {
ssh ${REMOTE_USER}@${SERVER} -- "${CURRENT_DIR}/bin/${APP} remote_console"
}
ping() {
ssh ${REMOTE_USER}@${SERVER} -- "${CURRENT_DIR}/bin/${APP} ping"
}
clean() {
# TODO: remove old versions
echo -e "Not yet implemented"
}
case "$1" in
deploy)
deploy
;;
migrate)
migrate
;;
start)
start
;;
stop)
stop
;;
restart)
restart
;;
upgrade)
upgrade
;;
downgrade)
downgrade
;;
console)
console
;;
ping)
ping
;;
clean)
clean
;;
*)
echo "Usage: $0 {deploy|migrate|upgrade|downgrade|stop|start|restart|clean}" >&2
exit 1
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment