is a that offers robust solutions for simplifying and enhancing the security and compliance aspects of software applications. Aptible streamlines the complex process of achieving and maintaining industry-standard certifications such as HIPAA, SOC 2, and GDPR. Aptible No Infrastructure Platform Sounds interesting, isn’t it? Like many of you I love to try new things. gives one month of a free trial which is just perfect to poke around. Aptible Let’s assume you have an existing app hosted somewhere (in my case it’s DigitalOcean) and you really want to try out Aptible. I took from my about . There we had a decent yet simple CI/CD pipeline based on Github Action. So let’s go ahead and make it work with Aptible. almost-one-line-spring-boot-app previous article Release Driver Development Aptible provides a nice way to deploy the code right from Git. We will take a closer look down below. Prerequisite Make sure you did next things before moving forward: Add Aptible’s username and password to Github Action’s secrets under and variables accordingly APTIBLE_USERNAME APTIBLE_PASSWORD Make sure to create a new App manually (go to Aptible’s Dashboard → choose your environment → button). The same as DigitialOcean, Aptible doesn’t automatically create an app on the first run. Create App Changing existing pipeline To be able to deploy to Aptible we need to add a new step to our existing Github Actions pipeline. I don’t want to get rid of DigitalOcean step, so let’s add a switcher to the section together with Aptible-related params: env env: # Where to deploy. Options are 'digitalocean' or 'aptible' DEPLOY_TARGET: 'aptible' # Aptible deploy params APTIBLE_ENVIRONMENT: 'google-aeb' APTIBLE_APP: 'deployinator' For the deployment step we are using . It is pretty self explanatory, you just need to specify credentials, what, and where you are deploying. Deploy to Aptible Github Action The step looks like: - name: Deploy to Aptible if: ${{ env.DEPLOY_TARGET == 'aptible' }} uses: aptible/aptible-deploy-action@v1 with: username: ${{ secrets.APTIBLE_USERNAME }} password: ${{ secrets.APTIBLE_PASSWORD }} environment: ${{ env.APTIBLE_ENVIRONMENT }} app: ${{ env.APTIBLE_APP }} docker_img: ${{ secrets.DOCKERHUB_USERNAME }}/deployinator:${{env.RELEASE_VERSION}} Before the actual deployment, the step pulls the image from Dockerhub and pushes into Aptible’s Docker registry. Perfect, let’s try it out. Committing the changes, pushing to master and … this is what we see on the Aptible Dashboard: Troubleshooting (unplanned section) I know, I promised it to be seamless. It will! We just need to figure out a root cause for the failure. I wasn’t able to find any kind of logs neither on the dashboard nor in the Github’s build - it was green. Nothing I could find by googling the error, says: official doc If endpoint provisioning fails, restart your app using the aptible restart command. You will see a prompt asking you to do so. Note this failure is most likely due to an app health check failure. We have troubleshooting instructions here: My deploy failed with HTTP health checks failed The only way to check what exactly has happened is to install and restart the app. Aptible CLI Frankly speaking, installing CLI to get logs is not the friendliest way to understand what’s wrong with the deployment. It would be great if Aptible could provide more insights on the dashboard. > brew install --cask aptible # be ready to provide login/password > aptible login > aptible restart --app deployinator Among other output logs we can find next errors: ... ERROR -- : Your Docker image must EXPOSE a port to provision an Endpoint, add an EXPOSE directive in your Dockerfile. ERROR -- : FAILED: Wait up to 180s for containers in service cmd to respond to HTTP health checks ... We have to add to the Dockerfile to let Aptible know how to configure the endpoint and do the heath checks. We also need to change Spring Boot server’s port accordingly by adding to file. You can take a look at the full code at branch. EXPOSE 80 server.port=80 application.properties deploy-aptible On the second attempt we can see app’s Endpoint automatically created That’s way better. The only thing our app can do is to show the version under endpoint. So, copy the hostname from the endpoint and try it. /version Perfect, it works. Deploy on Git Push Another option I mentioned in the beginning is to deploy by Git Push. To make it work you have to press the button on the Dashboard and go through a pretty straightforward which includes providing your public ssh key and adding Aptible’s Git repo as a remote for your existing repo. The idea here is by pushing into Aptible’s Git remote you trigger (re-)deployment. It’s completely fine to to work with your existing Git repo (named ) as before, but when you need a deploy, just run something like: Deploy Code setup process origin git push aptible main Aptible will find Dockerfile in your repo, build an image based on it, and deploy as a container. Pretty cool, huh? As a small additional bonus, you can see deployment logs right in your console. Seems like we don’t need the Github Actions pipeline anymore. Aptible deploys your app based on what you have in a Git repo. Which is absolutely nice! But it’s only from the first sight. This automated approach works good only for small apps, while having drawbacks working with a bigger one. Think about: How to manage versions as you no longer have CI/CD pipeline? What if you need additional steps (run integration tests, publish artifacts, etc) before deployment? Dockerfile becomes overloaded by extras like because it’s the only thing between you and Aptible. gradlew build Let’s try this out and see how far it will bring us. First of all, we have to make Dockerfile self-sufficient by moving everything inside. By ‘everything‘ I literally mean everything that we had in the pipeline. Take a look at the result and I will explain it down below: # Temp container to run gradle build FROM gradle:latest AS BUILD COPY --chown=gradle:gradle . . USER gradle # Tag current commit with commit's sha for versioning purposes RUN git tag $(git rev-parse --short HEAD) RUN gradle build # Main stage FROM eclipse-temurin:17 EXPOSE 80 COPY --from=BUILD /home/gradle/build/libs/deployinator-*.jar /app/deployinator.jar ENTRYPOINT java -jar /app/deployinator.jar We are using a build. First phase is to build a jar file. To make it happen we start with temporary image, copy all the files inside and run . There is also one trick in here. As we copied the source files, we also have folder inside the image (it is temporary, no worries about extra files). The reasoning behind this is to let access Git tags and provide version info for Gradle. multi-stage gradle:latest gradle build all .git gradle-git-plugin So, the overall deployment flow looks like: You push a branch into Aptible’s Git repo Aptible starts a deployment by doing a of the repo shallow clone Aptible finds Dockerfile and kicks off docker build ... Docker goes over instructions in a Dockerfile and copies everything from a cloned repo inside a container, including a folder .git Command tags current commit with commit hash git tag $(git rev-parse --short HEAD) During gradle-git-plugin fetches last tag and makes it a project version gradle build As build finishes, Aptible triggers and exposes our app to the world on a port defined in the statement. docker run ... EXPOSE Commit hash is not the best option for a project’s version. SemVer or simply buildNumber + gitHash is slightly better (a bit more info about it in a ). previous article However, I couldn’t find a way to access anything similar to buildNumber. Aptible doesn’t seem to add as to docker build command APTIBLE_PROCESS_INDEX metadata variable --build-arg file is not accessible from the container’s root Configuration variable .aptible.env If you were able to find a way to get a sequential build number (or any other config var which might be helpful) from within Dockerfile - let me know in the comments. All the code is available under branch. Now let’s make it deployed by running: deploy-aptible-on-git-push # Check current hash > git rev-parse --short HEAD 703496a # Kick-off deployment > git push aptible deploy-aptible-on-git-push:main Waiting for a little bit and… Perfect, commit hash is the same. We have a dirty flag here which means that Aptible changed (probably added) something after git clone and introduced an unstashed change. It’s worth mentioning that Aptible provides additional configs for Releases, you can take a closer look . here Conclusion Moving a simple app from DigitalOcean to Aptible having a Github Actions pipeline is a pretty easy. You just have to change the deployment step with almost no changes to the code (except explicitly adding http port if necessary). When you have things clearly separated and independent from each other, interchangeability works perfectly. Another way could be setting up deployment on Git Push. It's a very straightforward and nice-looking approach. However, I’m still skeptical about the fact that it’s pretty limited and forces you to concentrate CI/CD actions in a Dockerfile. Which is not something that leads you toward a clear . separation of concerns