Containerizing and deploying a Go application with seelf
Tags: docker, tutorial, opensource, go
Published: 2023-06-05 09:27:11

Going from a locally running project to a remote deployment available to users can sometimes feel frustrating, especially if your needs are simple.

Today, I'll show you how you can take a tiny Golang application, containerize it using a `Dockerfile` and a `compose.yml` file, and deploy it without frustration using a tiny open-source project I've made: [seelf](https://github.com/YuukanOO/seelf).

## First things first, our toy application

So you're a developer and you came up with a fantastic application idea: a tiny Golang application with outputs the number of times it has been started. To make things interesting, you also had decided to logs the application start time in a PostgreSQL database.

_Note: This application is available at: https://github.com/YuukanOO/seelf-go-tutorial and each step has its own branch._

So you make this application, runs it locally with an instance of PostgreSQL and everything is fine, you're proud of you (and you should always be)!

## Here comes Docker

As you know containerizing an application is a great way to deploy and share it easily, you come up with this `Dockerfile`:

```
FROM golang:1.20-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN go build -ldflags="-s -w" -o sample

FROM alpine:3.16
WORKDIR /app
COPY --from=builder /app/sample ./
EXPOSE 8080
CMD ["./sample"]
```

And a `compose.yml` file to launch all your application stack in one command:

```yml
services:
  app:
    build: .
    restart: unless-stopped
    environment:
      - DATABASE_URL=postgresql://dbuser:dbpass@db:5432/sample?sslmode=disable
    ports:
      - 8080:8080
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres:15-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: dbuser
      POSTGRES_PASSWORD: dbpass
      POSTGRES_DB: sample
    healthcheck:
      test: pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}
      interval: 5s
      timeout: 5s
      retries: 5
    volumes:
      - dbdata:/var/lib/postgresql/data

volumes:
  dbdata:
```

Now, you can run `docker compose up -d --wait --build` and your application is available at http://localhost:8080.

## Going live with seelf

And now, you really want to share this amazing app with the world. Since you really like self-hosting, you have deployed [seelf](https://github.com/YuukanOO/seelf/blob/main/DOCUMENTATION.md#installation) on a tiny VPS.

seelf is a **lightweight self-hosting deployment** platform written in **Go** which takes a compose file and deploy an application stack, exposing services at nice URLs and managing certificates so you don't have to.

So you start by creating an application on your seelf instance by clicking on the _New application_ button.

![seelf homepage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ycphz3qfhw3loe98iqu7.png)

You fill the provided form with a nice name for your application (as this will determine the subdomain used), the git repository url, and set production environment variables for the `app` and `db` services which will overwrite the default ones defined in the `compose.yml` file.

![seelf new application form](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jpgk8if6a4hbrb7pz0i3.png)

You click _Create_ and on the next screen, the _New deployment_ button will ask you what kind of deployment you want to trigger for your newly created application.

![seelf new deployment page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/npss7te82gtqz6mwf2d6.png)

You choose `git` as the deployment kind since your application is hosted on [github](https://github.com/YuukanOO/seelf-go-tutorial/tree/containerizing) and enter the branch you want to deploy (`containerizing` in this example).

After a few seconds, the deployment should be complete and your application available.

![seelf successful deployment](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9hspsnlzn39gc0asqhiu.png)

Clicking the `app` link in the _deployed services_ section of the deployment will open a new page to your live application!

![your application is live](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1gfdgm536c4is4luzrit.png)

Congratulations, you have successfuly deployed your first application with **seelf**!

_seelf is in its early stage but you can check the [roadmap](https://github.com/YuukanOO/seelf/milestone/1) to see what's planned. Thanks for taking the time to read this ;)_