feat(rundeck): Initial commit

This commit is contained in:
hygienic-books 2023-06-13 01:58:30 +02:00
parent 085676f21b
commit e5d21d0e6a
13 changed files with 245 additions and 2 deletions

100
README.md
View File

@ -1,3 +1,99 @@
# rundeck # Rundeck Docker Compose files
Docker Rundeck deployment instructions Docker Compose files to spin up an instance of Rundeck.
# How to run
Add a `COMPOSE_ENV` file and save its location as a shell variable along with the location where this repo lives, here for example `/opt/containers/rundeck` plus all other variables. At [env/fqdn_context.env.example](env/fqdn_context.env.example) you'll find an example environment file.
When everything's ready start Rundeck with Docker Compose, otherwise head down to [Initial setup](#initial-setup) first.
## Environment
```
export COMPOSE_DIR='/opt/containers/rundeck'
export COMPOSE_CTX='ux_vilnius'
export COMPOSE_PROJECT='rundeck-'"${COMPOSE_CTX}"
export COMPOSE_FILE="${COMPOSE_DIR}"'/docker-compose.yml'
export COMPOSE_ENV=<add accordingly>
```
## Start
```
docker compose --project-name "${COMPOSE_PROJECT}" --file "${COMPOSE_FILE}" --env-file "${COMPOSE_ENV}" --profile 'full' up --detach
```
# Initial setup
We're assuming you run Docker Compose workloads with ZFS-based bind mounts. ZFS management, creating a zpool and setting adequate properties for its datasets is out of scope of this document.
## Datasets
Create ZFS datasets and set permissions as needed.
* Parent dateset
```
zfs create -o mountpoint=/opt/docker-data 'zpool/docker-data'
```
* Container-specific datasets
```
zfs create -p 'zpool/docker-data/rundeck-'"${COMPOSE_CTX}"'/rundeck'
zfs create -p 'zpool/docker-data/rundeck-'"${COMPOSE_CTX}"'/postgres'
```
* Create subdirs
```
mkdir -p '/opt/docker-data/rundeck-'"${COMPOSE_CTX}"'/rundeck/'{'.ssh','config','data','projects'}
```
* Prefill content
* Rundeck settings in `realm.properties`
At the very least override Rundeck's default `realm.properties` file with one of your own and set a username and a password for local login. Default credentials will otherwise be `admin:admin`. Per [Rundeck's manual on Jetty and JAAS authentication section "PropertyFileLoginModule"](https://docs.rundeck.com/docs/administration/security/authentication.html#propertyfileloginmodule) you're going to need Rundeck's `rundeck.war` file to create a bcrypt hash for your password. Run the official Rundeck Docker image in a throwaway container like so where `rundeck/rundeck:4.13.0` is an example version you want to use:
```
docker run \
--rm \
--tty \
--interactive \
--entrypoint bash \
rundeck/rundeck:4.13.0 \
-c 'java -jar /home/rundeck/rundeck.war --encryptpwd Jetty'
```
This will download `rundeck/rundeck:4.13.0` if needed and open up something along the lines of:
```
Required values are marked with: *
Username (Optional, but necessary for Crypt encoding):
```
Type your desired username, type `<Enter>` and then your plain text password followed by `<Enter>` again. The whole exchange may look like this:
```
Required values are marked with: *
Username (Optional, but necessary for Crypt encoding):
my-username
*Value To Encrypt (The text you want to encrypt):
t0psecr3t
==ENCRYPTED OUTPUT==
bcrypt: BCRYPT:$2a$10$jMWQvKbjpmBrKdA0Qi0/n.UvHot1F7Cvf7/Avlv9afknHpbvT6j7y
obfuscate: OBF:1z0f18qk1xtp1vgv1t331vfz1xtt18qq1z0f
md5: MD5:962aefc8c283c13e13d9c990dafdfba9
crypt: CRYPT:myS5y0c4wMQts
```
Put a single line into an otherwise empty `/opt/docker-data/rundeck-'"${COMPOSE_CTX}"'/rundeck/config/realm.properties`:
```
my-username: BCRYPT:$2a$10$jMWQvKbjpmBrKdA0Qi0/n.UvHot1F7Cvf7/Avlv9afknHpbvT6j7y,user,admin
```
The account `my-username` will have roles `user` and `admin` and it'll be the only existing account when Rundeck starts.
* SSH `known_hosts` file
Place an empty `known_hosts` file at `/opt/docker-data/rundeck-'"${COMPOSE_CTX}"'/rundeck/.ssh/known_hosts`. Feel free to optionally prefill it with SSH public host keys.
* Change ownership
```
chown -R 999 '/opt/docker-data/rundeck-'"${COMPOSE_CTX}"'/postgres'
chown -R 1000 '/opt/docker-data/rundeck-'"${COMPOSE_CTX}"'/rundeck'
```
When done head back up to [How to run](#how-to-run).

View File

@ -0,0 +1,14 @@
# For the remainder of this Dockerfile EXAMPLE_ARG_FOR_DOCKERFILE will be
# available with a value of 'must_be_available_in_dockerfile', check out the env
# file at 'env/fully.qualified.domain.name.example' for reference.
# ARG EXAMPLE_ARG_FOR_DOCKERFILE
# Another env var, this one's needed in the example build step below:
# ARG POSTGRES_VERSION
# Example
# FROM "postgres:${POSTGRES_VERSION}"
# RUN apt-get update && \
# apt-get -y install \
# somepackage-6.q16-6-extra && \
# rm -rf /var/lib/apt/lists/*

View File

View File

@ -0,0 +1,14 @@
# For the remainder of this Dockerfile EXAMPLE_ARG_FOR_DOCKERFILE will be
# available with a value of 'must_be_available_in_dockerfile', check out the env
# file at 'env/fully.qualified.domain.name.example' for reference.
# ARG EXAMPLE_ARG_FOR_DOCKERFILE
# Another env var, this one's needed in the example build step below:
# ARG RUNDECK_VERSION
# Example
# FROM "rundeck:${RUNDECK_VERSION}"
# RUN apt-get update && \
# apt-get -y install \
# somepackage-6.q16-6-extra && \
# rm -rf /var/lib/apt/lists/*

View File

@ -0,0 +1,2 @@
hostname pubkey
another-hostname also-a-pubkey

View File

@ -0,0 +1 @@
my-first-account: BCRYPT:$2a$10$ZcvSOoSNHbnP/foEvJ/6WeKIauGLCr9XCo5.UboJVUJDbHPWrV30K,user,admin

View File

11
common-settings.yml Normal file
View File

@ -0,0 +1,11 @@
services:
common-settings:
environment:
TZ: "${TIMEZONE:-Etc/UTC}"
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "10"
compress: "true"
restart: "${RESTARTPOLICY:-unless-stopped}"

View File

@ -0,0 +1,19 @@
services:
rundeck-build:
image: "rundeck:${RUNDECK_VERSION}"
profiles: ["build", "build-rundeck"]
build:
context: "build-context/rundeck"
dockerfile: Dockerfile
args:
EXAMPLE_ARG_FOR_DOCKERFILE: "${EXAMPLE_ARG_FROM_ENV_FILE}"
RUNDECK_VERSION: "${RUNDECK_VERSION}"
postgres-build:
image: "postgres:${POSTGRES_VERSION}"
profiles: ["build", "build-postgres"]
build:
context: "build-context/postgres"
dockerfile: Dockerfile
args:
EXAMPLE_ARG_FOR_DOCKERFILE: "${EXAMPLE_ARG_FROM_ENV_FILE}"
POSTGRES_VERSION: "${POSTGRES_VERSION}"

54
docker-compose.yml Normal file
View File

@ -0,0 +1,54 @@
services:
rundeck:
image: "rundeck/rundeck:${RUNDECK_VERSION}"
container_name: "rundeck-rundeck-${CONTEXT}"
networks:
rundeck-default:
profiles: ["full", "rundeck"]
extends:
file: common-settings.yml
service: common-settings
tty: true
ports:
- ${RUNDECK_PORT}:4440
volumes:
- /opt/docker-data/rundeck-${CONTEXT}/rundeck/config/realm.properties:/home/rundeck/server/config/realm.properties
- /opt/docker-data/rundeck-${CONTEXT}/rundeck/data:/home/rundeck/server/data
- /opt/docker-data/rundeck-${CONTEXT}/rundeck/projects:/home/rundeck/projects
- /opt/docker-data/rundeck-${CONTEXT}/rundeck/.ssh/known_hosts:/home/rundeck/.ssh/known_hosts
environment:
RUNDECK_DATABASE_DRIVER: org.postgresql.Driver
RUNDECK_DATABASE_USERNAME: rundeck
RUNDECK_DATABASE_PASSWORD: rundeck
RUNDECK_DATABASE_URL: jdbc:postgresql://postgres/rundeck?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
RUNDECK_GRAILS_URL: https://rundeck.ops.loft.seneve.de
RUNDECK_SERVER_FORWARDED: 'true'
TZ: ${TIMEZONE}
postgres:
image: "postgres:${POSTGRES_VERSION}"
container_name: "rundeck-postgres-${CONTEXT}"
networks:
rundeck-default:
profiles: ["full", "postgres"]
extends:
file: common-settings.yml
service: common-settings
volumes:
- /opt/docker-data/rundeck-${CONTEXT}/postgres:/var/lib/postgresql/data
ports:
- ${POSTGRES_PORT}:5432
environment:
POSTGRES_DB: rundeck
POSTGRES_USER: rundeck
POSTGRES_PASSWORD: rundeck
TZ: ${TIMEZONE}
networks:
rundeck-default:
name: rundeck-${CONTEXT}
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
ipam:
driver: default
config:
- subnet: ${SUBNET}

32
env/fqdn_context.env.example vendored Normal file
View File

@ -0,0 +1,32 @@
CONTEXT=ux_vilnius
# Set something sensible here and uncomment
# ---
# RUNDECK_VERSION=x.y.z
# POSTGRES_VERSION=x.y.z
# Feel free to leave defaults. They apply while these vars are commented out
# ---
# RESTARTPOLICY=unless-stopped
# TIMEZONE=Etc/UTC
# Subnet to use for this Docker Compose project. Docker defaults to
# container networks in prefix 172.16.0.0/12 which is 1 million addresses in
# the range from 172.16.0.0 to 172.31.255.255. Docker uses 172.17.0.0/16 for
# itself. Use any sensible prefix in 172.16.0.0/12 here except for Docker's
# own 172.17.0.0/16.
# ---
SUBNET=172.30.95.0/24
# See 'docker-compose.override.yml' for how to make a variable available in
# a Dockerfile
# ---
# EXAMPLE_ARG_FROM_ENV_FILE=must_be_available_in_dockerfile