Migrate from Docker on Debian to Podman on Rocky

- Upgrade base OS from Debian 11 to Rocky Linux 9
- Configure 100GB XFS filesystem with auto-expansion
- Replace Docker with rootless Podman for improved security
- Add nginx reverse proxy for non-privileged port handling
- Move the Traefik dashboard from port 8443 to 9443
- Configure SELinux contexts for container operations
This commit is contained in:
Kris Lamoureux 2025-06-08 22:14:49 -04:00
parent 236ec455cc
commit d2473533d5
Signed by: kris
GPG Key ID: 105B748C1362EB96
17 changed files with 344 additions and 127 deletions

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
.ansible_vault .ansible*
.bitwarden .bitwarden
environments environments
*.log *.log

View File

@ -1,7 +1,9 @@
SHELL := /bin/bash
all: vagrant all: vagrant
vagrant: vagrant:
vagrant up --no-destroy-on-error --no-color | tee ./vagrantup.log set -o pipefail; vagrant up --no-destroy-on-error --no-color | tee ./vagrantup.log
./scripts/forward-ssh.sh ./scripts/forward-ssh.sh
clean: clean:

View File

@ -1,19 +1,22 @@
# Free I.T. Athen's Infrastructure # Free I.T. Athen's Infrastructure
This project is used to develop Ansible for deploying and maintaining websites This project is used to develop Ansible for deploying and maintaining websites
and services operated by Free I.T. Athens (FRITA). and services operated by Free I.T. Athens (FRITA).
- Requires GNU Make, Ansible, and Vagrant on the host - Requires GNU Make, Ansible, and Vagrant on the host
## Quick Start ## Quick Start
1. Clone this project 1. Clone this project
2. Run `make` to provision a Debian 11 base box 2. Run `make` to provision a Rocky 9 base box
3. Go to 3. Go to
- [Traefik Dashboard](https://traefik.local.freeitathens.org:8443/dashboard/#/) - [Traefik Dashboard](https://traefik.local.freeitathens.org:9443/dashboard/#/)
- [WordPress](https://www.local.freeitathens.org) - [WordPress](https://www.local.freeitathens.org)
- [Nextcloud](https://cloud.local.freeitathens.org) - [Nextcloud](https://cloud.local.freeitathens.org)
4. Click through the HTTPS security warning 4. Click through the HTTPS security warning
## Production ## Production
1. Clone [production-env](https://github.com/freeitathens/production-env/) to `./environments` 1. Clone [production-env](https://github.com/freeitathens/production-env/) to `./environments`
``` ```
@ -32,6 +35,7 @@ and services operated by Free I.T. Athens (FRITA).
5. Delete the `.ansible_vault` file when you are done 5. Delete the `.ansible_vault` file when you are done
### Using Ansible Vault to add or rotate values ### Using Ansible Vault to add or rotate values
Do not submit ciphertext into Ansible Vault with the indention formatting.<br /> Do not submit ciphertext into Ansible Vault with the indention formatting.<br />
To submit, press `CTRL+d` twice. To submit, press `CTRL+d` twice.
@ -46,13 +50,16 @@ To submit, press `CTRL+d` twice.
``` ```
ansible-vault encrypt --vault-pass-file .ansible_vault ansible-vault encrypt --vault-pass-file .ansible_vault
``` ```
- e.g., `pwgen -s 100 1 | ansible-vault encrypt --vault-pass-file .ansible_vault` - e.g., `pwgen -s 100 1 | ansible-vault encrypt --vault-pass-file .ansible_vault`
## Authors ## Authors
* **Kris Lamoureux** - *Project Founder* - [@krislamo](https://github.com/krislamo)
- **Kris Lamoureux** - _Project Founder_ - [@krislamo](https://github.com/krislamo)
## Copyrights and Licenses ## Copyrights and Licenses
Copyright (C) 2019, 2020, 2022 Free I.T. Athens
Copyright (C) 2019, 2020, 2022, 2023, 2025 Free I.T. Athens
This program is free software: you can redistribute it and/or modify it under This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software

24
Vagrantfile vendored
View File

@ -14,9 +14,13 @@ else
File.write(".playbook", PLAYBOOK) File.write(".playbook", PLAYBOOK)
end end
# Debian 11 # Optionally allow more verbosity in Ansible
VAGRANT_ANSIBLE_VERBOSE=ENV["VAGRANT_ANSIBLE_VERBOSE"] || false
Vagrant.configure("2") do |config| Vagrant.configure("2") do |config|
config.vm.box = "debian/bullseye64" config.vm.box = "rockylinux/9"
config.vm.hostname = "fritadev"
config.vm.disk :disk, size: "100GB", primary: true
config.vm.synced_folder ".", "/vagrant", disabled: true config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.network "private_network", type: "dhcp" config.vm.network "private_network", type: "dhcp"
@ -29,6 +33,7 @@ Vagrant.configure("2") do |config|
libvirt.cpus = 2 libvirt.cpus = 2
libvirt.memory = 4096 libvirt.memory = 4096
libvirt.default_prefix = "" libvirt.default_prefix = ""
libvirt.machine_virtual_size = 100
end end
# Set VirtualBox settings # Set VirtualBox settings
@ -37,11 +42,24 @@ Vagrant.configure("2") do |config|
vbox.memory = 4096 vbox.memory = 4096
end end
# Expand XFS rootfs
config.vm.provision "shell", inline: <<-SHELL
set -xe
df -h /
dnf install -y cloud-utils-growpart
PART="$(findmnt -n -o SOURCE /)"
DISK="$(lsblk -n -o PKNAME "$PART")"
NUM="$(lsblk -n -o KNAME "$PART" | sed 's/.*[^0-9]//')"
growpart "/dev/$DISK" "$NUM" && \
xfs_growfs /
df -h /
SHELL
# Provision with Ansible # Provision with Ansible
config.vm.provision "ansible" do |ansible| config.vm.provision "ansible" do |ansible|
ENV['ANSIBLE_ROLES_PATH'] = File.dirname(__FILE__) + "/roles" ENV['ANSIBLE_ROLES_PATH'] = File.dirname(__FILE__) + "/roles"
ansible.compatibility_mode = "2.0" ansible.compatibility_mode = "2.0"
ansible.playbook = "dev/" + PLAYBOOK + ".yml" ansible.playbook = "dev/" + PLAYBOOK + ".yml"
ansible.verbose = VAGRANT_ANSIBLE_VERBOSE
end end
end end

View File

@ -3,4 +3,4 @@ inventory = ./environments/development
interpreter_python = /usr/bin/python3 interpreter_python = /usr/bin/python3
[ssh_connection] [ssh_connection]
pipelining=True pipelining = True

View File

@ -9,10 +9,14 @@ secret:
NEXTCLOUD_ADMIN_PASSWORD: NCadm1npa55w0rd! NEXTCLOUD_ADMIN_PASSWORD: NCadm1npa55w0rd!
############## ##############
### Docker ### ### Common ###
############## ##############
docker_users: users:
- vagrant oci:
uid: 2000
gid: 2000
home: true
ansible_temp: true
################ ################
#### MariaDB ### #### MariaDB ###
@ -30,12 +34,12 @@ webserver:
############### ###############
### Traefik ### ### Traefik ###
############### ###############
#TRAEFIK_VERSION: latest # TRAEFIK_VERSION: latest
#TRAEFIK_ROOT_DOMAIN: local.freeitathens.org # TRAEFIK_ROOT_DOMAIN: local.freeitathens.org
#TRAEFIK_DOMAIN: traefik.local.freeitathens.org # TRAEFIK_DOMAIN: traefik.local.freeitathens.org
#TRAEFIK_DASHBOARD: true # TRAEFIK_DASHBOARD: true
#TRAEFIK_EXPOSED_DEFAULT: false # TRAEFIK_EXPOSED_DEFAULT: false
#TRAEFIK_WEB_ENABLED: true # TRAEFIK_WEB_ENABLED: true
TRAEFIK_DEBUG: true TRAEFIK_DEBUG: true
TRAEFIK_ACME_PROVIDER: dreamhost TRAEFIK_ACME_PROVIDER: dreamhost
TRAEFIK_ACME_CASERVER: https://localhost/directory TRAEFIK_ACME_CASERVER: https://localhost/directory
@ -45,23 +49,23 @@ webserver:
################# #################
### WordPress ### ### WordPress ###
################# #################
#WORDPRESS_VERSION: latest # WORDPRESS_VERSION: latest
#WORDPRESS_DOMAIN: www.local.freeitathens.org # WORDPRESS_DOMAIN: www.local.freeitathens.org
#WORDPRESS_DB_HOST: host.docker.internal # WORDPRESS_DB_HOST: host.docker.internal
#WORDPRESS_DB_NAME: wordpress # WORDPRESS_DB_NAME: wordpress
#WORDPRESS_DB_USER: wordpress # WORDPRESS_DB_USER: wordpress
#WORDPRESS_WEB_ENABLED: true # WORDPRESS_WEB_ENABLED: true
WORDPRESS_DB_PASSWORD: "{{ secret.WORDPRESS_DB_PASSWORD }}" WORDPRESS_DB_PASSWORD: "{{ secret.WORDPRESS_DB_PASSWORD }}"
################# #################
### Nextcloud ### ### Nextcloud ###
################# #################
#NEXTCLOUD_VERSION: stable # NEXTCLOUD_VERSION: stable
#NEXTCLOUD_DOMAIN: cloud.local.freeitathens.org # NEXTCLOUD_DOMAIN: cloud.local.freeitathens.org
#NEXTCLOUD_MYSQL_HOST: host.docker.internal # NEXTCLOUD_MYSQL_HOST: host.docker.internal
#NEXTCLOUD_MYSQL_DATABASE: nextcloud # NEXTCLOUD_MYSQL_DATABASE: nextcloud
#NEXTCLOUD_MYSQL_USER: nextcloud # NEXTCLOUD_MYSQL_USER: nextcloud
#NEXTCLOUD_WEB_ENABLED: true # NEXTCLOUD_WEB_ENABLED: true
#NEXTCLOUD_ADMIN: admin # NEXTCLOUD_ADMIN: admin
NEXTCLOUD_ADMIN_PASSWORD: "{{ secret.NEXTCLOUD_ADMIN_PASSWORD }}" NEXTCLOUD_ADMIN_PASSWORD: "{{ secret.NEXTCLOUD_ADMIN_PASSWORD }}"
NEXTCLOUD_MYSQL_PASSWORD: "{{ secret.NEXTCLOUD_MYSQL_PASSWORD }}" NEXTCLOUD_MYSQL_PASSWORD: "{{ secret.NEXTCLOUD_MYSQL_PASSWORD }}"

View File

@ -5,5 +5,5 @@
- vars/webserver.yml - vars/webserver.yml
roles: roles:
- common - common
- docker - podman
- webserver - webserver

View File

@ -1,4 +1,5 @@
packages: common_packages:
- dnsutils - dnsutils
- ncdu - ncdu
- tree - tree
- vim

View File

@ -2,35 +2,87 @@
ansible.builtin.file: ansible.builtin.file:
path: "~/.ansible/tmp" path: "~/.ansible/tmp"
state: directory state: directory
mode: 0700 mode: "755"
- name: Create system user groups
ansible.builtin.group:
name: "{{ item.key }}"
gid: "{{ item.value.gid }}"
state: present
loop: "{{ users | dict2items }}"
loop_control:
label: "{{ item.key }}"
when: users is defined
- name: Create system users
ansible.builtin.user:
name: "{{ item.key }}"
state: present
uid: "{{ item.value.uid }}"
group: "{{ item.value.gid }}"
groups: "{{ item.value.groups | default([]) }}"
shell: "{{ item.value.shell | default('/bin/bash') }}"
create_home: "{{ item.value.home | default(false) }}"
home: "{{ item.value.homedir | default('/home/' + item.key) }}"
system: "{{ item.value.system | default(false) }}"
loop: "{{ users | dict2items }}"
loop_control:
label: "{{ item.key }}"
when: users is defined
- name: Create Ansible's temporary remote directory for users
ansible.builtin.file:
path: "{{ item.value.homedir | default('/home/' + item.key) }}/.ansible/tmp"
state: directory
mode: "755"
owner: "{{ item.key }}"
group: "{{ item.value.gid }}"
loop: "{{ users | dict2items }}"
loop_control:
label: "{{ item.key }}"
when:
- users is defined
- item.value.ansible_temp | default(false)
- name: Install EPEL repository
ansible.builtin.dnf:
name: epel-release
state: present
update_cache: true
- name: Install useful software - name: Install useful software
ansible.builtin.apt: ansible.builtin.dnf:
name: "{{ packages }}" name: "{{ common_packages }}"
state: present state: present
update_cache: true update_cache: true
- name: Install the Uncomplicated Firewall - name: Install firewalld
ansible.builtin.apt: ansible.builtin.dnf:
name: ufw name: firewalld
state: present state: present
update_cache: true
- name: Deny incoming traffic by default - name: Start and enable firewalld service
community.general.ufw: ansible.builtin.systemd:
default: deny name: firewalld
direction: incoming state: started
enabled: true
- name: Allow outgoing traffic by default - name: Set default zone to drop (deny incoming by default)
community.general.ufw: ansible.posix.firewalld:
default: allow zone: drop
direction: outgoing
- name: Allow OpenSSH with rate limiting
community.general.ufw:
name: ssh
rule: limit
- name: Enable firewall
community.general.ufw:
state: enabled state: enabled
permanent: true
immediate: true
- name: Allow SSH in drop zone with rate limiting via rich rule
ansible.posix.firewalld:
zone: drop
rich_rule: 'rule service name="ssh" accept limit value="10/m"'
permanent: true
immediate: true
state: enabled
- name: Set drop as the default zone
ansible.builtin.command:
cmd: firewall-cmd --set-default-zone=drop
changed_when: false

View File

@ -0,0 +1,4 @@
- name: Restart systemd-logind
ansible.builtin.systemd:
name: systemd-logind
state: restarted

View File

@ -0,0 +1,49 @@
- name: Install Podman
ansible.builtin.dnf:
name: ["podman", "podman-docker", "podman-compose"]
state: present
- name: Create /etc/containers/nodocker to quiet CLI emulation notice
ansible.builtin.file:
path: /etc/containers/nodocker
state: touch
mode: "644"
- name: Create logind.conf.d directory
ansible.builtin.file:
path: /etc/systemd/logind.conf.d
state: directory
mode: "755"
- name: Create linger directory
ansible.builtin.file:
path: /var/lib/systemd/linger
state: directory
mode: "755"
- name: Enable lingering for oci user
ansible.builtin.file:
path: /var/lib/systemd/linger/oci
state: touch
mode: "644"
notify: Restart systemd-logind
- name: Force handler execution for user lingering
ansible.builtin.meta: flush_handlers
- name: Create user systemd directory
ansible.builtin.file:
path: "/home/oci/.config/systemd/user"
state: directory
mode: "755"
owner: oci
group: oci
- name: Enable oci's podman socket
ansible.builtin.systemd:
name: podman.socket
enabled: true
state: started
scope: user
become_user: oci
become: true

View File

@ -1,5 +1,3 @@
version: '3.5'
volumes: volumes:
wordpress: wordpress:
nextcloud: nextcloud:
@ -10,8 +8,10 @@ networks:
services: services:
traefik: traefik:
image: traefik:${TRAEFIK_VERSION:-latest} image: ${TRAEFIK_IMAGE:-docker.io/library/traefik}:${TRAEFIK_VERSION:-latest}
restart: always restart: always
security_opt:
- label=type:container_runtime_t
command: command:
- --api.dashboard=${TRAEFIK_DASHBOARD:-true} - --api.dashboard=${TRAEFIK_DASHBOARD:-true}
- --api.debug=${TRAEFIK_DEBUG:-false} - --api.debug=${TRAEFIK_DEBUG:-false}
@ -20,7 +20,7 @@ services:
- --providers.docker.exposedbydefault=${TRAEFIK_EXPOSED_DEFAULT:-false} - --providers.docker.exposedbydefault=${TRAEFIK_EXPOSED_DEFAULT:-false}
- --entrypoints.web.address=:80 - --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443 - --entrypoints.websecure.address=:443
- --entrypoints.local.address=:8443 - --entrypoints.local.address=:9443
- --entrypoints.web.http.redirections.entrypoint.to=websecure - --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https - --entrypoints.web.http.redirections.entrypoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true - --entrypoints.web.http.redirections.entrypoint.permanent=true
@ -33,11 +33,11 @@ services:
environment: environment:
DREAMHOST_API_KEY: ${TRAEFIK_DREAMHOST_APIKEY} DREAMHOST_API_KEY: ${TRAEFIK_DREAMHOST_APIKEY}
ports: ports:
- 80:80 - "${ENTRYWEB:-127.0.0.1:8080}:80"
- 443:443 - "${ENTRYSECURE:-127.0.0.1:8443}:443"
- "127.0.0.1:8443:8443" - "${ENTRYLOCAL:-127.0.0.1:9443}:9443"
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - ${OCI_SOCK:-/run/user/2000/podman/podman.sock}:/var/run/docker.sock:ro,Z
- ./.acme:/etc/letsencrypt - ./.acme:/etc/letsencrypt
labels: labels:
traefik.http.routers.api.rule: Host(`${TRAEFIK_DOMAIN:-traefik.local.freeitathens.org}`) traefik.http.routers.api.rule: Host(`${TRAEFIK_DOMAIN:-traefik.local.freeitathens.org}`)
@ -52,7 +52,7 @@ services:
- traefik - traefik
wordpress: wordpress:
image: wordpress:${WORDPRESS_VERSION:-latest} image: ${WORDPRESS_IMAGE:-docker.io/library/wordpress}:${WORDPRESS_VERSION:-latest}
restart: always restart: always
environment: environment:
WORDPRESS_DB_HOST: ${WORDPRESS_DB_HOST:-host.docker.internal} WORDPRESS_DB_HOST: ${WORDPRESS_DB_HOST:-host.docker.internal}
@ -81,7 +81,7 @@ services:
- host.docker.internal:host-gateway - host.docker.internal:host-gateway
nextcloud: nextcloud:
image: nextcloud:${NEXTCLOUD_VERSION:-stable} image: ${NEXTCLOUD_IMAGE:-docker.io/library/nextcloud}:${NEXTCLOUD_VERSION:-stable}
restart: always restart: always
environment: environment:
MYSQL_HOST: ${NEXTCLOUD_MYSQL_HOST:-host.docker.internal:3306} MYSQL_HOST: ${NEXTCLOUD_MYSQL_HOST:-host.docker.internal:3306}

View File

@ -0,0 +1,22 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
stream {
server {
listen 80;
proxy_pass 127.0.0.1:8080;
}
server {
listen 443;
proxy_pass 127.0.0.1:8443;
}
}

View File

@ -1,14 +1,38 @@
- name: Restart nginx
ansible.builtin.systemd:
name: nginx
state: restarted
- name: Restart MariaDB - name: Restart MariaDB
ansible.builtin.service: ansible.builtin.service:
name: mariadb name: mariadb
state: restarted state: restarted
listen: restart_mariadb listen: restart_mariadb
- name: Compose up on webserver stack - name: Start podman compose project
ansible.builtin.command: "docker-compose up -d" ansible.builtin.command:
args: cmd: podman compose up -d
chdir: "{{ webserver_root }}" chdir: "/home/oci/webserver"
listen: composeup_webserver notify: Generate systemd service files
changed_when: false
become_user: oci
become: true
- name: Reload systemd user daemon
ansible.builtin.systemd:
daemon_reload: true
scope: user
notify: Enable systemd user service
become_user: oci
become: true
- name: Enable systemd user service
ansible.builtin.systemd:
name: webserver
enabled: true
scope: user
become_user: oci
become: true
- name: Grab Nextcloud container information - name: Grab Nextcloud container information
community.docker.docker_container_info: community.docker.docker_container_info:
@ -23,7 +47,8 @@
listen: composeup_webserver listen: composeup_webserver
- name: Check Nextcloud status - name: Check Nextcloud status
ansible.builtin.command: "docker exec --user www-data {{ webserver_root | basename }}_nextcloud_1 ansible.builtin.command:
"docker exec --user www-data {{ webserver_root | basename }}_nextcloud_1
php occ status" php occ status"
listen: composeup_webserver listen: composeup_webserver
register: nextcloud_status register: nextcloud_status
@ -34,3 +59,12 @@
when: when:
- nextcloud_status.stderr[:26] == "Nextcloud is not installed" - nextcloud_status.stderr[:26] == "Nextcloud is not installed"
- nextcloud_autoinstall - nextcloud_autoinstall
- name: Install webserver docker-compose.yml
ansible.builtin.copy:
src: docker-compose.yml
dest: /home/oci/webserver/compose.yml
mode: "600"
owner: oci
group: oci
notify: Generate systemd service files

View File

@ -1,72 +1,96 @@
- name: Install MariaDB Server - name: Install MariaDB Server
ansible.builtin.apt: ansible.builtin.dnf:
name: mariadb-server name: mariadb-server
state: present state: present
- name: Change the bind-address to allow Docker - name: Change the bind-address to allow Docker
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: /etc/mysql/mariadb.conf.d/50-server.cnf path: /etc/my.cnf.d/mariadb-server.cnf
regex: "^bind-address" regex: "^bind-address"
line: "bind-address = 0.0.0.0" line: "bind-address = 0.0.0.0"
notify: restart_mariadb notify: restart_mariadb
- name: Start and enable MariaDB service
ansible.builtin.systemd:
name: mariadb
state: started
enabled: true
- name: Install MySQL Support for Python 3 - name: Install MySQL Support for Python 3
ansible.builtin.apt: ansible.builtin.dnf:
name: python3-pymysql name: python3-PyMySQL
state: present state: present
- name: Create MariaDB databases - name: Create MariaDB databases
community.mysql.mysql_db: community.mysql.mysql_db:
name: "{{ item.name }}" name: "{{ item.name }}"
state: present state: present
login_unix_socket: /var/run/mysqld/mysqld.sock login_unix_socket: /var/lib/mysql/mysql.sock
loop: "{{ databases }}" loop: "{{ databases }}"
no_log: "{{ item.pass is defined }}" no_log: true
- name: Create MariaDB users - name: Create MariaDB users
community.mysql.mysql_user: community.mysql.mysql_user:
name: "{{ item.name }}" name: "{{ item.name }}"
password: "{{ item.pass }}" password: "{{ item.pass }}"
host: '%' host: "%"
state: present state: present
priv: "{{ item.name }}.*:ALL" priv: "{{ item.name }}.*:ALL"
login_unix_socket: /var/run/mysqld/mysqld.sock login_unix_socket: /var/lib/mysql/mysql.sock
loop: "{{ databases }}" loop: "{{ databases }}"
no_log: "{{ item.pass is defined }}" no_log: true
- name: Create webserver docker-compose directory - name: Create webserver stack directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ webserver_root }}" path: /home/oci/webserver
state: directory state: directory
mode: 0600 mode: "700"
owner: oci
group: oci
- name: Install webserver docker-compose.yml - name: Install webserver compose file
ansible.builtin.copy: ansible.builtin.copy:
src: docker-compose.yml src: docker-compose.yml
dest: "{{ webserver_root }}/docker-compose.yml" dest: /home/oci/webserver/compose.yml
mode: 0600 mode: "600"
notify: composeup_webserver owner: oci
group: oci
notify: Start podman compose project
- name: Install docker-compose .env - name: Generate webserver environment configuration
ansible.builtin.template: ansible.builtin.template:
src: compose-env.j2 src: compose-env.j2
dest: "{{ webserver_root }}/.env" dest: /home/oci/webserver/.env
mode: 0600 mode: "400"
notify: composeup_webserver owner: oci
group: oci
notify: Start podman compose project
- name: Allow MariaDB database connections - name: Install nginx
community.general.ufw: ansible.builtin.dnf:
rule: allow name: ["nginx", "nginx-mod-stream"]
port: 3306 state: present
proto: tcp update_cache: true
src: "{{ item }}"
loop: "{{ mariadb_trust }}"
- name: Add HTTP and HTTPS firewall rule - name: Deploy nginx proxy config
community.general.ufw: ansible.builtin.copy:
rule: allow src: nginx.conf
port: "{{ item }}" dest: /etc/nginx/nginx.conf
proto: tcp mode: "644"
notify: Restart nginx
- name: Allow HTTP and HTTPS in firewall
ansible.posix.firewalld:
service: "{{ item }}"
permanent: true
state: enabled
immediate: true
loop: loop:
- "80" - http
- "443" - https
- name: Start and enable nginx
ansible.builtin.systemd:
name: nginx
state: started
enabled: true

View File

@ -8,7 +8,7 @@ MATCH_PATTERN="ssh -fNT -i ${PRIVATE_KEY}.*vagrant@"
function ssh_connect { function ssh_connect {
sudo ssh -fNT -i "$PRIVATE_KEY" \ sudo ssh -fNT -i "$PRIVATE_KEY" \
-L 8443:localhost:8443 \ -L 9443:localhost:9443 \
-L 80:localhost:80 \ -L 80:localhost:80 \
-L 443:localhost:443 \ -L 443:localhost:443 \
-o UserKnownHostsFile=/dev/null \ -o UserKnownHostsFile=/dev/null \

View File

@ -3,5 +3,5 @@
become: true become: true
roles: roles:
- common - common
- docker - podman
- webserver - webserver