Skip to content

Commit

Permalink
feat: use embed to build single binary (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
dirathea authored Oct 14, 2024
1 parent ca50dc8 commit 46e08b8
Show file tree
Hide file tree
Showing 13 changed files with 125 additions and 33 deletions.
6 changes: 4 additions & 2 deletions .air.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ tmp_dir = "tmp"
bin = "./tmp/main"
cmd = "go build -o ./tmp/main ."
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata", "frontend/node_modules"]
exclude_dir = ["assets", "tmp", "vendor", "testdata", "frontend/node_modules", "docs/node_modules", "node_modules", "dist", "frontend/build"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
Expand All @@ -21,7 +21,9 @@ tmp_dir = "tmp"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = []
pre_cmd = [
"npm run build --workspace=frontend",
]
rerun = false
rerun_delay = 500
send_interrupt = false
Expand Down
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
frontend/build/
5 changes: 5 additions & 0 deletions .github/workflows/next.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- # Add support for more platforms with QEMU (optional)
# https://github.com/docker/setup-qemu-action
name: Set up QEMU
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- # Add support for more platforms with QEMU (optional)
# https://github.com/docker/setup-qemu-action
name: Set up QEMU
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- # Add support for more platforms with QEMU (optional)
# https://github.com/docker/setup-qemu-action
name: Set up QEMU
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ secret/
node_modules

dist/
frontend/build/
31 changes: 26 additions & 5 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ before:
- go mod tidy
# you may remove this if you don't need go generate
- go generate ./...
- npm ci --workspace=frontend
- npm run build --workspace=frontend

builds:
- env:
Expand All @@ -42,13 +44,32 @@ archives:

dockers:
- use: buildx
dockerfile: goreleaser.Dockerfile
image_templates:
- "ghcr.io/dirathea/{{ .ProjectName }}:{{ .Tag }}"
- "ghcr.io/dirathea/{{ .ProjectName }}:v{{ .Major }}"
- "ghcr.io/dirathea/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}"
- "ghcr.io/dirathea/{{ .ProjectName }}:latest"
- "ghcr.io/dirathea/{{ .ProjectName }}:{{ .Tag }}-arm64"
- "ghcr.io/dirathea/{{ .ProjectName }}:v{{ .Major }}-arm64"
- "ghcr.io/dirathea/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}-arm64"
goarch: arm64
build_flag_templates:
- "--platform=linux/amd64,linux/arm64"
- "--platform=linux/arm64"
- use: buildx
dockerfile: goreleaser.Dockerfile
image_templates:
- "ghcr.io/dirathea/{{ .ProjectName }}:{{ .Tag }}-amd64"
- "ghcr.io/dirathea/{{ .ProjectName }}:v{{ .Major }}-amd64"
- "ghcr.io/dirathea/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}-amd64"
build_flag_templates:
- "--platform=linux/amd64"

docker_manifests:
- name_template: "ghcr.io/dirathea/{{ .ProjectName }}:{{ .Tag }}"
image_templates:
- "ghcr.io/dirathea/{{ .ProjectName }}:{{ .Tag }}-amd64"
- "ghcr.io/dirathea/{{ .ProjectName }}:{{ .Tag }}-arm64"
- name_template: "ghcr.io/dirathea/{{ .ProjectName }}:latest"
image_templates:
- "ghcr.io/dirathea/{{ .ProjectName }}:{{ .Tag }}-amd64"
- "ghcr.io/dirathea/{{ .ProjectName }}:{{ .Tag }}-arm64"

changelog:
sort: asc
Expand Down
46 changes: 25 additions & 21 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,38 +1,45 @@
# Stage 1: Build the Go server
FROM golang:1.23-alpine AS server-builder
# Stage 1: Build the Remix frontend
FROM node:20-alpine AS frontend-builder

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy go mod and sum files
COPY go.mod go.sum ./
# Copy package.json and package-lock.json
COPY frontend/package.json frontend/package-lock.json ./

# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download
# Install dependencies
RUN npm install

# Copy the source from the current directory to the Working Directory inside the container
COPY ./ .
COPY frontend/ .

# Build the Go app
RUN go build -o server .
# Build the Remix app
RUN npm run build

# Stage 2: Build the Remix frontend
FROM node:20-alpine AS frontend-builder
# Stage 2: Build the Go server
FROM golang:1.23-alpine AS server-builder

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy package.json and package-lock.json
COPY frontend/package.json frontend/package-lock.json ./
# Copy go mod and sum files
COPY go.mod go.sum ./

# Install dependencies
RUN npm install
# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download

# Copy the source from the current directory to the Working Directory inside the container
COPY frontend/ .
COPY ./ .

# Build the Remix app
RUN npm run build
# Copy the Remix build output from the frontend-builder stage
COPY --from=frontend-builder /app/build ./frontend/build

# Build the Go app
# Ensure the Remix build output exists
RUN if [ ! -f frontend/build/client/index.html ]; then echo "Remix build output not found!"; exit 1; fi

# Build the Go app
RUN go build -o server .

# Stage 3: Create the final image
FROM alpine:latest
Expand All @@ -43,9 +50,6 @@ WORKDIR /app
# Copy the Go server binary from the server-builder stage
COPY --from=server-builder /app/server .

# Copy the Remix build output from the frontend-builder stage
COPY --from=frontend-builder /app/build ./frontend/build

# Expose port 8080 to the outside world
EXPOSE 8080

Expand Down
3 changes: 3 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
"vite": "^5.1.0",
"vite-tsconfig-paths": "^4.2.1"
},
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "4.22.4"
},
"engines": {
"node": ">=20.0.0"
}
Expand Down
13 changes: 13 additions & 0 deletions goreleaser.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Goreleaser Dockerfile
FROM alpine:latest

# Set the Current Working Directory inside the container
WORKDIR /app

COPY pasolo pasolo

# Expose port 8080 to the outside world
EXPOSE 8080

# Command to run the executable
CMD ["./pasolo"]
10 changes: 5 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"bytes"
"embed"
"encoding/json"
"fmt"
"io"
Expand All @@ -11,17 +12,19 @@ import (

"github.com/dirathea/pasolo/pkg/config"
"github.com/dirathea/pasolo/pkg/cookie"
"github.com/dirathea/pasolo/pkg/frontend"
"github.com/dirathea/pasolo/pkg/register"
"github.com/dirathea/pasolo/pkg/session"
"github.com/dirathea/pasolo/pkg/user"
"github.com/go-webauthn/webauthn/webauthn"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)

var (
webAuthn *webauthn.WebAuthn
err error
//go:embed all:frontend/build/client
frontendFs embed.FS
)

func main() {
Expand Down Expand Up @@ -211,10 +214,7 @@ func main() {
return c.JSON(200, "OK")
})

e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
Root: "frontend/build/client",
HTML5: true,
}))
frontend.Setup(e, frontendFs)

address := fmt.Sprintf(":%s", config.Server.Port)

Expand Down
15 changes: 15 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions pkg/frontend/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package frontend

import (
"embed"
"net/http"

"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)

func Setup(e *echo.Echo, fsEmbed embed.FS) {
e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
Root: "frontend/build/client",
Filesystem: http.FS(fsEmbed),
HTML5: true,
}))
}

0 comments on commit 46e08b8

Please sign in to comment.