Skip to content

Commit

Permalink
Optimize Dockerfile + move to CircleCI (#11)
Browse files Browse the repository at this point in the history
* Optimize RUN commands in Dockerfile

* Update README instructions

* Add circleCI config

* Add workflow to enable github status check

* Install goss, beautiful circleci

* Fix goss tests for updated Dockerfile

* Fix goss tests again

* Updated Makefile commands

* Last try getting CircleCI to build the correct image
  • Loading branch information
artis3n authored Sep 11, 2020
1 parent 98b3c27 commit a088ea6
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 95 deletions.
36 changes: 36 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
version: 2.1
jobs:
build:
machine:
image: ubuntu-1604:202007-01
steps:
- checkout
- run: git submodule sync
- run: git submodule update --init
- run:
name: Open Xserver connections
command: 'xhost +local:'
- run:
name: Install dependencies
command: |
sudo apt-get install build-essential
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
brew install dive
curl -fsSL https://goss.rocks/install | sudo sh
- run:
name: Build the image
command: make build
- run:
name: Goss tests
command: make test
- run:
name: Close Xserver connections
command: 'xhost -local:'
when: always

workflows:
version: 2
test:
jobs:
- build
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.github
.circleci
.gitmodules
.hadolint.yaml
.pre-commit-config.yaml
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: CI

on:
pull_request:
branches:
- main

env:
TAG: githubci

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true

- name: Lint Dockerfile
uses: brpaz/hadolint-action@eb9b96be611b84830aa1babacfb7070ecd2a8b1b # v1.1.0
6 changes: 3 additions & 3 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
with:
submodules: true

- name: Deploy the Docker image to GitHub Container Registry
- name: Deploy the Docker image to GitHub Container Registry - Semver
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: artis3n/pgmodeler
Expand All @@ -24,7 +24,7 @@ jobs:
registry: ghcr.io
tag_semver: true

- name: Deploy the Docker image to GitHub Package Registry - Latest
- name: Deploy the Docker image to GitHub Container Registry - Latest
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: artis3n/pgmodeler
Expand All @@ -33,7 +33,7 @@ jobs:
registry: ghcr.io
tags: "latest"

- name: Deploy the Docker image to Docker Hub
- name: Deploy the Docker image to Docker Hub - Semver
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: artis3n/pgmodeler
Expand Down
42 changes: 0 additions & 42 deletions .github/workflows/main.yml

This file was deleted.

47 changes: 27 additions & 20 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,39 @@ RUN apt-get update \
&& apt-get autoclean -y \
# Remove apt-get cache from the layer to reduce container size
&& rm -rf /var/lib/apt/lists/*
RUN "$QMAKE_PATH" -version && pkg-config libpq --cflags --libs

# Copy project files
RUN mkdir /app
COPY ./pgmodeler ./pgmodeler
COPY ./plugins ./pgmodeler/plugins
COPY ./pgmodeler /pgmodeler
COPY ./plugins /pgmodeler/plugins

# Set up non-root user
RUN groupadd -r modeler \
&& useradd -m --no-log-init -u 1000 -g modeler modeler
RUN chown -R modeler:modeler /app \
&& chown -R modeler:modeler /pgmodeler
USER modeler
RUN groupadd -g 1000 modeler \
&& useradd -m -l -u 1000 -g modeler modeler

WORKDIR /pgmodeler
RUN "$QMAKE_PATH" -r CONFIG+=release \
PREFIX="$INSTALLATION_ROOT" \
BINDIR="$INSTALLATION_ROOT" \
PRIVATEBINDIR="$INSTALLATION_ROOT" \
PRIVATELIBDIR="$INSTALLATION_ROOT/lib" \
pgmodeler.pro

RUN make && make install
# Add persistence folder for project work
RUN mkdir /app/savedwork \
&& chown -R modeler:modeler /app/savedwork
RUN mkdir /app \
# Add persistence folder for project work
&& mkdir /app/savedwork \
# Configure qmake for compilation
&& "$QMAKE_PATH" -version \
&& pkg-config libpq --cflags --libs \
&& "$QMAKE_PATH" -r CONFIG+=release \
PREFIX="$INSTALLATION_ROOT" \
BINDIR="$INSTALLATION_ROOT" \
PRIVATEBINDIR="$INSTALLATION_ROOT" \
PRIVATELIBDIR="$INSTALLATION_ROOT/lib" \
pgmodeler.pro \
# Compile PgModeler - will take about 20 minutes
&& make \
&& make install \
# Clean up source code after compilation succeeds
# We no longer need it in the container
&& rm -rf /pgmodeler \
# Make modeler user owner of the compiled app
&& chown -R modeler:modeler /app

USER modeler
WORKDIR /app

ENV QT_X11_NO_MITSHM=1
ENV QT_GRAPHICSSYSTEM=native
Expand Down
12 changes: 4 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,19 @@ size:
test:
xhost +local:
mkdir -p /tmp/saves; touch /tmp/saves/exist.txt
dgoss run -it --rm -e DISPLAY=$$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v /tmp/saves:/app/savedwork artis3n/pgmodeler:$${TAG:-test}
dgoss run -it --rm -e DISPLAY --cap-drop=all -v /tmp/.X11-unix:/tmp/.X11-unix -v /tmp/saves:/app/savedwork artis3n/pgmodeler:$${TAG:-test}
CI=true dive artis3n/pgmodeler:$${TAG:-test}
xhost -local:

.PHONY: test-edit
test-edit:
xhost +local:
dgoss edit -it --rm -e DISPLAY=$$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix artis3n/pgmodeler:$${TAG:-test}
xhost -local:
mkdir -p /tmp/saves; touch /tmp/saves/exist.txt
dgoss edit -it --rm -e DISPLAY --cap-drop=all -v /tmp/.X11-unix:/tmp/.X11-unix -v $$(xauth info | grep "Authority file" | awk '{ print $$3 }'):/home/modeler/.Xauthority:ro -v /tmp/saves:/app/savedwork artis3n/pgmodeler:$${TAG:-test}

.PHONY: build
build:
docker build . -t artis3n/pgmodeler:$${TAG:-test}

.PHONY: run
run:
xhost +local:
mkdir -p /tmp/saves
docker run -it --rm -e DISPLAY=$$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v /tmp/saves:/app/savedwork artis3n/pgmodeler:$${TAG:-latest}
xhost -local:
docker run -it --rm -e DISPLAY --cap-drop=all -v /tmp/.X11-unix:/tmp/.X11-unix -v $$(xauth info | grep "Authority file" | awk '{ print $$3 }'):/home/modeler/.Xauthority:ro -v $${WORK:-~/Documents}:/app/savedwork artis3n/pgmodeler:$${TAG:-test}
47 changes: 32 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# artis3n/pgmodeler

[![GitHub release (latest by date)](https://img.shields.io/github/v/release/artis3n/pgmodeler-container?style=flat-square)](https://github.com/users/artis3n/packages/container/pgmodeler)
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/artis3n/pgmodeler-container/Test?style=flat-square)](https://github.com/artis3n/pgmodeler-container/actions)
![CircleCI](https://img.shields.io/circleci/build/github/artis3n/pgmodeler-container/main?style=flat-square)
![GitHub last commit](https://img.shields.io/github/last-commit/artis3n/pgmodeler-container?style=flat-square)
![GitHub](https://img.shields.io/github/license/artis3n/pgmodeler-container?style=flat-square)
![GitHub followers](https://img.shields.io/github/followers/artis3n?style=social)
![Twitter Follow](https://img.shields.io/twitter/follow/artis3n?style=social)

Docker image wrapping [pgmodeler/pgmodeler][pgmodeler repo]. Unlike other containers I've seen for this project, this container is **_secure by default_**. There is no `--privileged` or any capabilities passed to the container. There is a non-root user. You get the graphical interface for PGModeler and can save project files to a specified volume for persistence.
Docker image wrapping [pgmodeler/pgmodeler][pgmodeler repo]. Unlike other containers I've seen for this project, this container is **_secure by default_**. There is no `--privileged` or any capabilities passed to the container. There is a non-root user. You don't over-expose your Xserver. You get the graphical interface for PGModeler and can save project files to a specified volume for persistence with peace of mind.

Download from GitHub Container Registry or Docker Hub:

Expand All @@ -16,23 +16,37 @@ docker pull ghcr.io/artis3n/pgmodeler:latest
docker pull artis3n/pgmodeler:latest
```

I wrote an article explaining in detail how I set up this container to be secure.
Check it out!

## Usage

Run the container:
First, discover the location of your `.Xauthority` file.
See the above article for details on what we are doing here if you are not familiar and are interested.
Then run the container (dropping all of Docker's default Linux capabilities, as they are not needed).

```bash
xhost +local:
docker run -it --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix ghcr.io/artis3n/pgmodeler:latest
xhost -local:
XAUTHORITY=$(xauth info | grep "Authority file" | awk '{ print $3 }')

docker run -it --rm --cap-drop=all \
-e DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix:ro \
-v $XAUTHORITY:/home/modeler/.Xauthority:ro \
ghcr.io/artis3n/pgmodeler:latest
```

| :exclamation: To persist your project data, be sure to mount a directory to `/app/savedwork` |
| --- |

```bash
xhost +local:
docker run -it --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v /persistent/local/directory/for/project:/app/savedwork ghcr.io/artis3n/pgmodeler:latest
xhost -local:
XAUTHORITY=$(xauth info | grep "Authority file" | awk '{ print $3 }')

docker run -it --rm --cap-drop=all \
-e DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix:ro \
-v $XAUTHORITY:/home/modeler/.Xauthority:ro \
-v /persistent/local/directory/for/project:/app/savedwork \
ghcr.io/artis3n/pgmodeler:latest
```

Then, while working in PGModeler, be sure to save your project files to `/app/savedwork`. Done!
Expand All @@ -52,17 +66,20 @@ The steps are:

```bash
# Check to make sure your WiFi device is en0. If not, replace en0 with the appropriate device.
IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
# 'echo $IP' should show your IP address, e.g. 192.168.1.X
export DISPLAY=$IP:0
export DISPLAY=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}'):0
```

Now you can run the container with the regular instructions:

```bash
xhost +local:
docker run -it --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v /persistent/local/directory/for/project:/app/savedwork ghcr.io/artis3n/pgmodeler:latest
xhost -local:
XAUTHORITY=$(xauth info | grep "Authority file" | awk '{ print $3 }')

docker run -it --rm --cap-drop=all \
-e DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix:ro \
-v $XAUTHORITY:/home/modeler/.Xauthority:ro \
-v /persistent/local/directory/for/project:/app/savedwork \
ghcr.io/artis3n/pgmodeler:latest
```

[pgmodeler repo]: https://github.com/pgmodeler/pgmodeler
Expand Down
10 changes: 3 additions & 7 deletions goss.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
file:
/pgmodeler:
exists: true
owner: modeler
group: modeler
filetype: directory
/pgmodeler/plugins:
exists: true
owner: modeler
group: modeler
filetype: directory
size: 0
/app/pgmodeler:
exists: true
filetype: file
Expand All @@ -17,6 +11,8 @@ file:
/app/savedwork:
exists: true
filetype: directory
owner: modeler
group: modeler
/app/savedwork/exist.txt:
exists: true
filetype: file
Expand Down

0 comments on commit a088ea6

Please sign in to comment.